CodePipeline을 사용하여 다른 계정에서 AWS CloudFormation 스택을 배포하려면 어떻게 해야 하나요?

최종 업데이트 날짜: 2022년 1월 19일

AWS CodePipeline을 사용하여 다른 AWS 계정에서 AWS CloudFormation 스택을 배포하고 싶습니다. 어떻게 설정해야 하나요?

간략한 설명

CodePipeline을 사용하여 다른 AWS 계정에서 CloudFormation 스택을 배포하려면 다음을 수행합니다.

참고: 이 절차에서는 계정 1계정 2, 두 개의 AWS 계정이 있다고 가정합니다.

1.    (계정 1에서) 다음에 키 사용 권한을 부여하는 고객 관리형 AWS Key Management Service(AWS KMS) 키를 생성합니다.

  • 계정 1의 CodePipeline 서비스 역할
  • 계정 2

2.    (계정 1에서) 계정 2에 버킷에 대한 액세스 권한을 부여하는 버킷 정책을 사용하여 Amazon Simple Storage Service (Amazon S3) 버킷을 생성합니다.

3.    (계정 2에서) 다음을 허용하는 교차 계정 AWS Identity and Access Management(IAM) 역할을 생성합니다.

  • CloudFormation API 작업
  • 계정 1에서 Amazon S3 버킷에 액세스
  • 계정 1의 고객 관리형 AWS KMS 키를 사용한 암호 해독

4.    (계정 1에서) 계정 2에서 교차 계정 역할을 수임할 수 있도록 계정 1의 CodePipeline 서비스 역할에 AssumeRole 권한을 추가합니다.

5.    (계정 2에서) 스택에 의해 배포된 서비스에 필요한 권한을 포함하는 CloudFormation 스택에 대한 서비스 역할을 생성합니다.

6.    (계정 1에서) 계정 2와 연결된 리소스를 포함하도록 계정 1에서 CodePipeline 구성을 업데이트합니다.

해결 방법

(계정 1에서) 계정 1의 CodePipeline 서비스 역할 및 계정 2에 사용 권한을 부여하는 고객 관리형 AWS KMS 키 생성

1.    계정 1에서 AWS KMS 콘솔을 엽니다.

2.    탐색 창에서 고객 관리형 키를 선택합니다.

3.    키 생성(Create key)을 선택합니다. 그런 다음 대칭(Symmetric)을 선택합니다.

참고: 고급 옵션(Advanced options) 섹션에서 오리진을 KMS로 그대로 둡니다.

4.    별칭에 키 이름을 입력합니다.

5.    (선택 사항) 사용 사례를 기반으로 태그를 추가합니다. 그런 다음 다음(Next)을 선택합니다.

6.    키 관리자의 경우 키 관리 권한 정의 페이지에서 AWS Identity and Access Management(IAM) 사용자를 선택합니다. 또한 키에 대한 관리자 역할을 맡기려는 다른 사용자 또는 그룹도 선택합니다. 그런 다음 다음(Next)을 선택합니다.

7.    키 사용 권한 정의 페이지에서 이 계정에 대해 키에 액세스할 IAM 자격 증명을 추가합니다. 예를 들면 CodePipeline 서비스 역할입니다.

8.    다른 AWS 계정(Other AWS accounts) 섹션에서 다른 AWS 계정 추가(Add another AWS account)를 선택합니다. 그런 다음 계정 2에서 IAM 역할의 Amazon 리소스 이름(ARN)을 입력합니다.

9.    다음(Next)을 선택합니다. 그런 다음 마침(Finish)을 선택합니다.

10.    고객 관리형 키(Customer managed keys) 섹션에서 방금 생성한 키를 선택합니다. 그런 다음 키의 ARN을 복사합니다.

중요: 파이프라인을 업데이트하고 IAM 정책을 구성할 때 AWS KMS 키의 ARN이 있어야 합니다.

(계정 1에서) 계정 2에 버킷에 대한 액세스 권한을 부여하는 버킷 정책을 사용하여 Amazon S3 버킷 생성

1.    계정 1에서 Amazon S3 콘솔을 엽니다.

2.    CodePipeline의 ArtifactStore로 사용할 기존 Amazon S3 버킷을 선택하거나 새 S3 버킷을 생성합니다.

참고: 아티팩트에 스택 템플릿 파일, 템플릿 구성 파일 또는 둘 다 포함될 수 있습니다. CodePipeline은 이러한 아티팩트를 통해 CloudFormation 스택 및 변경 세트를 사용합니다. 템플릿 구성 파일에서 템플릿 파라미터 값, 스택 정책 및 태그를 지정해야 합니다.

3.    버킷의 Amazon S3 세부 정보 페이지에서 권한을 선택합니다.

4.    [Bucket Policy]를 선택합니다.

5.    버킷 정책 편집기에서 다음 정책을 입력합니다.

중요: codepipeline-source-artifact를 CodePipeline의 SourceArtifact 버킷 이름으로 바꿉니다. ACCOUNT_B_NO계정 2의 계정 번호로 바꿉니다.

{
  "Id": "Policy1553183091390",
  "Version": "2012-10-17",
  "Statement": [{
      "Sid": "",
      "Action": [
        "s3:Get*",
        "s3:Put*"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::codepipeline-source-artifact/*",
      "Principal": {
        "AWS": [
          "arn:aws:iam::ACCOUNT_B_NO:root"
        ]
      }
    },
    {
      "Sid": "",
      "Action": [
        "s3:ListBucket"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::codepipeline-source-artifact",
      "Principal": {
        "AWS": [
          "arn:aws:iam::ACCOUNT_B_NO:root"
        ]
      }
    }
  ]
}

6.    저장(Save)을 선택합니다.

(계정 2에서) 교차 계정 IAM 역할 생성

다음을 수행하는 IAM 정책을 생성합니다.

  • 계정 2에서 교차 계정 IAM 역할을 수임하는 계정 1의 파이프라인
  • CloudFormation API 작업
  • SourceArtifact와 관련된 Amazon S3 API 작업

1.    계정 2에서 IAM 콘솔을 엽니다.

2.    탐색 창에서 정책(Policies)을 선택합니다. 그런 다음, 정책 생성(Create Policy)을 선택합니다.

3.    JSON 탭을 선택합니다. 그런 다음, 다음 정책을 JSON 편집기에 입력합니다.

중요: codepipeline-source-artifact를 파이프라인 아티팩트 스토어의 버킷 이름으로 바꿉니다.

{
  "Version": "2012-10-17",
  "Statement": [{
      "Effect": "Allow",
      "Action": [
        "cloudformation:*",
        "iam:PassRole"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:Get*",
        "s3:Put*",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::codepipeline-source-artifact/*"
      ]
    }
  ]
}

4.    [정책 검토(Review policy)]를 선택합니다.

5.    이름(Name)에 정책 이름을 입력합니다.

6.    정책 생성(Create policy)을 선택합니다.

AWS KMS API 작업을 허용하는 두 번째 IAM 정책 생성

1.    계정 2에서 IAM 콘솔을 엽니다.

2.    탐색 창에서 정책(Policies)을 선택합니다. 그런 다음, 정책 생성(Create Policy)을 선택합니다.

3.    JSON 탭을 선택합니다. 그런 다음, 다음 정책을 JSON 편집기에 입력합니다.

중요: arn:aws:kms:REGION:ACCOUNT_A_NO:key/key-id를 앞서 복사한 AWS KMS 키의 ARN으로 바꿉니다.

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "kms:DescribeKey",
      "kms:GenerateDataKey*",
      "kms:Encrypt",
      "kms:ReEncrypt*",
      "kms:Decrypt"
    ],
    "Resource": [
      "arn:aws:kms:REGION:ACCOUNT_A_NO:key/key-id"
    ]
  }]
}

4.    [정책 검토(Review policy)]를 선택합니다.

5.    이름(Name)에 정책 이름을 입력합니다.

6.    정책 생성(Create policy)을 선택합니다.

생성한 정책을 사용하여 교차 계정 IAM 역할 생성

1.    계정 2에서 IAM 콘솔을 엽니다.

2.    탐색 창에서 [Roles]를 선택합니다.

3.    역할 생성(Create Role)을 선택합니다.

4.    다른 AWS 계정(Another AWS account)을 선택합니다.

5.    계정 ID에 계정 1의 계정 ID를 입력합니다.

6.    다음: 권한(Next: Permissions)을 선택합니다. 그런 다음 IAM 역할을 생성하는 단계를 완료합니다.

7.    교차 계정 역할 정책 및 KMS 키 정책을 방금 생성한 역할에 연결합니다. 자세한 설명은 IAM 자격 증명 권한 추가 및 제거를 참조하세요.

(계정 1에서) 계정 2에서 교차 계정 역할을 수임할 수 있도록 계정 1의 CodePipeline 서비스 역할에 AssumeRole 권한 추가

1.    계정 1에서 IAM 콘솔을 엽니다.

2.    탐색 창에서 [Roles]를 선택합니다.

3.    CodePipeline에 사용 중인 IAM 서비스 역할을 선택합니다.

4.    인라인 정책 추가를 선택합니다.

5.    JSON 탭을 선택합니다. 그런 다음, 다음 정책을 JSON 편집기에 입력합니다.

중요: ACCOUNT_B_NO계정 2의 계정 번호로 바꿉니다.

{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": "sts:AssumeRole",
    "Resource": [
      "arn:aws:iam::ACCOUNT_B_NO:role/*"
    ]
  }
}

6.    정책 검토(Review policy)를 선택한 후 정책을 생성합니다.

(계정 2에서) 스택에 의해 배포된 서비스에 필요한 권한을 포함하는 CloudFormation 스택에 대한 서비스 역할 생성

참고: 서비스 역할은 계정 2의 CloudFormation 스택에서 직접 구성됩니다. 역할에는 스택에 의해 배포된 서비스에 대한 권한이 포함되어야 합니다.

1.    계정 2에서 IAM 콘솔을 엽니다.

2.    탐색 창에서 [Roles]를 선택합니다.

3.    사용자를 대신해 서비스를 시작할 때 사용할 AWS CloudFormation의 역할을 생성합니다.

4.    사용 사례에 따라 역할에 권한을 적용합니다.

중요: 신뢰 정책이 AWS CloudFormation에 대한 신뢰 정책이고 역할에 스택에서 배포한 서비스에 액세스할 권한이 있는지 확인하세요.

(계정 1에서) 계정 2와 연결된 리소스를 포함하도록 CodePipeline 구성 업데이트

참고: AWS Command Line Interface(AWS CLI) 명령을 실행할 때 오류가 발생할 경우 최신 AWS CLI 버전을 사용하고 있는지 확인하세요.

다른 계정과 연결된 리소스를 사용하는 파이프라인을 생성하거나 편집하기 위해 CodePipeline 콘솔을 사용할 수 없습니다. 하지만 콘솔을 사용하여 파이프라인의 일반 구조를 생성할 수 있습니다. 그런 다음 AWS CLI를 사용하여 파이프라인을 편집하고 다른 계정과 연결된 리소스를 추가할 수 있습니다. 또는 현재 파이프라인을 새 파이프라인의 리소스로 업데이트할 수 있습니다. 자세한 내용은 CodePipeline에서 파이프라인 생성을 참조하세요.

1.    다음 AWS CLI 명령을 실행하여 파이프라인 JSON 구조를 가져옵니다.

aws codepipeline get-pipeline --name MyFirstPipeline >pipeline.json

2.    로컬에 있는 pipeline.json 파일에서 artifactStore 아래의 encryptionKey ID에 AWS KMS 키의 ARN과 함께 ID가 포함되어 있는지 확인합니다.

참고: 파이프라인 구조에 대한 자세한 내용은 AWS CLI 명령 참조의 create-pipeline을 참조하세요.

3.    pipeline.json 파일에서 AWS CloudFormation 작업 구성을 업데이트합니다.

참고: 파이프라인에 대한 작업 구성 JSON 구조 내부의 RoleArn은 CloudFormation 스택에 대한 역할(CFN_STACK_ROLE)입니다. 작업 구성 JSON 구조 외부의 roleArn은 파이프라인이 CloudFormation 스택을 운영하기 위해 맡는 교차 계정 역할(CROSS_ACCOUNT_ROLE)입니다.

4.    역할이 다음 두 가지 모두에 대해 업데이트되었는지 확인합니다.

  • 파이프라인에 대한 작업 구성 JSON 구조 내부의 RoleArn입니다.
  • 파이프라인에 대한 작업 구성 JSON 구조 외부의 roleArn입니다.

참고: 다음 코드 예제에서 RoleArn은 스택을 시작하기 위해 AWS CloudFormation에 전달된 역할입니다. CodePipeline은 roleArn을 사용하여 AWS CloudFormation 스택을 운영합니다.

{
  "name": "Prod_Deploy",
  "actions": [{
    "inputArtifacts": [{
      "name": "MyApp"
    }],
    "name": "test-cfn-x",
    "actionTypeId": {
      "category": "Deploy",
      "owner": "AWS",
      "version": "1",
      "provider": "CloudFormation"
    },
    "outputArtifacts": [],
    "configuration": {
      "ActionMode": "CHANGE_SET_REPLACE",
      "ChangeSetName": "test",
      "RoleArn": "ARN_FOR_CFN_STACK_ROLE",
      "Capabilities": "CAPABILITY_IAM",
      "StackName": "test-cfn-sam",
      "TemplatePath": "MyApp::template.yaml"
    },
    "roleArn": "ARN_FOR_CROSS_ACCOUNT_ROLE",
    "runOrder": 1
  }]
}

5.    pipeline.json 파일에서 메타데이터 구성을 제거합니다. 예를 들면 다음과 같습니다.

"metadata": {
  "pipelineArn": "arn:aws:codepipeline:REGION:ACC:my_test",
  "updated": 1551216777.183,
  "created": 1551207202.964
}

중요: 올바른 JSON 형식에 맞추려면 메타데이터 섹션 앞의 쉼표를 제거합니다.

6.    (선택 사항) 파이프라인을 생성하고 JSON 구조를 업데이트하려면 다음 명령을 실행하여 새 구성 파일로 파이프라인을 업데이트합니다.

aws codepipeline update-pipeline --cli-input-json file://pipeline.json

7.    (선택 사항) 현재 파이프라인을 사용하고 JSON 구조를 업데이트하려면 다음 명령을 실행하여 새로운 파이프라인을 생성합니다.

aws codepipeline create-pipeline --cli-input-json file://pipeline.json

중요: pipeline.json 파일에서 새 파이프라인의 이름을 변경해야 합니다.