前言 这里记录TerraForm学习笔记
语法 注释
# 单行注释
// 单行注释
/* */ 多行注释
Resource 语法 1 2 3 4 resource "aws_instance" "web" { ami = "ami-a1b2c3d4" instance_type = "t2.micro" }
provider 声明模块使用哪些provider
1 2 3 4 5 6 7 8 terraform { required_providers { mycloud = { source = "mycorp/mycloud" version = "~> 1.0" } } }
超时 1 2 3 4 5 6 7 8 resource "aws_db_instance" "example" { timeouts { create = "60m" delete = "2h" } }
Behavior Terraform 自身维护了一个 state的数据库, 来映射真实存在的物理资源。通过与数据库中的资源对比,随后提供相应资源curd的功能。 同样,我们也可以通过 <RESOURCE TYPE>.<NAME>.<ATTRIBUTE> 方法来引用对应的资源。
Provisioners Provisioners可以在本地主机或者远程主机上执行特定的操作。
TerraForm不建议使用此方式,因为这些为TerraForm增加了相当多的负责性和不确定性。
如何使用? 1 2 3 4 5 6 7 resource "aws_instance" "web" { provisioner "local-exec" { command = "echo The server's IP address is ${self.private_ip} " } }
self 对象provisioner 块中不能通过名称引用父资源,不过可以通过 self 对象。
比如上方实例,通self.private_ip 引用了一个aws_instance 的private_ip 属性。
Provisioner 连接设置 在我们使用的过程,肯定是需要指定远程服务器的连接方式,tf提供了相关的配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 provisioner "file" { source = "conf/myapp.conf" destination = "/etc/myapp.conf" connection { type = "ssh" user = "root" password = "${var.root_password} " host = "${var.host} " } } provisioner "file" { source = "conf/myapp.conf" destination = "C:/App/myapp.conf" connection { type = "winrm" user = "Administrator" password = "${var.admin_password} " host = "${var.host} " } }
当connection 在resource中,作用域在resource中所有的provisioners
当connection 在provisioner 中,作用域仅仅在当前的provisioner
相关属性配置详解
没有resource的provisioner 如果您需要运行不与特定资源直接关联的provisioner,您可以将它们与null_resource。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 resource "aws_instance" "cluster" { count = 3 # .. . } resource "null_resource" "cluster" { # Changes to any instance of the cluster requires re-provisioning triggers = { cluster_instance_ids = "${join(",", aws_instance.cluster.*.id)} " } # Bootstrap script can run on any instance of the cluster # So we just choose the first in this case connection { host = "${element(aws_instance.cluster.*.public_ip, 0)} " } provisioner "remote-exec" { # Bootstrap script called with private_ip of each node in the cluster inline = [ "bootstrap-cluster.sh ${join(" ", aws_instance.cluster.*.private_ip)} " , ] } }
file provisioner 执行文件copy操作
示例用法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 resource "aws_instance" "web" { provisioner "file" { source = "conf/myapp.conf" destination = "/etc/myapp.conf" } provisioner "file" { content = "ami used: ${self.ami} " destination = "/tmp/file.log" } provisioner "file" { source = "conf/configs.d" destination = "/etc" } provisioner "file" { source = "apps/app1/" destination = "D:/IIS/webapp1" } }
注意,目录写法有一个规范。
当源目录以/号结尾的时候,比如/a/b/ 到 /c, 则会把 /b 下所有的文件copy到 /c.
当源目录不移/号结尾,比如/a/b 到 /c, 则会把整个目录复制过去,最终会是 /c/b
详细参数说明
local-exec Provisioner tf会调用本地的命令去执行,而不是远程主机
1 2 3 4 5 6 7 resource "aws_instance" "web" { provisioner "local-exec" { command = "echo ${self.private_ip} >> private_ips.txt" } }
详细参数说明
remote-exec Provisioner 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 resource "aws_instance" "web" { # .. . # Establishes connection to be used by all # generic remote provisioners (i.e. file/remote-exec) connection { type = "ssh" user = "root" password = var.root_password host = self.public_ip } provisioner "remote-exec" { inline = [ "puppet apply" , "consul join ${aws_instance.web.private_ip} " , ] } }
详细参数说明
Data Sources 详细参数说明
Variables and Outputs 输入变量 声明变量 文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 variable "image_id" { type = string } variable "availability_zone_names" { type = list(string) default = ["us-west-1a" ] } variable "docker_ports" { type = list(object({ internal = number external = number protocol = string })) default = [ { internal = 8300 external = 8300 protocol = "tcp" } ] }
使用变量 可以通过var.<NAME>来使用。
1 2 3 4 resource "aws_instance" "example" { instance_type = "t2.micro" ami = var .image_id }
为变量赋值的方法
单独使用-var 命令行选项
在变量定义(.tfvars)文件中,在命令行指定或自动加载
作为环境变量
命令行上的变量
1 2 3 terraform apply -var ="image_id=ami-abc123" terraform apply -var ='image_id_list=["ami-abc123" ,"ami-def456" ]' -var ="instance_type=t2.micro" terraform apply -var ='image_id_map={"us-east-1" :"ami-abc123" ,"us-east-2" :"ami-def456" }'
变量定义(.tfvars)文件
这些文件放置的是已经声明过的变量赋值
1 terraform apply -var -file="testing.tfvars"
.tfvars
1 2 3 4 5 image_id = "ami-abc123" availability_zone_names = [ "us-east-1a" , "us-west-1c" , ]
如果存在这些文件,tf会自动加载许多定义的变量文件
以terraform.tfvars或terraform.tfvars.json命名的文件
以.auto.tfvars 或 .auto.tfvars.json 结尾的任何文件
环境变量的方式
TerraForm会搜索以TF_VAR_ 开头的所有环境变量
比如:
1 export TF_VAR_image_id =ami-abc123
变量优先级
环境变量
terraform.tfvars文件
terraform.tfvars.json文件
按文件名的词法顺序处理的任何.auto.tfvars或 .auto.tfvars.json文件
命令行上的任何-var和-var-file选项,按提供的顺序排列。
Output Values 文档 Output values 有多种用途
子模块可以使用输出将其资源属性的子集公开给父模块。
根模块可以在运行后使用输出在 CLI 输出中打印某些值 terraform apply
1 2 3 output "instance_ip_addr" { value = aws_instance.server .private_ip }
local values 声明一个本地value
1 2 3 4 locals { service_name = "forum" owner = "Community Team" }
1 2 3 4 5 6 7 8 9 10 11 12 locals { # Ids for multiple sets of EC2 instances, merged together instance_ids = concat(aws_instance.blue.*.id, aws_instance.green.*.id) } locals { # Common tags to be assigned to all resources common_tags = { Service = local.service_name Owner = local.owner } }
使用一个local values
1 2 3 4 5 resource "aws_instance" "example" { tags = local.common_tags }
Modules 表达式 文档
for
1 2 3 4 5 6 7 8 9 [for s in var .list : upper(s)] [for k, v in var .map : length(k) + length(v)] [for i , v in var .list : "${i} is ${v}" ]
1 {for s in var .list : s => upper(s)}
1 2 3 4 5 { foo = "FOO" bar = "BAR" baz = "BAZ" }