amazon-web-servicesterraformterraform-provider-awsamazon-kms

Why does terraform give error "Policy contains a statement with one or more invalid principals."


Trying to create kms key with following terraform code causes same terraform error in both cases. I have tried too many times and I cannot find reason why. Is the wildcard not allowed in a policy of kms? This happens when my permissions stack is being created i.e. the stack that creates most of the permissions for the resources.

Terraform error.

│ Error: updating KMS Key (ssss-cdb7-xxx-a58c-ss): updating policy: MalformedPolicyDocumentException: Policy contains a statement with one or more invalid principals.
│ 
│   with module.kms.aws_kms_key.sns-encryption-key,
│   on kms/main.tf line 181, in resource "aws_kms_key" "sns-encryption-key":
│  181: resource "aws_kms_key" "sns-encryption-key" {
resource "aws_kms_key" "sns-encryption-key" {
  description             = "This key is used to encrypt sns queue"
  deletion_window_in_days = 7
  enable_key_rotation     = true
  policy                  = jsonencode({
    Version   = "2012-10-17"
    Statement = [
      {
        Effect    = "Allow"
        Principal = {
          Service = "s3.amazonaws.com"
        }
        Action = [
          "kms:GenerateDataKey*",
          "kms:Decrypt"
        ]
        Resource = "*"
      },
      {
        Effect    = "Allow"
        Principal = {
          AWS = [
            "arn:aws:iam::${var.account_id}:role/${var.env_name}*",
            "arn:aws:iam::${var.account_id}:root"
          ]
        }
        Action = [
          "kms:*",
        ]
        Resource = "*"
      },
    ]
  })

  tags = {
    Environment     = var.env_name
    EnvironmentType = var.env_type
    CreatedAt       = timestamp()
  }
  lifecycle {
    prevent_destroy = true
  }
}
resource "aws_kms_key" "sns-encryption-key" {
  description             = "This key is used to encrypt sns queue"
  deletion_window_in_days = 7
  enable_key_rotation    = true
      # Version = "2012-10-17",
      # Id      = "key-policy-1",
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Resource = "*"
        Action = ["kms:GenerateDataKey*", "kms:Decrypt", "kms:Encrypt"]
        Principal = {
          Service = "s3.amazonaws.com"
        }
      },
      {
        Effect  = "Allow"
        Principal = {
          AWS = "arn:aws:iam::${var.account_id}:role/*" 
        }
        Action = [ "kms:*" ]
        Resource = "*"
      },
      {
        Effect    = "Allow"
        Principal = {
          AWS = "arn:aws:iam::${var.account_id}:root"
        }
        Action = ["kms:*"]
        Resource = "*"
      }
    ]
  })

  tags = {
    Environment     = var.env_name
    EnvironmentType = var.env_type
    CreatedAt       = timestamp()
  }
  lifecycle {
    prevent_destroy = true
  }
}

Solution

  • The documentation on Specifying a Principal states that wildcards are not allowed:

    Note

    You cannot use a wildcard to match part of a principal name or ARN.

    Therefore your role ARN pattern which ends with a * wildcard is invalid for use in the Principal element.