[英]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.