【问题标题】:How do I create an IAM role in Terraform for Amazon ECR?如何在 Terraform for Amazon ECR 中创建 IAM 角色?
【发布时间】:2020-01-06 18:46:15
【问题描述】:

this answer 的后面,我正在尝试创建一个允许访问 ECR 的aws_iam_role。但是,当我定义以下内容时:

resource "aws_iam_role" "jenkins_ecr_role" {
  name = "JenkinsECRRole"

  assume_role_policy = <<END_OF_POLICY
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "ecr.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
END_OF_POLICY
}

我得到错误:

Error: Error creating IAM Role JenkinsECRRole:
MalformedPolicyDocument: Invalid principal in policy: "SERVICE":"*"

根据 AWS 文档,ecr.amazonaws.com 似乎是一个有效的委托人。我做错了什么?

【问题讨论】:

  • 允许 ECR 代入角色,不允许用户/实例配置文件代入能够与 ECR 交互的角色。
  • @ydaetskcoR 那么在这种情况下正确的 Principal 是什么?
  • 我也做了同样的假设。原来Principal 是 AWS 服务访问 ECR 所需要的。就我而言,ecs 中的某些机器需要ecr 权限。所以Principal"Service": ["ecs.amazonaws.com"]

标签: amazon-web-services terraform amazon-iam terraform-provider-aws amazon-ecr


【解决方案1】:

似乎这个问题还没有完全回答,所以我将尝试举例说明我是如何为我的 gitlab-runner ec2 实例添加 ecr 的。首先,ec2 实例需要一个iam_instance_profile,您似乎已经拥有了。第二:您需要assume-role,以便实例可以承担服务的角色。 请注意,我可以访问所有资源,而不仅仅是特定资源(您可以根据需要进行调整)

角色

resource "aws_iam_role" "role" {
  name               = "${local.env}-role"
  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": ["ec2.amazonaws.com"]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF

}

允许访问 ECR 的政策

resource "aws_iam_policy" "policy" {
  name = "${local.env}-ecr-access-policy"
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = [
          "ecr:*",
        ]
        Effect   = "Allow"
        Resource = "*"
      },
    ]
  })
}

策略与角色的关联

resource "aws_iam_policy_attachment" "attach" {
  name       = "${local.env}-attach"
  roles      = ["${aws_iam_role.role.name}"]
  policy_arn = "${aws_iam_policy.policy.arn}"
}

最后是 EC2 需要的配置文件

resource "aws_iam_instance_profile" "profile" {
  name = "${local.env}-gitlab-runner-instance-profile"
  role = aws_iam_role.role.name
}

EC2 实例

resource "aws_instance" "ec2" {
  ami                         = "ami-06c94f9acb4ba21b2"
  instance_type               = "t2.small"
  associate_public_ip_address = true
  key_name                    = "<key_name>"
  subnet_id                   = <subnet>
  iam_instance_profile        = aws_iam_instance_profile.profile.name
  vpc_security_group_ids      = ["<security_group>"]

  tags = {
    Environment = "dev"
  }
}

【讨论】:

    【解决方案2】:

    我认为您正在尝试授予 EC2 访问 ECR 的权限。为此,您需要为 ECR 创建 IAM 策略并为 EC2 创建 IAM 角色并将角色附加到策略中。

    请参考这段代码:

    resource "aws_iam_role" "role" {
      name = "test-role"
    
      assume_role_policy = <<EOF
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Action": "sts:AssumeRole",
              "Principal": {
                "Service": "ec2.amazonaws.com"
              },
              "Effect": "Allow",
              "Sid": ""
            }
          ]
        }
    EOF
    }
    
    resource "aws_iam_policy" "policy" {
      name        = "test-policy"
      description = "A test policy"
    
      policy = <<EOF
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Action": [
            "ecr:*",
            "cloudtrail:LookupEvents"
          ],
          "Effect": "Allow",
          "Resource": "*"
        }
      ]
    }
    EOF
    }
    
    resource "aws_iam_role_policy_attachment" "test-attach" {
      role       = "${aws_iam_role.role.name}"
      policy_arn = "${aws_iam_policy.policy.arn}"
    }
    

    希望,它会有所帮助。

    【讨论】:

      【解决方案3】:

      您需要将下述手动策略附加到您的 IAM 角色。

      resource "aws_iam_role_policy" "role_policy" {
        name   = "${aws_iam_role.role.name}"
        role   = "${aws_iam_role.role.id}"
        policy = <<EOF
      {
        "Version": "2008-10-17",
        "Statement": [
          {
            "Sid": "new statement",
            "Effect": "Allow",
            "Principal": {
              "AWS": "<IAM-ROLE-ARN>"
            },
            "Action": [
              "ecr:BatchCheckLayerAvailability",
              "ecr:BatchGetImage",
              "ecr:CompleteLayerUpload",
              "ecr:GetDownloadUrlForLayer",
              "ecr:InitiateLayerUpload",
              "ecr:PutImage",
              "ecr:UploadLayerPart"
            ]
          }
        ]
      }
      EOF
      }
      

      【讨论】:

        【解决方案4】:

        您的角色是为需要该策略才能使用其他资源的服务创建的,我不确定这是否有帮助。

        您需要创建一个可以承担的角色,ec2、sagemaker、s3 等。 ECR 不承担任何角色,因为它只是一个注册表。

        例如,我有一个 Sagemaker 实例:

        resource "aws_iam_role" "sagemaker_model" {
        
          assume_role_policy = <<EOF
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Action": "sts:AssumeRole",
              "Principal": {
                "Service": "sagemaker.amazonaws.com"
              },
              "Effect": "Allow",
              "Sid": ""
            }
          ]
        }
        EOF
        
        }
        

        然后该实例需要使用其他资源 (ECR) 的权限:

        resource "aws_iam_policy" "ecr" {
        
          policy = <<EOF
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "VisualEditor0",
              "Effect": "Allow",
              "Action": [
                "ecr:*"
              ],
              "Resource": [
                "*"
              ]
            }
          ]
        }
        EOF
        }
        

        然后我将该策略附加到以前的角色:

        resource "aws_iam_role_policy_attachment" "model_attach_ecr" {
          role       = aws_iam_role.sagemaker_model.name
          policy_arn = aws_iam_policy.ecr.arn
        }
        

        虽然 ECR 有一个特定的属性,它有自己的访问策略,但您需要通过创建一个 aws_ecr_repository_policy 来允许之前创建的角色可以访问特定的容器注册表:

        resource "aws_ecr_repository_policy" "policy" {
        
          repository = <aws_ecr_repository.repo.name>
          policy     = <<EOF
        {
          "Version": "2008-10-17",
          "Statement": [
            {
              "Sid": "new statement",
              "Effect": "Allow",
              "Principal": {
                "AWS": "${aws_iam_role.sagemaker_model.arn}"
              },
              "Action": [
                "ecr:*"
              ]
            }
          ]
        }
        EOF
        }
        

        在这一项中,您需要将&lt;aws_ecr_repository.repo.name&gt; 替换为实际的存储库名称。

        我希望这会有所帮助。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-09-09
          • 2020-05-16
          • 2020-04-25
          • 2019-12-08
          • 2020-03-26
          • 2018-11-10
          • 2019-04-22
          相关资源
          最近更新 更多