使用 terraform 版本 0.12 的 AWS KMS 和 IAM 关联

AWS KMS and IAM association using terraform version 0.12

您好 AWS 和 Terraform 专家,我正在生成由我们的前同事手动构建的 KMS 和 IAM 关联,​​我在完成下面所述的 kms 策略副本时遇到问题:

{
"Version": "2012-10-17",
"Statement": [
    {
        "Effect": "Allow",
        "Principal": {
            "AWS": "arn:aws:iam::12345678912345:root"
        },
        "Action": "kms:*",
        "Resource": "*"
    },
    {
        "Effect": "Allow",
        "Principal": {
            "AWS": "ALSKDJFHGNVBCMXJDH0987"
        },
        "Action": "kms:Decrypt",
        "Resource": "*"
    }
]

}

这个 ALSKDJFHGNVBCMXJDH0987 是一个 IAM 角色,我认为它是由 AWS 控制台转换的(还不确定为什么)

  {
        "Effect": "Allow",
        "Principal": {
            "AWS": "ALSKDJFHGNVBCMXJDH0987"
        },
        "Action": "kms:Decrypt",
        "Resource": "*"
    }

我在使用我创建的 terraform 脚本时遇到此错误:

Error: MalformedPolicyDocumentException: Policy contains a statement with one or more invalid principals.
status code: 400, request id: alsknldkj2-assd-3333-0sdc-askdjaksdjn2

on main.tf line 84, in resource "aws_kms_key" "secrets":
84: resource "aws_kms_key" "secrets" {

顺序有问题吗?或者我错过了什么?这里附上我使用的地形代码:

data "template_file" "my-lambda-policy" {
 template = "${file("policy/lambda.json")}"
  vars = {
      SWAG = var.AWS-SWAG
      STUDENT-BELONGS = var.STUDENT
      STUDENT-TEACHER = var.TEACHER
      ROOM = var.CLASSROOM
  }
}

resource "aws_iam_policy" "my-lambda-pol" {
  name = "my-lambda-policy"
  policy = data.template_file.my-lambda-policy.rendered
}

data "template_file" "my-my-lambda-pol2" {
  template = "${file("policy/lambda2.json")}"
}

resource "aws_iam_policy" "my-lambda-pol2" {
  name = "my-my-lambda-pol2"
  policy = data.template_file.my-my-lambda-pol2.rendered
}

data "template_file" "my-lambda-to-my-kms-policy" {
  template = "${file("policy/kms-lambda.json")}"
  vars = {
      SWAG = var.AWS-SWAG
      KMS_KEY_ID = aws_kms_key.mysecret.id
  }
}

resource "aws_iam_policy" "lambda-to-kms" {
  name = "my-lambda-to-my-kms-policy"
  policy = data.template_file.my-lambda-to-my-kms-policy.rendered
}

resource "aws_iam_role" "the-lambda-role" {
  name = "{STUD_CHAIR}-${STU_SEAG}-${STUDENT-BELONGS}-${STUDENT-TEACHER}"
  assume_role_policy = <<EOF
{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Principal": {
            "Service": "lambda.amazonaws.com"
         },
         "Action": "sts:AssumeRole"
      }
   ]
}
EOF
}

resource "aws_iam_role_policy_attachment" "my-lambda-policy_attachment" {
  policy_arn = aws_iam_policy.my-lambda-pol.arn
  role = aws_iam_role.the-lambda-role.name
}

resource "aws_iam_role_policy_attachment" "my-lambda-pol2_attachment" {
  policy_arn = aws_iam_policy.my-lambda-pol2.arn
  role = aws_iam_role.the-lambda-role.name
}

resource "aws_iam_role_policy_attachment" "kms-attachment" {
  depends_on = [aws_kms_key.mysecret]
  policy_arn = aws_iam_policy.lambda-to-kms.arn
  role = aws_iam_role.the-lambda-role.name
}

data "template_file" "my-kms-policy" {
  template = "${file("policy/my-kms-policy.json")}"
  vars = {
      STUD_CHAIR= "${var.CHAIR}"
      STU_SWAG = "${l{var.SWAG}}"
      STUDENT-BELONGS = "${var.STUDENT}"
      STUDENT-TEACHER = "${var.TEACHER}"
      ROOM = "${var.CLASSROOM}"
  }
}

resource "aws_kms_key" "mysecret" {
  description = "KMS Key for ${var.STUDENT}-${var.TEACHER}-key-${var.CLASSROOM}"
  policy = data.template_file.my-kms-policy.rendered
  depends_on = [aws_iam_role.the-lambda-role]
}

resource "aws_kms_alias" "mysecret" {
  name = "alias/${var.STUDENT}-${var.TEACHER}-key-${var.CLASSROOM}"
  depends_on = [aws_iam_role.the-lambda-role]
  target_key_id = aws_kms_key.mysecret.key_id
}

这是 my-kms-policy.json

里面的内容
{
"Version": "2012-10-17",
"Statement": [
    {
        "Effect": "Allow",
        "Principal": {
            "AWS": "arn:aws:iam::${ROOM}:root"
        },
        "Action": "kms:*",
        "Resource": "*"
    },
    {
        "Effect": "Allow",
        "Principal": {
            "AWS": "arn:aws:iam::${ROOM}:role/${STUD_CHAIR}-${STU_SEAG}-${STUDENT-BELONGS}-${STUDENT-TEACHER}"
        },
        "Action": "kms:Decrypt",
        "Resource": "*"
    }
]
}

解决方法

解决方法是 运行 terraform apply 两次。

原因

重新创建 IAM 角色时,需要更新引用此角色的策略,原因如下所述:

https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user.html

If your Principal element contains the ARN for a specific IAM role or user, then that ARN is transformed to a unique principal ID when the policy is saved. This helps mitigate the risk of someone escalating their permissions by removing and recreating the role or user. You don't normally see this ID in the console because there is also a reverse transformation back to the ARN when the trust policy is displayed. However, if you delete the role or user, then the principal ID appears in the console because AWS can no longer map it back to an ARN. Therefore, if you delete and recreate a user or role referenced in a trust policy's Principal element, you must edit the role to replace the ARN.

运行 Terraform 第一次将重新创建 IAM 角色,这样就违反了政策。 运行 第二次将通过添加新创建的对 IAM 角色的引用来更正策略。