Intro and Aim:
A quick post here as I didn’t find a suitable example online when researching.
The aim is to create multiple CMKs (Customer Managed Keys) in AWS KMS (Key Management Service) with Terraform with unique aliases from a list of variables.
We will also create secrets in AWS Secrets Manager with the newly created CMKs used for the Encryption key. For now the secrets will be created without contents.
Steps below:
Prerequisites:
Install terraform and set environment variables to connect to my AWS account (rather than entering keys in my terraform code.
export AWS_ACCESS_KEY_ID=<ACCESSKEYID>
export AWS_SECRET_ACCESS_KEY=<SECRET>
export AWS_SESSION_TOKEN=<SESSTOK>
Code:
The key to achieving this aim was the use of count.index in my terraform code to create multiple resources of the same kind, interating through my list of variables.
Files:
$ find .
.
./output.tf
./main.tf
./secrets.tf
./env
./env/eu-west-1.tfvars
./variables.tf
main.tf:
provider "aws" {
region = var.aws_region
}
resource "aws_kms_key" "clustername" {
count = length(var.clustername) //count will be number of keys
description = var.clustername[count.index]
}
resource "aws_kms_alias" "clustername-alias" {
count = length(var.clustername) //count will be number of key aliases
name = "alias/${var.clustername[count.index]}-alias"
target_key_id = aws_kms_key.clustername[count.index].key_id
}
secrets.tf (note the depends_on field, this ensures the KMS key alias is created before proceeding).
resource "aws_secretsmanager_secret" "app-keystore" {
depends_on = [aws_kms_alias.clustername-alias]
count = length(var.clustername) //count will be number of keys
name = "${var.clustername[count.index]}-concat-app-keystore"
kms_key_id = "alias/${var.clustername[count.index]}-alias"
}
variables.tf:
variable "aws_region" {
type = string
description = "AWS provider to be used to create roles, policies, S3 objects, ..."
}
variable "clustername" {
type = list(any)
}
./env/eu-west-1.tfvars
# Do not change the order of these default values. it will force the build to destory and rebuild
aws_region = "eu-west-1"
clustername = [
"euw1-test-c001",
"euw1-test-c002",
"euw1-test-c003",
"euw1-test-c004",
]
output.tf:
output "kms_key_id" {
value = aws_kms_key.clustername[*].arn
}
output "kms_alias_arn" {
value = aws_kms_alias.clustername-alias[*].arn
}
output "aws_secretsmanager_secret" {
value = aws_secretsmanager_secret.app-keystore[*].arn
}
Execution:
Use the terraform commands, init, validate, plan before applying with
terraform apply --var-file=./env/eu-west-1.tfvars
The output of terraform apply below:
Check via AWS console:
Here we see the keys created, along with the aliases:
And the secrets:
Clean Up:
Run terraform destroy
to clean up the resources created:
References:
https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html
https://www.terraform.io/language/meta-arguments/count
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias