迁移Auto Scaling组至Launch Template时遇Terraform加密参数报错
最近我在把Auto Scaling Groups从Launch Configuration迁移到Launch Template(目的是支持T2 Unlimited实例),写了这样一段Terraform代码:
resource "aws_launch_template" "test_launch_template" { image_id = "ami_id" name_prefix = "test-pref" instance_type = "t2.small" key_name = "jayesh" vpc_security_group_ids = ["sg-23423432","sg-23452115"] user_data = "${base64encode(data.template_file.user_data.rendered)}" iam_instance_profile { name = "test" } disable_api_termination = true instance_initiated_shutdown_behavior = "terminate" block_device_mappings { device_name = "/dev/sda1" ebs { delete_on_termination = true volume_size = "${var.volume_size}" } } credit_specification { cpu_credits = "unlimited" } lifecycle { create_before_destroy = "true" } }
结果执行terraform apply的时候碰上个奇怪的错误:
1 error(s) occurred:
aws_autoscaling_group.test_asg: 1 error(s) occurred:
aws_autoscaling_group.test_asg: Error creating AutoScaling Group:
ValidationError: You must use a valid fully-formed launch template. the encrypted flag cannot be specified since device /dev/sda1 has a snapshot specified.
status code: 400, request id: 7902a390-58de-11e8-af77-87d327f8b121
明明我没指定encrypted参数,怎么会报这个错?
问题原因
其实问题出在Terraform AWS Provider的默认行为上:当你在block_device_mappings的ebs块里没有显式声明encrypted参数时,旧版本的Provider会默认把这个参数设为false并发送给AWS API。但如果你的AMI对应的根卷(/dev/sda1)是基于加密快照创建的,AWS就会拒绝这个请求——因为从加密快照创建的卷,你不能手动设置encrypted=false,也不需要指定这个参数,AWS会自动继承快照的加密属性。
解决办法
有两种可行的解决方式:
显式匹配快照的加密状态
先确认你的AMI根卷快照是否加密(可以通过AWS控制台或者aws ec2 describe-snapshots --snapshot-id <你的快照ID>命令查看),如果是加密的,就在ebs块里添加encrypted = true:block_device_mappings { device_name = "/dev/sda1" ebs { delete_on_termination = true volume_size = "${var.volume_size}" encrypted = true # 新增这一行,和快照加密状态一致 } }升级Terraform AWS Provider版本
较新的AWS Provider版本已经修复了这个默认行为,当你不指定encrypted参数时,不会主动发送这个字段给AWS API,让AWS自动处理加密属性的继承。你可以在provider "aws"块里指定一个较新的版本,比如:provider "aws" { region = "你的区域" version = ">= 3.0" # 或者更高的稳定版本 }
额外提示
如果还是有问题,建议先检查AMI的详细信息,确认根卷对应的快照是否加密,确保你的配置和底层资源的属性一致,这样就能避免这类因隐式参数导致的报错了。
内容的提问来源于stack exchange,提问作者Jayesh Dhandha

