[小ネタ]レビュー用URLにビルド結果を組み込む
こんにちは!AWS事業本部コンサルティング部のたかくに(@takakuni_)です。
今回は、CodePipelineの手動承認アクションで使用するレビュー用URLにCodeBuildのビルド結果を組み込んでみようと思います。
先に結論
- ビルド結果は、ビルド変数「CODEBUILD_BUILD_URL」から取得できる。
- ビルド変数の出力には、「名前空間」と「エクスポートされた環境変数」を使用する。
ビルド実行URLの規則性について
初めに、ビルド履歴のURLには規則性があることをご紹介します。
URLは以下のように生成されています。
https://【リージョン】.console.aws.amazon.com/codesuite/codebuild/【アカウントID】/projects/【ビルドプロジェクト名】/build/【ビルドプロジェクト名】%3A【ビルドID】/?region=【リージョン】
「%3A」とは
URLの「【ビルドプロジェクト名】%3A【ビルドID】」で、「%3A」という文字が使われてます。「%3A」は、URLエンコードされた「:(コロン)」に該当します。
つまり、「【ビルドプロジェクト名】%3A【ビルドID】」は、「【ビルドプロジェクト名】:【ビルドID】」となります。
エクスポートされた環境変数とは
CodePipelineではCodeBuildプロジェクトでエクスポートされた環境変数を名前空間を使って各アクション間で受け渡すことができます。
環境変数は、buildspecの「exported-variables」で値をエクスポートできます。
以下は、「exported-variables」を使用して環境変数をエクスポートする一例です。
「BuildID」と「BuildTag」を「exported-variables」で定義して、「post_build」フェーズで変数をエクスポートしていることがわかります。
version: 0.2
env:
exported-variables:
- BuildID
- BuildTag
phases:
install:
runtime-versions:
golang: 1.14
commands:
- "git clone https://github.com/tfutils/tfenv.git ~/.tfenv"
- "ln -s ~/.tfenv/bin/* /usr/local/bin"
- "tfenv install $TF_VERSION"
- "tfenv use $TF_VERSION"
pre_build:
commands:
- "terraform init -input=false -no-color"
build:
commands:
- "terraform plan -input=false -no-color"
post_build:
commands:
- "export BuildID=`echo $CODEBUILD_BUILD_ID | cut -d: -f1`"
- "export BuildTag=`echo $CODEBUILD_BUILD_ID | cut -d: -f2`"
名前空間とは
名前空間とは、CodePipelineの各アクションに名前をつける機能になります。名前空間を使用してアクション間で値を受け渡すことができます。
以下の画面の場合、アクション名は「Terraform_Security_Analysis」ですが、環境変数の受け渡し時は名前空間の「TFSEC」が使用されます。
値の受け渡し方法
CodeBuildプロジェクトの場合、#{名前空間.エクスポートされた環境変数}
で値を受け渡します。
「#{TFSEC.BuildID}」の場合、名前空間「TFSEC」のビルドプロジェクトでエクスポートされた環境変数「BuildID」を取り出します。
CodeBuildプロジェクト以外にも、アクションタイプごとにさまざまな値を取り出すことができます。かなり便利な機能なためぜひパイプランを組む際はオススメです。
やってみた
今回は、CodeBuildのビルド結果を手動承認アクションのレビューURLに組み込もうと思います。
CodeBuildで使用されている「CODEBUILD_BUILD_URL」を「BUILD_URL」としてエクスポートして、手動承認アクションで名前解決を行います。
CodeBuildプロジェクトの情報は以下の通りです。
- アクション名:Terraform_Security_Analysis
- アクションプロバイダー:AWS CodeBuild
- リージョン:アジアパシフィック
- 入力アーティファクト:Artifact_Source_CodeCommit_Source
- プロジェクト名:developers-io-2022-tf-build-tfsec-project
- 環境変数:設定なし
- 変数の名前空間:TFSEC
buildspecで変数のエクスポート
さきほど紹介した「exported-variables」を使用する方法で、変数をエクスポートします。
buildspecは以下の通りです。
version: 0.2
env:
exported-variables:
- BUILD_URL
phases:
pre_build:
commands:
- "echo Executing tfsec"
- "mkdir -p reports/tfsec/"
build:
commands:
- "tfsec -s --no-color --config-file exclude.yml ."
- "tfsec -s --no-color --config-file exclude.yml . --format junit > reports/tfsec/report.xml"
post_build:
commands:
- "export BUILD_URL=`echo $CODEBUILD_BUILD_URL`"
reports:
reports:
files:
- "reports/tfsec/report.xml"
file-format: JUNITXML
ビルド履歴から変数がエクスポートできていることがわかります。
名前解決
「#{TFSEC.BUILD_URL}」で名前解決を行います。
レビュー画面からエクスポートされた環境変数が解決できていることがわかります。
もちろん、URLを踏むとCodeBuildの実行履歴に遷移します。
方法は1つだけではない
先日、公開した「TerraformのCI/CDパイプラインを実装してみた」では、「【ビルドプロジェクト名】%3A【ビルドID】」の部分をcut
コマンドで抽出してURLを生成していました。
具体的には以下のコマンドです。
CodeBuildで使用されている環境変数「CODEBUILD_BUILD_ID」からビルドプロジェクト名とビルドIDを抽出し、新しい環境変数にエクスポートしています。
export BuildID=`echo $CODEBUILD_BUILD_ID | cut -d: -f1`
export BuildTag=`echo $CODEBUILD_BUILD_ID | cut -d: -f2`
コードが少し長いですが、エクスポートした環境変数、名前空間を使用してURLを生成しています。
CodePipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
Name: !Sub "${PrjPrefix}-tf-pipeline"
ArtifactStore:
EncryptionKey:
Id: !GetAtt KeyS3Arthifact.Arn
Type: "KMS"
Location: !Ref BucketArtifacts
Type: "S3"
RoleArn: !GetAtt RoleTfPipelne.Arn
Stages:
- Name: "Source"
Actions:
- Name: "CodeCommit_Source"
ActionTypeId:
Category: "Source"
Owner: "AWS"
Provider: "CodeCommit"
Version: "1"
Configuration:
RepositoryName: !GetAtt CodeCommit.Name
BranchName: !Ref BranchName
PollForSourceChanges: false
OutputArtifacts:
- Name: "Artifact_Source_CodeCommit_Source"
RoleArn: !GetAtt RoleTfPipelne.Arn
RunOrder: 1
- Name: "tfsec_Stage"
Actions:
- Name: "Terraform_Security_Analysis"
Namespace: TFSEC
ActionTypeId:
Category: "Build"
Owner: "AWS"
Provider: "CodeBuild"
Version: "1"
Configuration:
ProjectName: !Ref ProjectTfsec
InputArtifacts:
- Name: "Artifact_Source_CodeCommit_Source"
RoleArn: !GetAtt RoleTfPipelne.Arn
RunOrder: 1
- Name: "Terraform_Stages"
Actions:
- Name: "Terraform_Security_Analysis_Manual_Review"
ActionTypeId:
Category: "Approval"
Owner: "AWS"
Provider: "Manual"
Version: "1"
Configuration:
CustomData: "tfsec review"
ExternalEntityLink: !Sub "https://${AWS::Region}.console.aws.amazon.com/codesuite/codebuild/${AWS::AccountId}/projects/#{TFSEC.BuildID}/build/#{TFSEC.BuildID}%3A#{TFSEC.BuildTag}/?region=${AWS::Region}"
RoleArn: !GetAtt RoleTfPipelne.Arn
RunOrder: 1
- Name: "Terraform_Plan"
Namespace: "TERRAFORM"
ActionTypeId:
Category: "Build"
Owner: "AWS"
Provider: "CodeBuild"
Version: "1"
Configuration:
ProjectName: !Ref ProjectTfplan
InputArtifacts:
- Name: "Artifact_Source_CodeCommit_Source"
RoleArn: !GetAtt RoleTfPipelne.Arn
RunOrder: 2
- Name: "Terraform_Plan_Manual_Review"
ActionTypeId:
Category: "Approval"
Owner: "AWS"
Provider: "Manual"
Version: "1"
Configuration:
CustomData: "Terraform plan review"
ExternalEntityLink: !Sub "https://${AWS::Region}.console.aws.amazon.com/codesuite/codebuild/${AWS::AccountId}/projects/#{TERRAFORM.BuildID}/build/#{TERRAFORM.BuildID}%3A#{TERRAFORM.BuildTag}/?region=${AWS::Region}"
RoleArn: !GetAtt RoleTfPipelne.Arn
RunOrder: 3
- Name: "Terraform_Apply"
ActionTypeId:
Category: "Build"
Owner: "AWS"
Provider: "CodeBuild"
Version: "1"
Configuration:
ProjectName: !Ref ProjectTfapply
InputArtifacts:
- Name: "Artifact_Source_CodeCommit_Source"
RoleArn: !GetAtt RoleTfPipelne.Arn
RunOrder: 4
終わりに
以上、「レビュー用URLにビルド結果を組み込む」でした。
CodeBuildプロジェクトではさまざまな環境変数が使用されているため、ぜひ一度プロジェクトで使用しているDockerイメージをprintenvしてみてはいかがでしょうか。
この記事がどなたかの参考になれば幸いです。
以上、AWS事業本部コンサルティング部のたかくに(@takakuni_)でした!