如何使用if,else elsif语句创建Terraform?

时间:2019-04-07 05:40:26

标签: terraform terraform-provider-aws

我正在设置一个terraform模块来创建aurora集群。
我需要一个跨区域复制的选项,因此我需要确定与源区域相关的副本区域。
有什么方法可以在terraform中有条件地进行多项选择吗?

7 个答案:

答案 0 :(得分:1)

从terraform 0.12开始,您可以使用地图来伪造开关,例如

locals {
  environments = {
    prod = "east",
    prod2 = "west2"
  }
  
  region = lookup(environment_region, lower(var.environment), "west")
}

这样做的好处是,如果结果更复杂,则可以从地图中返回对象/列表,而不是简单的字符串。

例如,我有一个集中的命名模块,该模块根据资源类型等根据不同的规则组成名称。

locals {
  parts_map = {
    # NB Location should always be last to ensure geo-separation of names
    prefix = [ local.type.code, var.name, var.role, var.environment, module.location.code ]
    suffix = [ var.name, var.role, var.environment, local.type.code, module.location.code ]
    mode3  = [ var.name, local.type.code, var.role, var.environment, module.location.code ]
}

parts = compact(local.parts_map[local.type.order])

答案 1 :(得分:1)

locals {
  test = "${ condition ? value : (elif-condition ? elif-value : else-value)}"
}

对于更直截了当的“ if-elif-else”方法,您可以将if短手嵌入其他手以产生相似的效果。如果用例也位于for循环内,则也可以这样做:

locals {
  test = {
    for i in list : 
      key => "${ condition ? value : (elif-condition ? elif-value : else-value)}"
  }
}

在任何使用“ $ {}”语法的情况下都可以使用

答案 2 :(得分:0)

在Terraform <0.12中没有这样的东西/ elseif / else

但是,您可以在Terrafom Conditions中使用经典的布尔逻辑

答案 3 :(得分:0)

我认为您真的不需要这个。

通常,您可以插入一些变量作为输入,并且可以将这些变量输入值。如果需要任何逻辑/决策,最好的方法是在CI / CD的plepleine差异变量(即区域和源区域)中使用,或在运行terraform之前在脚本中进行任何逻辑处理。

因此,在我的情况下,我们在部署计划中有不同的变量,并且每个变量都有其自己的环境(dev-test-stag-prod)和区域(即us-east-1)。在执行时,它会将terraform变量设置为给定的环境和区域。

到目前为止,我们有两个帐户,一个是沙箱,一个是“生产一”,但是在“生产一”上有dev,test,stag,prod,因此QA和某些集成也在那里进行了测试。 。开始时,我们仅使用沙盒尝试进行部署。由于我不想在每个构建版本中都设置AWS访问权限,因此我在运行terraform apply之前使用了以下工作方式:

if [ "$PROD_BUILD" = "true" ]
then
  echo "PROD build is used, the PROD AWS tokens will be used"
  export TF_VAR_CERTIFICATE_DOMAIN=$PROD_TERRAFORM_CERTIFICATE_DOMAIN
  export AWS_ACCESS_KEY_ID=${PROD_AWS_ACCESS_KEY_ID}
  export AWS_SECRET_ACCESS_KEY=${PROD_AWS_SECRET_ACCESS_KEY}
  export S3_TERRAFORM_STATE_BUCKET=$PROD_S3_TERRAFORM_STATE_BUCKET
  export S3_TERRAFORM_STATE_REGION=$PROD_S3_TERRAFORM_STATE_REGION
else
  echo "DEV build is used, the DEV AWS tokens will be used"
  export TF_VAR_CERTIFICATE_DOMAIN=$DEV_TERRAFORM_CERTIFICATE_DOMAIN
  export AWS_ACCESS_KEY_ID=${DEV_AWS_ACCESS_KEY_ID}
  export AWS_SECRET_ACCESS_KEY=${DEV_AWS_SECRET_ACCESS_KEY}
  export S3_TERRAFORM_STATE_BUCKET=$DEV_S3_TERRAFORM_STATE_BUCKET
  export S3_TERRAFORM_STATE_REGION=$DEV_S3_TERRAFORM_STATE_REGION
fi

答案 4 :(得分:0)

这是使用coalesce()函数的一种方式:

locals{
  prod = "${var.environment == "PROD" ? "east" : ""}"
  prod2 = "${var.environment == "PROD2" ? "west2" : ""}"
  nonprod = "${var.environment != "PROD" && var.environment != "PROD2" ? "west" : ""}"
  region = "${coalesce(local.prod,local.prod2, local.nonprod)}"
}

答案 5 :(得分:0)

您可以尝试仅使用maplookup。示例:

/* In your variables.tf */
variable "region_mapping" {
  description = "mapping for cross-region replication"
  default = {
    "us-east-1" = "us-east-2",
    "us-west-1" = "us-west-2"
  }
}

/* Then create use lookup to get the replication region from the deployment region */
resource "example" "example" {
  region = "${lookup(var.region_mapping, var.region)}"
}

如果var.region是部署当前群集的位置,并且其值例如为us-east-1,则查找将返回us-east-2作为您应部署副本的区域。

根据您的需要进行调整。

答案 6 :(得分:0)

这是我在Terraform脚本中实施条件时最有用的参考资料:https://blog.gruntwork.io/terraform-tips-tricks-loops-if-statements-and-gotchas-f739bbae55f9