Search code examples
amazon-web-servicesterraformterraform-provider-awsamazon-kms

Terraform encountered: unmarshaling policy 1: value of type awspolicy.intermediatePolicyDocument


Background

I am trying to setup a webapp using EKS, and am trying to setup DNS configuration options via Terraform (KMS stuff & records/rules that may change).

Expected Outcome

  • The AWS_KMS_Key should be created, & have the Policy "example" provisioned too it.

Description

This error occurs anytime I try to run terraform apply or terraform plan, and it doesn't make it to the yes/no step. I was able to create it once, but it doesn't seem to let me delete it. I have gone in manually to disable the key and schedule it for deletion. Is this an error that arises from the Key being seemingly "protected", or is it an error in Terraform trying to read the data object, or is it something else? Any help or insight is appreciated, I am mostly confused by the error "cannot unmarshal string", since I've never seen any similar error, and I don't have a clue what "unmarshalling" is.

Resource Object: aws_kms_key

resource "aws_kms_key" "example" {
  customer_master_key_spec = "ECC_NIST_P256"
  deletion_window_in_days  = 7
  key_usage                = "SIGN_VERIFY"
  policy = data.aws_iam_policy_document.example.json
}

Data Object: aws_iam_policy_document

data "aws_caller_identity" "me" {} # Gets the account info of the current connection ~(whoami)

data "aws_iam_policy_document" "example" {
    version = "2012-10-17"
    statement {
        sid = "Allow Route 53 DNSSEC Service"
        effect = "Allow"
        resources = ["*"]

        actions = [
            "kms:DescribeKey",
            "kms:GetPublicKey",
            "kms:Sign"
        ]

        principals {
            type        = "Service"
            identifiers = ["dnssec-route53.amazonaws.com"]
        }

        condition {
            test     = "ForAnyValue:StringEquals"
            variable = "aws:SourceAccount"
            values   = ["${data.aws_caller_identity.me.account_id}"]
        }

        condition {
            test     = "ForAnyValue:ArnLike"
            variable = "aws:SourceArn"
            values   = ["arn:aws:route53:::hostedzone/*"]
        }
    }
    statement {
        sid = "Allow Route 53 DNSSEC Service to CreateGrant"
        effect = "Allow"
        resources = ["*"]

        actions = [
            "kms:CreateGrant"
        ]

        principals {
            type        = "Service"
            identifiers = ["dnssec-route53.amazonaws.com"]
        }

        condition {
            test     = "Bool"
            variable = "kms:GrantIsForAWSresource"
            values   = ["true"]
        }
    }
    statement {
        sid = "Enable IAM User Permissions"
        effect = "Allow"
        resources = ["*"]

        actions = [
            "kms:*"
        ]

        principals {
            type        = "AWS"
            identifiers = ["arn:aws:iam::${data.aws_caller_identity.me.account_id}:root"]
        }
    }
}

ERROR output (Cleaned)

Error: while setting policy (<Json_of_Policy_Doc>), 
encountered: unmarshaling policy 1: 
json: cannot unmarshal string into Go value of type awspolicy.intermediatePolicyDocument

ERROR output

Error: while setting policy (
{"Statement":[
{"Action":["kms:DescribeKey","kms:GetPublicKey","kms:Sign"],
"Condition":{"ArnLike":{"aws:SourceArn":"arn:aws:route53:::hostedzone/*"},"StringEquals":{"aws:SourceAccount":"<aws_account_id>"}},
"Effect":"Allow",
"Principal":{"Service":"dnssec-route53.amazonaws.com"},
"Resource":"*",
"Sid":"Allow Route 53 DNSSEC Service"},

{"Action":"kms:CreateGrant",
"Condition":{"Bool":{"kms:GrantIsForAWSResource":"true"}},
"Effect":"Allow",
"Principal":{"Service":"dnssec-route53.amazonaws.com"},
"Resource":"*",
"Sid":"Allow Route 53 DNSSEC Service to CreateGrant"},

{"Action":"kms:*",
"Effect":"Allow",
"Principal":{"AWS":"arn:aws:iam::<aws_account_id>:root"},
"Resource":"*",
"Sid":"Enable IAM User Permissions"}],

"Version":"2012-10-17"}), 
encountered: unmarshaling policy 1: json: cannot unmarshal string into Go value of type awspolicy.intermediatePolicyDocument

Solution

  • You cannot use that kind of sid because as per the AWS documentation [1] it can only be:

    The Sid element supports ASCII uppercase letters (A-Z), lowercase letters (a-z), and numbers (0-9).

    This means you cannot use spaces in the sid argument.


    [1] https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html