title: Terraform malformed policy
body: <p>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.</p>
  <p>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 ..</p>
  <p>Looks like i can't use a data block, Is there any way i can to avoid the rearranging on arn in Principal block?</p>
  <p>I'm using terraform 0.12.20</p>
  <p>policy.json.tpl</p>
  <pre><code>{
      &quot;Version&quot;: &quot;2012-10-17&quot;,
      &quot;Id&quot;: &quot;key-policy-1&quot;,
      &quot;Statement&quot;: [{
              &quot;Sid&quot;: &quot;Enable IAM User Permissions&quot;,
              &quot;Effect&quot;: &quot;Allow&quot;,
              &quot;Principal&quot;: {
                  &quot;AWS&quot;: ${allowed_resources}
              },
              &quot;Action&quot;: &quot;kms:*&quot;,
              &quot;Resource&quot;: &quot;*&quot;
          },
          {
              &quot;Sid&quot;: &quot;Allow use of the key&quot;,
              &quot;Effect&quot;: &quot;Allow&quot;,
              &quot;Principal&quot;: {
                  &quot;AWS&quot;: ${allowed_resources}
              },
              &quot;Action&quot;: [
                  &quot;kms:Encrypt&quot;,
                  &quot;kms:Decrypt&quot;,
                  &quot;kms:ReEncrypt*&quot;,
                  &quot;kms:GenerateDataKey*&quot;,
                  &quot;kms:DescribeKey&quot;
              ],
              &quot;Resource&quot;: &quot;*&quot;
          }
      ]
  }
  </code></pre>
  <p>main.tf</p>
  <pre><code>resource &quot;aws_kms_key&quot; &quot;key&quot; {
    description = &quot;&quot;
    tags        = local.common_tags
    policy      = templatefile(&quot;${path.module}/policy.json.tpl&quot;, {
      allowed_resources = var.allowed_resources
    })
  }
  </code></pre>
  <p>variables.tf</p>
  <pre><code>variable &quot;allowed_resources&quot; {
    description = &quot;list of all principal resources&quot;
    type        = list(string)
    default = [
      &quot;arn:aws:iam::xxxxxxxxxxxx:user/a&quot;,
      &quot;arn:aws:iam::xxxxxxxxxxxxx:user/b&quot;,
      &quot;arn:aws:iam::xxxxxxxxxx:user/c&quot;,
      &quot;arn:aws:iam::xxxxxxxxxx:role/abc
    ]
  }
  </code></pre>
  <p>Error</p>
  <pre><code>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 &quot;kms_key&quot; &quot;key&quot;:
  10:53:19    8: resource &quot;aws_kms_key&quot; &quot;key&quot; {
  </code></pre>
  <p>Terraform plan:
  Terraform will perform the following actions:</p>
  <pre><code>  # aws_kms_key.amp_key will be updated in-place
    ~ resource &quot;aws_kms_key&quot; &quot;amp_key&quot; {
          arn                      = &quot;arn:aws:kms:us-east-1:xxxx:key/xxx-xxx-xxx-xx-xxxxxxxx&quot;
          customer_master_key_spec = &quot;SYMMETRIC_DEFAULT&quot;
          enable_key_rotation      = false
          id                       = &quot;xxx-xxx-xxx-xx-xxxxxxxx&quot;
          is_enabled               = true
          key_id                   = &quot;xxx-xxx-xxx-xx-xxxxxxxx&quot;
          key_usage                = &quot;ENCRYPT_DECRYPT&quot;
        ~ policy                   = jsonencode(
            ~ {
                  Id        = &quot;key-policy-1&quot;
                ~ Statement = [
                      {
                          Action    = &quot;kms:*&quot;
                          Effect    = &quot;Allow&quot;
                          Principal = {
                              AWS = &quot;arn:aws:iam::xxxxxxxx:root&quot;
                          }
                          Resource  = &quot;*&quot;
                          Sid       = &quot;Enable IAM User Permissions&quot;
                      },
                    ~ {
                          Action    = [
                              &quot;kms:Encrypt&quot;,
                              &quot;kms:Decrypt&quot;,
                              &quot;kms:ReEncrypt*&quot;,
                              &quot;kms:GenerateDataKey*&quot;,
                              &quot;kms:DescribeKey&quot;,
                          ]
                          Effect    = &quot;Allow&quot;
                        ~ Principal = {
                            ~ AWS = [
                                + &quot;arn:aws:iam::xxxxxx:user/c&quot;,
                                + &quot;arn:aws:iam::xxxxxx:user/a&quot;,
                                - &quot;arn:aws:iam::xxxxxx:role/abc&quot;,
                                - &quot;arn:aws:iam::xxxxxx:user/a&quot;,
                                - &quot;arn:aws:iam::xxxxxx:user/c&quot;,
                                  &quot;arn:aws:iam::xxxxxx:user/b&quot;,
                                + &quot;arn:aws:iam::xxxxxx:role/abc&quot;,
                           ]
                         }
                       ]
                  Version   = &quot;2012-10-17&quot;
                       }
                   )
  </code></pre>
  <p>When i tried to use data block</p>
  <pre><code>data &quot;template_file&quot; &quot;temp_file&quot; {
    template = &quot;${file(&quot;${path.module}/amp_key_policy.json.tpl&quot;)}&quot;
    vars = {
      allowed_resources = &quot;${var.allowed_resources}&quot; //tried without quotes
    }
  }
  resource &quot;aws_kms_key&quot; &quot;amp_key&quot; {
    description = &quot;&quot;
    tags        = local.common_tags
    policy      = data.template_file.temp_file.rendered
  }
  </code></pre>
  <p>Error: Incorrect attribute value type</p>
  <pre><code>  on main.tf line 10, in data &quot;template_file&quot; &quot;temp_file&quot;:
    10:   vars = {
    11:     allowed_resources = &quot;${var.allowed_resources}&quot;
    12:   }
  </code></pre>
  <p>Inappropriate value for attribute &quot;vars&quot;: element &quot;allowed_resources&quot;: string
  required.</p>
  <p>Updated:</p>
  <p>i tried using aws_iam_policy_document.</p>
  <pre><code>data &quot;aws_iam_policy_document&quot; &quot;amp_key_doc&quot; {
    for_each = toset(var.allowed_resources)
    statement {
      sid    = &quot;Enable IAM User Permissions&quot;
      effect = &quot;Allow&quot;
      principals {
        identifiers = [&quot;arn:aws:iam::xxxxx:root&quot;]
        type        = &quot;AWS&quot;
      }
      actions   = [&quot;kms:*&quot;]
      resources = [&quot;*&quot;]
    }
  
    statement {
      sid    = &quot;Allow access for Key Administrators&quot;
      effect = &quot;Allow&quot;
      principals {
        identifiers = [&quot;arn:aws:iam::xxxx:user/a&quot;]
        type        = &quot;AWS&quot;
      }
      actions = [
        &quot;kms:Create*&quot;,
        &quot;kms:Describe*&quot;,
        &quot;kms:Enable*&quot;,
        &quot;kms:List*&quot;,
        &quot;kms:Put*&quot;,
        &quot;kms:Update*&quot;,
        &quot;kms:Revoke*&quot;,
        &quot;kms:Disable*&quot;,
        &quot;kms:Get*&quot;,
        &quot;kms:Delete*&quot;,
        &quot;kms:TagResource&quot;,
        &quot;kms:UntagResource&quot;,
        &quot;kms:ScheduleKeyDeletion&quot;,
      &quot;kms:CancelKeyDeletion&quot;]
      resources = [&quot;*&quot;]
    }
  
    statement {
      sid    = &quot;Allow use of the key&quot;
      effect = &quot;Allow&quot;
      principals {
        identifiers = [var.allowed_resources]
        type        = &quot;AWS&quot;
      }
      actions = [
        &quot;kms:Encrypt&quot;,
        &quot;kms:Decrypt&quot;,
        &quot;kms:ReEncrypt*&quot;,
        &quot;kms:GenerateDataKey*&quot;,
        &quot;kms:DescribeKey&quot;
      ]
      resources = [&quot;*&quot;]
    }
  
    statement {
      sid    = &quot;Allow attachment of persistent resources&quot;
      effect = &quot;Allow&quot;
      principals {
        identifiers = [var.allowed_resources]
        type        = &quot;AWS&quot;
      }
      actions = [
        &quot;kms:CreateGrant&quot;,
        &quot;kms:ListGrants&quot;,
        &quot;kms:RevokeGrant&quot;
      ]
      resources = [&quot;*&quot;]
      condition {
        test     = &quot;Bool&quot;
        values   = [&quot;true&quot;]
        variable = &quot;kms:GrantIsForAWSResource&quot;
      }
    }
  }
  
  
  resource &quot;aws_kms_key&quot; &quot;key&quot; {
    description = &quot;&quot;
    tags        = local.common_tags
    policy      = data.aws_iam_policy_document.key_doc.json
  </code></pre>
  <p>Got an error , How do we pass the entire chunk of allowed_resources?</p>
  <pre><code>Error: Incorrect attribute value type
  
    on data.tf line 43, in data &quot;aws_iam_policy_document&quot; &quot;key_doc&quot;:
    43:       identifiers = [var.allowed_resources]
  
  Inappropriate value for attribute &quot;identifiers&quot;: element 0: string required.
  </code></pre>
  <p>Error: Incorrect attribute value type</p>
  <p>on data.tf line 60, in data &quot;aws_iam_policy_document&quot; &quot;key_doc&quot;:
  60:       identifiers = [var.allowed_resources]</p>
  <p>Inappropriate value for attribute &quot;identifiers&quot;: element 0: string required.</p>