【问题标题】:Cross-Account ECS Deployment跨账户 ECS 部署
【发布时间】:2020-01-25 00:58:11
【问题描述】:

我正在尝试使用 CodePipeline 将映像从一个帐户 (AccountA) 的 ECR 部署到另一个帐户 (AccountB) 的 ECS 集群。我在部署阶段遇到与权限相关的错误。

这是我在 AccountA 中的管道角色:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:GetBucketVersioning"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::<bucketname>/*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "ecr:GetAuthorizationToken",
                "ecr:BatchCheckLayerAvailability",
                "ecr:GetDownloadUrlForLayer",
                "ecr:GetRepositoryPolicy",
                "ecr:DescribeRepositories",
                "ecr:ListImages",
                "ecr:DescribeImages",
                "ecr:BatchGetImage",
                "ecr:InitiateLayerUpload",
                "ecr:UploadLayerPart",
                "ecr:CompleteLayerUpload",
                "ecr:PutImage"
            ],
            "Resource": [
                "*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "codebuild:BatchGetBuilds",
                "codebuild:InvalidateProjectCache",
                "codebuild:StartBuild",
                "codebuild:StopBuild",
                "codebuild:UpdateProject",
                "codebuild:UpdateWebhook"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": "arn:aws:iam::<AccountB>:role/taskexecutionrole",
            "Effect": "Allow"
        }
    ]
}

arn:aws:iam::&lt;AccountB&gt;:role/taskexecutionrole 角色存在于 AccountB 中并信任 AccountA。这是 AccountB 中的角色:

{
            "Effect": "Allow",
            "Action": "ecs:*",
            "Resource": [
                "*"
            ]
}

管道有一个 ECR 源,构建阶段生成一个 imagedefinitions.json 文件。最后在部署阶段进行 ECS 部署。

我得到的错误是: 无效的动作配置 标识符用于 AccountB。您的 accountId 是 AccountA

This answer 仅有助于手动 CLI 部署,我已经尝试了 this answer 的解决方案。

任何我缺少的指针?

【问题讨论】:

    标签: amazon-web-services amazon-ecs aws-codepipeline


    【解决方案1】:

    假设:

    Account_A => 代码管道和来源
    Account_B => ECS

    这是需要的:

    Account_A:
    * AWSCodePipelineServiceRole
    * Artifact_Store_S3_Bucket
    * KMS_Key_for_Pipeline_Artifact(客户管理的密钥)
    * Artifact_Store_S3_Bucket 上的存储桶策略允许 Account_B 访问
    * 允许访问 Cross_Account_Role(来自 Account_B)的 KMS_Key_for_Pipeline_Artifact 的关键策略

    Account_B
    * Cross_Account_Role(与 Account_A 和 Full_ECS 权限的信任关系)
    * 正在运行的 ECS 将被部署替换

    imagedefinitions.json(必须是源代码的一部分)

    [ 
        { 
          "name": "container_name", 
          "imageUri": "nginx:latest" 
        } 
    ]
    

    Artifact_Store_S3_Bucket 上的 Bucket_Policy

    {
        "Version": "2012-10-17",
        "Id": "SSEAndSSLPolicy",
        "Statement": [
            {
                "Sid": "DenyUnEncryptedObjectUploads",
                "Effect": "Deny",
                "Principal": "*",
                "Action": "s3:PutObject",
                "Resource": "arn:aws:s3:::Artifact_Store_S3_Bucket/*",
                "Condition": {
                    "StringNotEquals": {
                        "s3:x-amz-server-side-encryption": "aws:kms"
                    }
                }
            },
            {
                "Sid": "DenyInsecureConnections",
                "Effect": "Deny",
                "Principal": "*",
                "Action": "s3:*",
                "Resource": "arn:aws:s3:::Artifact_Store_S3_Bucket/*",
                "Condition": {
                    "Bool": {
                        "aws:SecureTransport": "false"
                    }
                }
            },
            {
                "Sid": "",
                "Effect": "Allow",
                "Principal": {
                    "AWS": "arn:aws:iam::Account_B:root"
                },
                "Action": [
                    "s3:Get*",
                    "s3:Put*"
                ],
                "Resource": "arn:aws:s3:::Artifact_Store_S3_Bucket/*"
            },
            {
                "Sid": "",
                "Effect": "Allow",
                "Principal": {
                    "AWS": "arn:aws:iam::Account_B:root"
                },
                "Action": "s3:ListBucket",
                "Resource": "arn:aws:s3:::Artifact_Store_S3_Bucket"
            }
        ]
    }
    

    pipeline.json:

    {
        "pipeline": {
            "name": "test",
            "roleArn": "arn:aws:iam::Account_A:role/service-role/AWSCodePipelineServiceRole",
            "artifactStore": {
                "type": "S3",
                "location": "Artifact_Store_S3_Bucket",
                "encryptionKey": {
                  "id": "arn:aws:kms:us-east-1:Account_A:key/KMS_Key_for_Pipeline_Artifact",
                  "type": "KMS"
                }
            },
            "stages": [
                {
                    "name": "Source",
                    "actions": [
                        {
                            "name": "Source",
                            "actionTypeId": {
                                "category": "Source",
                                "owner": "AWS",
                                "provider": "CodeCommit",
                                "version": "1"
                            },
                            "runOrder": 1,
                            "configuration": {
                                "BranchName": "master",
                                "PollForSourceChanges": "false",
                                "RepositoryName": "code"
                            },
                            "outputArtifacts": [
                                {
                                    "name": "SourceArtifact"
                                }
                            ],
                            "inputArtifacts": [],
                            "region": "us-east-1"
                        }
                    ]
                },
                {
                    "name": "Deploy",
                    "actions": [
                        {
                            "name": "Deploy",
                            "actionTypeId": {
                                "category": "Deploy",
                                "owner": "AWS",
                                "provider": "ECS",
                                "version": "1"
                            },
                            "runOrder": 1,
                            "roleArn": "arn:aws:iam::Account_B:role/CrossAccount_Role",
                            "configuration": {
                                "ClusterName": "<Cluster>",
                                "ServiceName": "<Service>"
                            },
                            "outputArtifacts": [],
                            "inputArtifacts": [
                                {
                                    "name": "SourceArtifact"
                                }
                            ],
                            "region": "us-east-1"
                        }
                    ]
                }
            ],
            "version": 1
        }
    }
    

    更新管道:

    $ aws codepipeline update-pipeline --region us-east-1 --cli-input-json file://pipeline.json

    【讨论】:

    • 非常感谢,它几乎可以工作了。不知何故,S3 工件存储桶未正确加密并且失败,当我使用 KMS 密钥手动加密它时,部署工作正常。你知道整个事情是否可以在没有加密的情况下工作吗?如果我禁用 KMS 加密,我会收到 accessdenied 错误。当我尝试使用 cloudformation 创建存储桶时遇到格式错误的 XML 异常。
    • 更新:我现在可以默认加密存储桶,但管道中的 CodeBuild 阶段使用不同的加密密钥写入,尝试修复,应该很快完成......
    • 很高兴我能提供帮助。
    • @gkris 您在账户 A 或账户 B 中的哪里设置了 codedeploy?
    猜你喜欢
    • 1970-01-01
    • 2020-10-07
    • 1970-01-01
    • 2017-07-23
    • 1970-01-01
    • 2023-02-21
    • 1970-01-01
    • 2022-08-02
    • 2020-07-17
    相关资源
    最近更新 更多