Terraform толкает стеки Cloudformation. Как сделать список строк из параметров - PullRequest
0 голосов
/ 22 января 2020

Я борюсь с проводным корпусом. Мне нужно собрать стеки облачной информации, динамически параметризованные с помощью terraform.

Мой ресурс выглядит так.

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
]

}

Мне нужно поместить целевые группы arn из списка, содержащего json объектов:

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

Я попробовал все. Проблема в том, что я перепробовал много функций terraform, и все время terraform добавляет несколько двойных кавычек, которые не поддерживает облачная информация, или terraform не будет обрабатывать template_body из-за пропущенных кавычек ..
Знаете ли вы, что я могу подделать какой-нибудь хитрый трюк, как достичь этого?

1 Ответ

0 голосов
/ 23 января 2020

При построении строк, представляющих сериализованные структуры данных, гораздо проще использовать встроенные функции сериализации Terraform для построения результата, чем пытаться создать допустимую строку с использованием шаблонов строк.

В этом случае мы можем использовать jsonencode для построения строки JSON, представляющей template_body из значения объекта Terraform, что затем позволяет использовать все функции выражения языка 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
        },
      },
    },
  })

Как вы можете видеть выше, используя jsonencode для всей структуры данных, мы можем использовать операторы выражений Terraform для построения значений. Для TargetGroupArns в вышеприведенном примере я использовал функцию flatten вместе с for выражением для преобразования вложенной структуры данных local.single_az_node_groups в плоский список целевой группы Строки ARN.


CloudFormation поддерживает как JSON, так и YAML, а Terraform также имеет функцию yamlencode , которую вы могли бы потенциально использовать вместо jsonencode здесь. Я выбрал jsonencode, так как yamlencode в настоящее время помечен как экспериментальный (точное форматирование YAML, которое он производит, может измениться в более позднем выпуске), а также потому, что Terraform имеет специальную поддержку JSON форматирования в выходных данных плана, где он может показать структурную diff структуры данных внутри, а не diff на основе строки.

...