在此答案的背面,我正在尝试创建一个允许访问 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
是一个有效的委托人。我做错了什么?
这个问题似乎还没有完全回答,所以我将尝试举一个关于如何为我的 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"
}
}
我认为您正在尝试授予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}"
}
希望,它有帮助。
您需要将下面提到的手动策略附加到您的 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
}
您的角色是为需要策略才能使用其他资源的服务创建的,我不确定这是否有帮助。
你需要创建一个能够承担的角色,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
}
在这种情况下,您需要将<aws_ecr_repository.repo.name>
替换为实际的存储库名称。
我希望这有所帮助。