Terraform 实现循环for和条件判断if (11)
  zNxK8cIqmu7p 2023年11月13日 44 0

实现循环 (for)

Terraform 中本身并不支持循环的语句,但是可以通过其他形式来实现循环的效果。

每一个资源块除了他所支持的特定参数外,Terraform 也具有一种被称为 mt acmt 元参数的参数。所谓元参数就是这种参数能够引用到任意的资源块中,从而达到更改资源原有行为的目的。provisioner 就是元参数。


利用 count 元参数实现循环

默认情况下 Terraform 的资源块只允许创建一个基础设施资源对象,不过使用 count 元参数,我们可以让 terraform 一次性创建多个基础设施资源对象,对于创建服务器集群的应用场景,在count 元参数的帮助下,就方便多了。


使用 count 元参数实例

  1. 在模块中添加 count 参数

count 仅支持整数。count 为 2,期望 Terraform 创建两台 ec2 实例。

# 创建EC2实例
resource "aws_instance" "server" {
  count = 2                             // 期望创建2台ec2实例
  ami = lookup(var.amis, var.region)
  instance_type = var.instance_type
  key_name = var.ssh_key_name
  user_data = var.server_script
  tags = {
    Name = "${var.server_name}-${count.index}"  // 引用 count.index 是实例的索引
  }
}
  • 引用 count.index 是实例的索引 从0开始计数。
  • ${}是变量内查,会渲染成 nginx-server-1


  1. 在 output 中添加

使用 [*] 表示所有 instance 实例,仅想显示第一台服务器的IP,可以使用 server[0] 来表示。

join 将 IP 地址列表,拼接在一起。

output "ip" {
  value = join("\n", aws_instance.server[*].public_ip) // 使用 [*] 表示所有 instance 实例
  description = "aws ec2 public ip"
}


  1. apply
terraform apply

...
Outputs:

SS_IP = <<EOT
34.222.16.131
35.91.156.111
EOT
WEB_IP = <<EOT
34.220.166.53
54.148.9.121
EOT


  1. 检查

结果是符合预期的

Terraform 实现循环for和条件判断if (11)_terraform



利用 for_each 实现循环

于 count 不同的是,for_each 仅支持 map 和 set 两种类型。

Terraform 的 HCI 配置语言并没有自变量的集合表示法,所以利用 toset 函数将列表转换成集合类型。

for_each 一旦被设置就可以使用 each 变量,each 有两个对象分别是each.key 和 each.value。在使用集合的情况下他们的结果一样,只有在使用映射时,他们的结果才会不一样。


使用 for_each 元参数实例

  1. 在模块中添加 for_each 参数
# 创建EC2实例
resource "aws_instance" "server" {
  for_each = toset(["dev", "test"])         // 声明 for_each 
  ami = lookup(var.amis, var.region)
  instance_type = var.instance_type
  key_name = var.ssh_key_name
  user_data = var.server_script
  tags = {
    Name = "${var.server_name}-${each.key}"  // 调用 each 变量
  }
}


  1. 在 output 中添加
output "ip" {
  value = join("\n", [aws_instance.server["dev"].public_ip, aws_instance.server["test"].public_ip])
  description = "aws ec2 public ip"
}


  1. apply
$ terraform apply 

Apply complete! Resources: 8 added, 0 changed, 0 destroyed.

Outputs:

SS_IP = <<EOT
35.164.33.19
34.213.116.13
EOT
WEB_IP = <<EOT
35.87.94.147
34.221.170.139
EOT



  1. 检查

Terraform 实现循环for和条件判断if (11)_terraform_02



条件判断 (if)

 在 Terraform 的 HCL 语言中通用不支持 if 判断。好在 Terraform 提供了 三目运算符,结合 count 元参数就可以实现 if 条件判断的功能了。

Terraform 的 HCL 配置语言具有以下形式的三目条件表达式。

condition ? true_val : false_val

如果条件为真,结果为真值,反之结果为假值。


当我们为不同的环境准备基础设施资源时, 每一个环境所需要的 ec2 实例数量都不一样,例如,测试环境有2台 ec2 实例,而生产环境有4台 ec2 实例,结合 terraform 的工作区,我们就可以根据相应的条件选择。



使用 count 元参数实现 if条件选择

  1. 在模块中添加 count 参数

count 对 terraform 的工作区名称进行判断,如果是 test 则将 2 赋值给 count。反之则赋值为 4。

# 创建EC2实例
resource "aws_instance" "server" {
  count = terraform.workspace == "test" ? 2 : 4
  ami = lookup(var.amis, var.region)
  instance_type = var.instance_type
  key_name = var.ssh_key_name
  user_data = var.server_script
  tags = {
    Name = "${var.server_name}-${count.index}"  // 调用 each 变量
  }
}



  1. 在 output 中添加
output "ip" {
  value = join("\n", aws_instance.server[*].public_ip)
  description = "aws ec2 public ip"
}


  1. 创建 test 工作区
% terraform workspace new test
Created and switched to workspace "test"!

You're now on a new, empty workspace. Workspaces isolate their state,
so if you run "terraform plan" Terraform will not see any existing state
for this configuration.


  1. apply
terraform apply


  1. 检查

Terraform 实现循环for和条件判断if (11)_terraform_03



  1. 切换工作区,执行 plan
% terraform workspace select default
Switched to workspace "default".

% terraform plan 
...
  # module.nginx-server.aws_instance.server[3] will be created
  + resource "aws_instance" "server" {
      + ami                                  = "ami-03f65b8614a860c29"
      + arn                                  = (known after apply)
      + associate_public_ip_address          = (known after apply)
      + availability_zone                    = (known after apply)
      + cpu_core_count                       = (known after apply)
      + cpu_threads_per_core                 = (known after apply)
      + disable_api_stop                     = (known after apply)
      + disable_api_termination              = (known after apply)
      + ebs_optimized                        = (known after apply)
      + get_password_data                    = false
      + host_id                              = (known after apply)

会计划创建4个 ec2 实例。





【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月13日 0

暂无评论

推荐阅读
  zNxK8cIqmu7p   2023年11月02日   22   0   0 terraform
  zNxK8cIqmu7p   2023年11月02日   28   0   0 terraform
  zNxK8cIqmu7p   2023年11月02日   108   0   0 IaCterraform
  zNxK8cIqmu7p   2023年11月02日   22   0   0 tfenvIaCterraform
  zNxK8cIqmu7p   2023年11月13日   18   0   0 terraform
  zNxK8cIqmu7p   2023年11月02日   36   0   0 terraform
  zNxK8cIqmu7p   2023年11月13日   19   0   0 terraform
  zNxK8cIqmu7p   2023年11月13日   16   0   0 terraform