简体   繁体   English

Terraform 推动 Cloudformation 堆栈。 如何根据参数制作字符串列表

[英]Terraform pushing Cloudformation stacks. How to make a string list from parameters

I'm fighting with wired case.我正在与有线案例作斗争。 I need to push cloudformation stacks dynamically parameterized with terraform.我需要推送使用 terraform 动态参数化的 cloudformation 堆栈。

My resource looks like this.我的资源看起来像这样。

resource "aws_cloudformation_stack" "eks-single-az" {
  count = length(var.single_az_node_groups)
  name = "eks-${var.cluster_name}-${var.single_az_node_groups[count.index].name}"

  template_body = <<EOF
Description: "eks-${var.cluster_name}-${var.single_az_node_groups[count.index].name}"

Resources:
  ASG:
    Type: AWS::AutoScaling::AutoScalingGroup
    Properties:
      AutoScalingGroupName: "eks-${var.cluster_name}-${var.single_az_node_groups[count.index].name}"
      VPCZoneIdentifier: ["${var.private_subnet_ids[count.index]}"]
      MinSize: "${lookup(var.single_az_node_groups[count.index], "asg_min", "0")}"
      MaxSize: "${lookup(var.single_az_node_groups[count.index], "asg_max", "10")}"
      HealthCheckType: EC2
      TargetGroupARNs: [] < - here is error. 
      MixedInstancesPolicy:
        InstancesDistribution:
          OnDemandBaseCapacity: "0"
          OnDemandPercentageAboveBaseCapacity: "${lookup(var.single_az_node_groups[count.index], "on_demand_percentage", "0")}"
        LaunchTemplate:
          LaunchTemplateSpecification:
            LaunchTemplateId: "${aws_launch_template.eks-single-az[count.index].id}"
            Version: "${aws_launch_template.eks-single-az[count.index].latest_version}"
          Overrides:
            - 
              InstanceType: m5.large
      Tags:
        - Key: "Name"
          Value: "eks-${var.cluster_name}-${var.single_az_node_groups[count.index].name}"
          PropagateAtLaunch: true
        - Key: "kubernetes.io/cluster/${var.cluster_name}"
          Value: "owned"
          PropagateAtLaunch: true
        - Key: "k8s.io/cluster-autoscaler/enabled"
          Value: "true"
          PropagateAtLaunch: true
        - Key: "k8s.io/cluster-autoscaler/${var.cluster_name}"
          Value: "true"
          PropagateAtLaunch: true
    UpdatePolicy:
      AutoScalingRollingUpdate:
        MinSuccessfulInstancesPercent: 80
        MinInstancesInService: "${lookup(data.external.desired_capacity.result, "eks-${var.cluster_name}-${var.single_az_node_groups[count.index].name}", "0")}"
        PauseTime: PT4M
        SuspendProcesses:
          - HealthCheck
          - ReplaceUnhealthy
          - AZRebalance
          - AlarmNotification
          - ScheduledActions
        WaitOnResourceSignals: true
  EOF

depends_on = [
  aws_launch_template.eks-single-az
]

}

I need to put target groups arn from list containing json objects:我需要从包含 json 对象的列表中放置目标组 arn:

single_az_node_groups = [
  {
    "name"          : "workload-az1",
    "instance_type" : "t2.micro",
    "asg_min"       : "1",
    "asg_max"       : "7",
    "target_group_arns" : "arnA, arnB, arnC"
  },
  ...
]

I tried everything.我尝试了一切。 Problem is that i tried many terraform functions and all the time terraform is addding some double-quotes which cloudformation does not support or terraform won't process the template_body becuase of missing quotes..问题是我尝试了许多 terraform 函数,并且 terraform 一直在添加一些 cloudformation 不支持的双引号,或者由于缺少引号,terraform 不会处理 template_body。
Do you know meybe some sneaky trick how to achive that ?你知道我是什么鬼鬼祟祟的把戏如何做到这一点吗?

When building strings that represent serialized data structures, it's much easier to use Terraform's built-in serialization functions to construct the result, rather than trying to produce a valid string using string templates.在构建表示序列化数据结构的字符串时,使用 Terraform 的内置序列化函数来构建结果要容易得多,而不是尝试使用字符串模板生成有效的字符串。

In this case, we can use jsonencode to construct a JSON string representing the template_body from a Terraform object value, which then allows using all of the Terraform language expression features to build it:在这种情况下,我们可以使用jsonencode从 Terraform 对象值构造一个表示template_body的 JSON 字符串,然后允许使用所有Terraform 语言表达式功能来构建它:

  template_body = jsonencode({
    Description: "eks-${var.cluster_name}-${var.single_az_node_groups[count.index].name}",

    Resources: {
      ASG: {
        Type: "AWS::AutoScaling::AutoScalingGroup",
        Properties: {
          AutoScalingGroupName: "eks-${var.cluster_name}-${var.single_az_node_groups[count.index].name}",
          VPCZoneIdentifier: [var.private_subnet_ids[count.index]],
          MinSize: lookup(var.single_az_node_groups[count.index], "asg_min", "0"),
          MaxSize: lookup(var.single_az_node_groups[count.index], "asg_max", "10"),
          HealthCheckType: "EC2",
          TargetGroupArns: flatten([
            for g in local.single_az_node_groups : [
              split(", ", g.target_group_arns)
            ]
          ]),
          # etc, etc
        },
      },
    },
  })

As you can see above, by using jsonencode for the entire data structure we can then use Terraform expression operators to build the values.正如您在上面看到的,通过对整个数据结构使用jsonencode ,然后我们可以使用 Terraform 表达式运算符来构建值。 For TargetGroupArns in the above example I used the flatten function along with a for expression to transform the nested local.single_az_node_groups data structure into a flat list of target group ARN strings.对于上面示例中的TargetGroupArns ,我使用flatten函数for表达式将嵌套的local.single_az_node_groups数据结构转换为目标组 ARN 字符串的平面列表。


CloudFormation supports both JSON and YAML, and Terraform also has a yamlencode function that you could potentially use instead of jsonencode here. CloudFormation 支持 JSON 和 YAML,Terraform 也有一个yamlencode函数,您可以在这里代替jsonencode使用jsonencode I chose jsonencode both because yamlencode is currently marked as experimental (the exact YAML formatting it produces may change in a later release) and because Terraform has special support for JSON formatting in the plan output where it can show a structural diff of the data structure inside, rather than a string-based diff.我选择jsonencode是因为yamlencode目前被标记为实验性(它产生的确切 YAML 格式可能会在以后的版本中改变),并且因为 Terraform 在计划输出中对 JSON 格式有特殊支持,它可以显示内部数据结构的结构差异, 而不是基于字符串的差异。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 删除堆栈时不会调用 AWS CloudFormation 宏。 它们仅在创建/更新堆栈时调用 - AWS CloudFormation Macros are not invoked while deleting Stacks. They are invoked only while creating/updating Stacks 如何将 AZ 列表从 Terraform 传递到 CloudFormation 模板? - How to pass a list of AZs from Terraform to a CloudFormation template? 如何使用boto3 cloudformation资源列出和过滤堆栈? - How list and filter stacks with boto3 cloudformation resource? CodePipeline:如何从GitHub引用嵌套的CloudFormation Stacks作为Source - CodePipeline: How to reference nested CloudFormation Stacks from GitHub as Source 如何验证或创建CloudFormation堆栈 - How to validate or create CloudFormation stacks Cloudformation 无法将输出参数与嵌套堆栈一起使用 - Cloudformation Unable to Use Outputted Parameters with Nested Stacks 如何在Cloudformation中使用List和Map参数 - How to use List and Map parameters in Cloudformation 如何使用 boto3 从已删除的 CloudFormation 堆栈中检索信息? - How can I retrieve information from deleted CloudFormation stacks using boto3? boto3 cloudformation list_stacks() function 未列出 cloudformation 中的所有堆栈 - boto3 cloudformation list_stacks() function is not listed all the stacks in cloudformation AWS CLI-获取名称以字符串开头的所有CloudFormation堆栈 - AWS CLI - Get all CloudFormation stacks that have a name that starts with string
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM