I’m trying to enable encryption of root block devices in an AWS launch template using an explicit customer-managed KMS CMK using Terraform v0.14.3 and AWS provider 3.22.0 on macOS.
It only seems to work if I do NOT specify the key_key_id
in the launch template block device ebs
configuration block (or if I set it to use the alias/aws/ebs
AWS-managed CMK).
When using my own CMK the EC2 instance never initialises and it just terminates before startup.
I don’t suppose anyone has encountered this before? Is this a failure in my understanding of AWS launch template block device configuration, or is there something funky with the AWS provider perhaps?
Pastebin of a minimal example is at Encryption root block device with explicit customer-managed KMS CMK using launch template - Pastebin.com.
variable "unique_example_string" {
type = string
default = "mytest123"
description = "Unique string to avoid resource naming conflicts in order to allow the example to function"
}
resource "aws_vpc" "vpc" {
cidr_block = "192.168.0.0/22"
}
data "aws_availability_zones" "azs" {
state = "available"
}
resource "aws_subnet" "subnet_az1" {
availability_zone = data.aws_availability_zones.azs.names[0]
cidr_block = "192.168.0.0/24"
vpc_id = aws_vpc.vpc.id
}
resource "aws_security_group" "sg" {
name_prefix = var.unique_example_string
vpc_id = aws_vpc.vpc.id
}
data "aws_ami" "ami" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["amzn2-ami-ecs-hvm-2.0.*"]
}
filter {
name = "root-device-type"
values = ["ebs"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
filter {
name = "architecture"
values = ["x86_64"]
}
}
data "aws_region" "current" {}
data "aws_caller_identity" "current" {}
# Policy copied and adapted from alias/aws/ebs KMS key.
data "aws_iam_policy_document" "kms_policy" {
statement {
sid = "Allow access through EBS for all principals in the account that are authorized to use EBS"
effect = "Allow"
principals {
type = "AWS"
identifiers = ["*"]
}
actions = [
# Tried both with and without kms:* action (no change in result).
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:CreateGrant",
"kms:DescribeKey"
]
# Tried both with and without conditions (no change in result).
condition {
test = "StringEquals"
variable = "kms:CallerAccount"
values = [data.aws_caller_identity.current.account_id]
}
condition {
test = "StringEquals"
variable = "kms:ViaService"
values = ["ec2.${data.aws_region.current.name}.amazonaws.com"]
}
}
statement {
sid = "Enable IAM User Permissions"
effect = "Allow"
principals {
type = "AWS"
identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"]
}
actions = ["kms:*"]
resources = ["*"]
}
}
resource "aws_kms_key" "kms" {
description = var.unique_example_string
# Tried both with and without an explicit policy (no change in result).
policy = data.aws_iam_policy_document.kms_policy.json
}
resource "aws_launch_template" "example" {
name_prefix = var.unique_example_string
ebs_optimized = true
image_id = data.aws_ami.ami.image_id
instance_type = "t3.nano"
vpc_security_group_ids = [aws_security_group.sg.id]
block_device_mappings {
device_name = data.aws_ami.ami.root_device_name
ebs {
delete_on_termination = true
encrypted = true
volume_type = "gp2"
volume_size = 30
# Tried both with and without kms_key_id (only works WITHOUT kms_key_id or when pointing to alias/aws/ebs).
#kms_key_id = aws_kms_key.kms.arn
}
}
}
resource "aws_autoscaling_group" "example" {
name_prefix = var.unique_example_string
vpc_zone_identifier = [aws_subnet.subnet_az1.id]
min_size = 1
max_size = 1
launch_template {
id = aws_launch_template.example.id
version = "$Latest"
}
}