I'm working on importing kms into terraform, I have imported these resources, but when i try to run a terraform plan its rearranging the arn's and hence the last arn has a comma. Thus my terraform apply is failing.
Is there anyway I can avoid this rearranging? I think in this case i should be using a data block instead of adding the policy directly. But i'm not sure how to pass the data block ..
Looks like i can't use a data block, Is there any way i can to avoid the rearranging on arn in Principal block?
I'm using terraform 0.12.20
policy.json.tpl
{
"Version": "2012-10-17",
"Id": "key-policy-1",
"Statement": [{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": ${allowed_resources}
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Principal": {
"AWS": ${allowed_resources}
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*"
}
]
}
main.tf
resource "aws_kms_key" "key" {
description = ""
tags = local.common_tags
policy = templatefile("${path.module}/policy.json.tpl", {
allowed_resources = var.allowed_resources
})
}
variables.tf
variable "allowed_resources" {
description = "list of all principal resources"
type = list(string)
default = [
"arn:aws:iam::xxxxxxxxxxxx:user/a",
"arn:aws:iam::xxxxxxxxxxxxx:user/b",
"arn:aws:iam::xxxxxxxxxx:user/c",
"arn:aws:iam::xxxxxxxxxx:role/abc
]
}
Error
10:53:19 Error: MalformedPolicyDocumentException: Policy contains a statement with one or more invalid principals.
10:53:19
10:53:19 on main.tf line 8, in resource "kms_key" "key":
10:53:19 8: resource "aws_kms_key" "key" {
Terraform plan: Terraform will perform the following actions:
# aws_kms_key.amp_key will be updated in-place
~ resource "aws_kms_key" "amp_key" {
arn = "arn:aws:kms:us-east-1:xxxx:key/xxx-xxx-xxx-xx-xxxxxxxx"
customer_master_key_spec = "SYMMETRIC_DEFAULT"
enable_key_rotation = false
id = "xxx-xxx-xxx-xx-xxxxxxxx"
is_enabled = true
key_id = "xxx-xxx-xxx-xx-xxxxxxxx"
key_usage = "ENCRYPT_DECRYPT"
~ policy = jsonencode(
~ {
Id = "key-policy-1"
~ Statement = [
{
Action = "kms:*"
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::xxxxxxxx:root"
}
Resource = "*"
Sid = "Enable IAM User Permissions"
},
~ {
Action = [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey",
]
Effect = "Allow"
~ Principal = {
~ AWS = [
+ "arn:aws:iam::xxxxxx:user/c",
+ "arn:aws:iam::xxxxxx:user/a",
- "arn:aws:iam::xxxxxx:role/abc",
- "arn:aws:iam::xxxxxx:user/a",
- "arn:aws:iam::xxxxxx:user/c",
"arn:aws:iam::xxxxxx:user/b",
+ "arn:aws:iam::xxxxxx:role/abc",
]
}
]
Version = "2012-10-17"
}
)
When i tried to use data block
data "template_file" "temp_file" {
template = "${file("${path.module}/amp_key_policy.json.tpl")}"
vars = {
allowed_resources = "${var.allowed_resources}" //tried without quotes
}
}
resource "aws_kms_key" "amp_key" {
description = ""
tags = local.common_tags
policy = data.template_file.temp_file.rendered
}
Error: Incorrect attribute value type
on main.tf line 10, in data "template_file" "temp_file":
10: vars = {
11: allowed_resources = "${var.allowed_resources}"
12: }
Inappropriate value for attribute "vars": element "allowed_resources": string required.
Updated:
i tried using aws_iam_policy_document.
data "aws_iam_policy_document" "amp_key_doc" {
for_each = toset(var.allowed_resources)
statement {
sid = "Enable IAM User Permissions"
effect = "Allow"
principals {
identifiers = ["arn:aws:iam::xxxxx:root"]
type = "AWS"
}
actions = ["kms:*"]
resources = ["*"]
}
statement {
sid = "Allow access for Key Administrators"
effect = "Allow"
principals {
identifiers = ["arn:aws:iam::xxxx:user/a"]
type = "AWS"
}
actions = [
"kms:Create*",
"kms:Describe*",
"kms:Enable*",
"kms:List*",
"kms:Put*",
"kms:Update*",
"kms:Revoke*",
"kms:Disable*",
"kms:Get*",
"kms:Delete*",
"kms:TagResource",
"kms:UntagResource",
"kms:ScheduleKeyDeletion",
"kms:CancelKeyDeletion"]
resources = ["*"]
}
statement {
sid = "Allow use of the key"
effect = "Allow"
principals {
identifiers = [var.allowed_resources]
type = "AWS"
}
actions = [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
]
resources = ["*"]
}
statement {
sid = "Allow attachment of persistent resources"
effect = "Allow"
principals {
identifiers = [var.allowed_resources]
type = "AWS"
}
actions = [
"kms:CreateGrant",
"kms:ListGrants",
"kms:RevokeGrant"
]
resources = ["*"]
condition {
test = "Bool"
values = ["true"]
variable = "kms:GrantIsForAWSResource"
}
}
}
resource "aws_kms_key" "key" {
description = ""
tags = local.common_tags
policy = data.aws_iam_policy_document.key_doc.json
Got an error , How do we pass the entire chunk of allowed_resources?
Error: Incorrect attribute value type
on data.tf line 43, in data "aws_iam_policy_document" "key_doc":
43: identifiers = [var.allowed_resources]
Inappropriate value for attribute "identifiers": element 0: string required.
Error: Incorrect attribute value type
on data.tf line 60, in data "aws_iam_policy_document" "key_doc": 60: identifiers = [var.allowed_resources]
Inappropriate value for attribute "identifiers": element 0: string required.
The error comes down to values of vars
only supporting primitive types as stated in the documentation
Variables for interpolation within the template. Note that variables must all be primitives. Direct references to lists or maps will cause a validation error.
If you create your policy as a iam_policy_document you can use the json attribute of the resource to pass into your aws_kms_key
resource.