Tried that too. Added this little block as well.
provisioner "file" {
destination = "~/.aws/credentials"
content = <<EOF
[default]
role_arn = ${var.kms_role_arn}
credential_source = Ec2InstanceMetadata
region = ${var.kms_region}
EOF
}
Same result
Setting “AWS_ROLE_ARN” does look promising, however, I’ve found an alternative solution that works much easier than cross account assumerole for now.
Sharing the KMS with external accounts is much simpler and requires no additional instance config. For those who might stumble upon the same problem in the future working from the boundary reference architecture as a base, add these edits into your code:
- Added the desired target accounts as a variable into your config:
variable "shared_accounts" {
type = list(string)
}
- Edit the worker_auth KMS key to have a policy to share with external accounts
resource "aws_kms_key" "worker_auth" {
description = "Boundary worker authentication key"
deletion_window_in_days = 10
tags = {
Name = "${var.tag}-${random_pet.test.id}"
}
#Note: "kms:ListKeys", "kms:ListAliases" aren't included because they aren't part of shared key permissions
policy = <<EOF
{
"Version": "2012-10-17",
"Id": "key-default-1",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:root"
},
"Action": "kms:*",
"Resource": "*"
}%{for account_num in var.shared_accounts},
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:${data.aws_partition.current.partition}:iam::${account_num}:root"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:GenerateDataKey",
"kms:DescribeKey"
],
"Resource": "*"
}
%{endfor}
]
}
EOF
}
- Save the key ARN
output "kms_key_id" {
value = aws_kms_key.worker_auth.arn
}
- In the account that is using the shared KMS, make sure the instance has a role policy that grants the same essential permissions onto that shared key arn like those needed in the original architecture. i.e., supposing the key arn is var.kms_key_id
resource "aws_iam_role_policy" "boundary" {
name = "${var.tag}-${random_pet.test.id}"
role = aws_iam_role.boundary.id
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": [
"kms:DescribeKey",
"kms:GenerateDataKey",
"kms:Decrypt",
"kms:Encrypt",
"kms:ListKeys",
"kms:ListAliases"
],
"Resource": [
"${var.kms_key_id}"
]
}
}
EOF
}
-
MOST IMPORTANT: In the worker config, make sure the key id passed in is indeed the ARN to the key, and not just the long 32-character alphanumeric key-id.
i.e. Make sure in this config:
%{ if kms_type == "aws" }
kms "awskms" {
purpose = "worker-auth"
key_id = "global_root"
kms_key_id = "${kms_worker_auth_key_id}"
}
%{ else }
kms "aead" {
purpose = "worker-auth"
aead_type = "aes-gcm"
key = "8fZBjCUfN0TzjEGLQldGY4+iE9AkOvCfjh7+p0GtRBQ="
key_id = "global_worker-auth"
}
%{ endif }
kms_key_id is an ARN, such as the output from the code above.