CodePipeline を使用して、別のアカウントの Amazon S3 にアーティファクトをデプロイする方法を教えてください。
最終更新日: 2020 年 10 月 20 日
S3 デプロイアクションプロバイダーで AWS CodePipeline を使用して、別のアカウントの Amazon Simple Storage Service (Amazon S3) にアーティファクトをデプロイしたいと考えています。また、アーティファクトの所有者をターゲットアカウントとして設定する必要があります。
簡単な説明
次の解決方法は、以下を前提とするシナリオの例に基づいています。
- 開発用 (dev) アカウントと本稼働 (prod) アカウントの 2 つのアカウントがあります。
- 開発アカウントの入力バケットは codepipeline-input-bucket (バージョニングが有効になっている) と呼ばれます。
- 開発アカウントのデフォルトのアーティファクトバケットは、codepipeline-us-east-1-0123456789 と呼ばれます。
- 本稼働アカウントの出力バケットは codepipeline-output-bucket と呼ばれます。
- 開発アカウントから本稼働アカウントの S3 バケットにアーティファクトをデプロイしています。
- 本稼働アカウントで作成されたクロスアカウントロールを引き受け、アーティファクトをデプロイします。ロールは、アーティファクトのオブジェクト所有者を開発アカウントではなく、ターゲットの本稼働アカウントとして設定します。
解決方法
開発アカウントの CodePipeline で使用する AWS Key Management Service (AWS KMS) キーを作成する
1. 開発アカウントで AWS KMS コンソールを開きます。
2. ナビゲーションペインから [Customer managed keys] をクリックします。
3. [キーの作成] を選択します。
4. [キータイプ] で、[対称キー] を選択します。
5. [詳細オプション] を展開します。
6. [キーマテリアルのオリジン] で、[KMS] を選択してから、[次へ] を選択します。
7. [エイリアス] には、 [s3deploykey] と入力します。
注意: s3deploykey をキーのエイリアスに置き換えます。
8. [次へ] を選択します。
9. [キー管理権限の定義] ページの [キー管理者] セクションで、キー管理者として AWS Identity and Access Management (IAM) ユーザーまたはロールを選択し、[次へ] を選択します。
10. [キー使用権限の定義] ページの [他の AWS アカウント] セクションで、[別の AWS アカウントを追加] を選択します。
11. 表示されるテキストボックスで、本稼働アカウントのアカウント ID を追加し、[次へ] を選択します。
注意: [このアカウント] セクションで既存のサービスロールを選択してから、[開発アカウントの KMS 使用ポリシーの更新] セクションの手順をスキップすることもできます。
12. キーポリシーを確認し、[完了] を選択します。
重要: クロスアカウントデプロイには KMS カスタマーマネージドキーを使用する必要があります。キーが設定されていない場合、CodePipeline はデフォルトの暗号化を使用してオブジェクトを暗号化します。この暗号化は、ターゲットアカウントのロールでは復号できません。
開発アカウントで CodePipeline を作成する
1. CodePipeline コンソールを開き、[パイプラインの作成] を選択します。
2. [パイプライン名] に [crossaccountdeploy] と入力します。
注意: crossaccountdeploy をパイプラインの名前に置き換えます。
[ロール名] テキストボックスには、サービスロール名 AWSCodePipelineServiceRole-us-east-1-crossaccountdeploy が自動的に入力されます。KMS キーにアクセスできる既存のサービスロールを選択することもできます。
3. [詳細設定] セクションを展開します。
4. [アーティファクトストア] の場合は、[デフォルトの場所] を選択します。
注意: シナリオで必要な場合は、カスタムの場所を選択できます。
5. [暗号化キー] で、[カスタマーマネージドキー] を選択します。
6. [KMS カスタマーマスターキー] の一覧から [s3deploykey] を選択し、[次へ] を選択します。
重要: s3deploykey をキーのエイリアスに置き換えます。
7. [ソースステージの追加] ページの [ソースプロバイダー] で、[Amazon S3] を選択します。
8. [バケット] に、[codepipeline-input-bucket] と入力します。
注意: codepipeline-input-bucket を、入力バケットの名前に置き換えます。
重要: CodePipeline を使用するには、入力バケットでバージョニングが有効になっている必要があります。
9. [S3 オブジェクトキー] に、[sample-website.zip] と入力します。
重要: 独自のウェブサイトの代わりにサンプルの AWS ウェブサイトを使用するには、チュートリアル: デプロイプロバイダーとして Amazon S3 を使用するパイプラインを作成するを参照してください。次に、[1: 静的ウェブサイトファイルを Amazon S3 にデプロイする] セクションの [前提条件] で、「静的ウェブサイトのサンプル」を検索します。
10. [変更検出オプション] で、[Amazon CloudWatch Events (推奨)] を選択し、[次へ] を選択します。
11. [ビルドステージの追加] ページで、[ビルドステージをスキップ]、[スキップ] を選択します。
12. [デプロイステージの追加] ページの [デプロイプロバイダー] で、[Amazon S3] を選択します。
13. [リージョン] で、[米国東部 (バージニア北部)] を選択します。
重要: 米国東部 (バージニア北部) を出力バケットの AWS リージョンに置き換えます。
14. [バケット] に、本稼働バケットの名前 [codepipeline-output-bucket] を入力します。
注意: codepipeline-output-bucket を、本稼働アカウントの出力バケットの名前に置き換えます。
15. [デプロイする前にファイルを抽出する] チェックボックスをオンにします。
注意: 必要に応じて、[デプロイパス] にパスを入力します。
16. [次へ] を選択します。
17. [パイプラインを作成] をクリックします。
これで、パイプラインはトリガーされますが、ソースステージは失敗します。次のエラーが表示されます。
The object with key 'sample-website.zip' does not exist.
[サンプルウェブサイトを入力バケットにアップロードする] セクションには、後からこのエラーを解決する方法が示されています。
開発アカウントの KMS 使用ポリシーを更新する
重要: 既存の CodePipeline サービスロールを使用していて、開発アカウントセクションの CodePipeline で使用する AWS Key Management Service (AWS KMS) キーの作成で、そのロールをキーユーザーとしてすでに追加している場合 は、このセクションをスキップしてください。
1. 開発アカウントで AWS KMS コンソールを開き、s3deploykey を選択します。
重要: s3deploykey をキーのエイリアスに置き換えます。
2. [キーユーザー] セクションで、[追加] を選択します。
3. 検索ボックスに、サービスロール [AWSCodePipelineServiceRole-us-east-1-crossaccountdeploy] を入力し、 [追加] を選択します。
本稼働アカウントでクロスアカウントロールを設定する
ポリシー作成方法:
1. 本稼働アカウントで IAM コンソールを開きます。
2. ナビゲーションペインで、[ポリシー] をクリックしてから [ポリシーの作成] をクリックします。
3. [JSON] タブを選択して、JSON エディタで以下のポリシーを入力します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::codepipeline-output-bucket/*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::codepipeline-output-bucket"
]
}
]
}
注意: codepipeline-output-bucket を、本稼働アカウントの出力バケットの名前に置き換えます。
4. [ポリシーの確認] を選択します。
5. [名前] に、[outputbucketfullaccess] と入力します。
6. [ポリシーの作成] を選択します。
7. 別のポリシーを作成するには、[ポリシーの作成] を選択します。
8. [JSON] タブを選択して、JSON エディタで以下のポリシーを入力します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kms:DescribeKey",
"kms:GenerateDataKey*",
"kms:Encrypt",
"kms:ReEncrypt*",
"kms:Decrypt"
],
"Resource": [
"arn:aws:kms:us-east-1:<dev-account-id>:key/<key id>"
]
},
{
"Effect": "Allow",
"Action": [
"s3:Get*"
],
"Resource": [
"arn:aws:s3:::codepipeline-us-east-1-0123456789/*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::codepipeline-us-east-1-0123456789"
]
}
]
}
注意: 作成した KMS キーの ARN を置き換えます。codepipeline-us-east-1-0123456789 を、開発アカウントのアーティファクトバケットの名前に置き換えます。
9. [ポリシーの確認] をクリックします。
10. [名前] に、[devkmss3access] と入力します。
11. [ポリシーの作成] を選択します。
ロールの作成方法:
1. 本稼働アカウントで IAM コンソールを開きます。
2. ナビゲーションペインで、[ロール]、[ロールの作成] を順に選択します。
3. [別の AWS アカウント] を選択します。
4. [アカウント ID] に、開発アカウント ID を入力します。
5. [次のステップ: アクセス許可] を選択します。
6. ポリシー一覧から、[outputbucketfullaccess] および [devkmss3access] を選択します。
7. [Next: Tags] を選択します。
8. (オプション) タグを追加し、続いて [次: レビュー] を選択します。
9. [ロール名] に [prods3role] と入力します。
10. [ロールの作成] を選択します。
11. ロール一覧から、prods3role を選択します。
12. [信頼関係] タブを選択し、[信頼関係を編集] を選択します。
13. [ポリシードキュメント] エディタで、次のポリシーを入力します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::<dev-account-id>:role/service-role/AWSCodePipelineServiceRole-us-east-1-crossaccountdeploy"
]
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
注意: dev-account-id を、開発環境のアカウント ID およびパイプラインのサービスロールに置き換えます。
14. [信頼ポリシーの更新] を選択します。
開発アカウントで CodePipeline アーティファクトバケットとサービスロールを設定する
1. 開発アカウントで Amazon S3 コンソールを開きます。
2. [バケット名] リストで、[codepipeline-us-east-1-0123456789] を選択します。
注意: codepipeline-us-east-1-0123456789 をアーティファクトバケットの名前に置き換えます。
3. [Permissions] を選択してから、[Bucket Policy] を選択します。
4. テキストエディタで、以下のステートメントで既存のポリシーを更新します。
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<prod-account-id>:root"
},
"Action": [
"s3:Get*",
"s3:Put*"
],
"Resource": "arn:aws:s3:::codepipeline-us-east-1-0123456789/*"
},
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<prod-account-id>:root"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::codepipeline-us-east-1-0123456789"
}
重要: 適切な JSON 形式に合わせるには、既存のステートメントの後にカンマを追加します。
注意: prod-account-id を本稼働環境のアカウント ID に置き換えます。codepipeline-us-east-1-0123456789 をアーティファクトバケット名に置き換えます。
5. [保存] を選択します。
6. 開発アカウントで IAM コンソールを開きます。
7. ナビゲーションペインで、[ポリシー] をクリックしてから [ポリシーの作成] をクリックします。
8. [JSON] タブを選択して、JSON エディタで以下のポリシーを入力します。
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": [
"arn:aws:iam::<prod-account-id>:role/prods3role"
]
}
}
注意: prod-account-id を本稼働環境のアカウント ID に置き換えます。
9. [ポリシーの確認] をクリックします。
10. [名前] に、[assumeprods3role] と入力します。
11. [ポリシーの作成] を選択します。
12. ナビゲーションペインで [ロール] を選択し、次に [AWSCodePipelineServiceRole-us-east-1-crossaccountdeploy] を選択します。
注意: 該当する場合、AWSCodePipelineServiceRole-us-east-1-crossaccountdeploy をサービスロールに置き換えます。
13. [ポリシーを添付] を選択してから、[assumeprods3role] を選択します。
14. [ポリシーを添付] を選択します。
開発アカウントでクロスアカウントロールを使用するように CodePipeline を更新する
1. パイプライン定義を codepipeline.json というファイルで取得するには、次のコマンドを実行します。
aws codepipeline get-pipeline --name crossaccountdeploy > codepipeline.json
注意: crossaccountdeploy をパイプラインの名前に置き換えます。
2. roleArn を含めるように codepipeline.json のデプロイセクションを更新します。例:
"roleArn": "arn:aws:iam::your-prod-account id:role/prods3role",
roleArn を追加するには、以下の更新を行います。
{
"name": "Deploy",
"actions": [
{
"name": "Deploy",
"actionTypeId": {
"category": "Deploy",
"owner": "AWS",
"provider": "S3",
"version": "1"
},
"runOrder": 1,
"configuration": {
"BucketName": "codepipeline-output-bucket",
"Extract": "true"
},
"outputArtifacts": [],
"inputArtifacts": [
{
"name": "SourceArtifact"
}
],
"roleArn": "arn:aws:iam::<prod-account-id>:role/prods3role",
"region": "us-east-1",
"namespace": "DeployVariables"
}
]
}
注意: prod-account-id を本稼働環境のアカウント ID に置き換えます。
3. codepipeline.json ファイルの末尾にあるメタデータセクションを削除します。例:
"metadata": {
"pipelineArn": "arn:aws:codepipeline:us-east-1:<dev-account-id>:crossaccountdeploy",
"created": 1587527378.629,
"updated": 1587534327.983
}
重要: 適切な JSON 形式に合わせるには、メタデータセクションの前のコンマを削除します。
4. パイプラインを更新するには、次のコマンドを実行します。
aws codepipeline update-pipeline --cli-input-json file://codepipeline.json
サンプルウェブサイトを入力バケットにアップロードする
1. 開発アカウントで Amazon S3 コンソールを開きます。
2. [バケット名] 一覧で、codepipeline-input-bucket を選択します。
注意: codepipeline-input-bucket を、入力バケットの名前に置き換えます。
3. [アップロード] を選択し、[ファイルの追加] を選択します。
4. 前にダウンロードした sample-website.zip ファイルを選択します。
5. [アップロード] をクリックします。
これで、CodePipeline がトリガーされ、以下の状況が発生します。
1. ソースアクションは、codepipeline-input-bucket から sample-website.zip を選択します。次に、ソースアクションは、Web サイトをソースアーティファクトとして codepipeline-us-east-1-0123456789 アーティファクトバケットに配置します。
2. デプロイアクションでは、CodePipeline サービスロール AWSCodePipelineServiceRole-us-east-1-crossaccountdeploy は本稼働アカウントの prods3role を引き受けます。
3. CodePipeline は、開発アカウントの KMS キーとアーティファクトバケットに対する prods3role アクセスを使用して、アーティファクトを取得します。次に、CodePipeline は抽出されたファイルを本稼働アカウントの codepipeline-output-bucket にデプロイします。
codepipeline-output-bucket で抽出されたオブジェクトには、所有者として本稼働アカウントがあります。</p