はじめに
こんにちは、アプリケーションチームの野地です。
今回は、業務内でAWS CodePipeline V2に触れる機会があったので、CodePipeline V2を使用する際の管理コンソールでの使い方から、開発時に悩んだ「CloudFormationで実装する際のyamlでの記述方法」も合わせて紹介したいと思います。
CodePipeline V2とは
2023年の10月ごろにリリースされたCodePipelineタイプです。
V2で作成したCodePipelineをコンソールからリリースする場合、ユーザーが宣言した環境変数を使用することで、入力パラメータの値を動的に渡すことができます。
今回は以下のような構成で、CodePipeline V2を使用して任意のファイルをS3へアップロードするパイプラインを作成したいと思います。
使い方
管理コンソールでの設定
基本的には通常通りに管理コンソールからパイプラインを作成し、設定をしていきます。
パイプラインの設定を選択する
以前はこのようにV1、V2を選択しましたが、注意書きにもあるように、現在は管理コンソールからはパイプラインV1の作成ができなくなっています。
下にスクロールすると、「変数」の設定が出てきます。ここで変数を設定することで、パイプラインのリリース時に入力パラメータの値を割り当てることができます。
ソースステージを設定する
ソースプロバイダー設定では、リポジトリやブランチ名を指定します。
※今回使用している環境は、パイプライン実行のアカウントとソースリポジトリのアカウントが違うため、管理コンソールからプルダウンで指定することができません。その場合は、yamlテンプレートなどを使用したCloudFormationからの作成によって指定が可能です
ビルドステージを追加する
BuildフェーズでPipelineリリース時に入力したパラメータを受け取るには、「環境変数-オプショナル」の項目で次のように値を入力します。(例として、環境変数名FILENAMEを用いる)
- 環境変数名:FILENAME、変数値:#{variables.FILENAME}
「環境変数-オプショナル」の設定をCloudFormation用にyamlで記述する際に、書き方が見つからずに苦労しましたので、テンプレート例を載せておきます。
yamlの場合は、BuildアクションのConfiguration
セクションにEnvironmentVariables
としてname
・value
・type
を記述することで反映させることができます。
CloudFormation用のyamlテンプレートでの記述方法
AWSTemplateFormatVersion: '2010-09-09' Parameters: EnvName: Type: String Mappings: EnvMap: develop: BranchName: 'develop_V2' EncryptionKey: 'arn:aws:kms:ap-northeast-1:xxxxxx:key/xxxxxx' Resources: FileUpdatePipeline: Type: AWS::CodePipeline::Pipeline Properties: PipelineType: V2 Variables: - Name: 'FILENAME' DefaultValue: 'DEFAULT' Description: '更新したいファイル名を入力してください。例:sqs.yamlを更新したい場合→sqsと入力' Name: !Sub 'file-update-${EnvName}' ArtifactStore: Type: S3 Location: !Sub 'artifacts-${EnvName}' EncryptionKey: Id: !FindInMap [EnvMap, !Ref EnvName, EncryptionKey] Type: KMS RoleArn: !Sub arn:aws:iam::${AWS::AccountId}:role_name Stages: - Name: Source Actions: - Name: Source ActionTypeId: Category: Source Owner: AWS Provider: CodeCommit Version: 1 RunOrder: 1 Configuration: PollForSourceChanges: false RepositoryName: 'repository_name' BranchName: !FindInMap [EnvMap, !Ref EnvName, BranchName] InputArtifacts: [] OutputArtifacts: - Name: SourceArtifact RoleArn: arn:aws:iam::${SourceAccountID}:role_name - Name: Deploy Actions: - Name: Approval ActionTypeId: Category: Approval Owner: AWS Provider: Manual Version: 1 RunOrder: 1 - Name: Build ActionTypeId: Category: Build Owner: AWS Provider: CodeBuild Version: 1 RunOrder: 2 Configuration: ProjectName: !Ref 'FileUpdateCodeBuild' EnvironmentVariables: !Join - '' - - '[' - '{"name":"FILENAME", "value":"#{variables.FILENAME}", "type":"PLAINTEXT" - '"}]' InputArtifacts: - Name: SourceArtifact OutputArtifacts: - Name: BuildArtifact FileUpdateCodeBuild: Type: AWS::CodeBuild::Project Properties: Name: !Sub 'file-update-${EnvName}' BadgeEnabled: false ServiceRole: !Sub arn:aws:iam::${AWS::AccountId}:role_name TimeoutInMinutes: 60 Artifacts: Type: CODEPIPELINE EncryptionKey: !FindInMap [EnvMap, !Ref EnvName, EncryptionKey] Source: Type: CODEPIPELINE BuildSpec: 'buildspec.yaml' Environment: Image: 'aws/codebuild/standard:7.0' Type: LINUX_CONTAINER ComputeType: BUILD_GENERAL1_MEDIUM PrivilegedMode: true EnvironmentVariables: - Name: ENV_NAME Value: !Ref 'EnvName' Type: PLAINTEXT
実際に使ってみる
今回の実装内容
冒頭でも説明しましたが、今回は「受け取った入力パラメータを使って、S3の任意のyamlテンプレートを変数で指定して更新する」ような、BuildフェーズをもつPipelineを作成したいと思います。
Buildフェーズで使用するbuildspec.yamlを次のように記述します。
- buildspec.yamlの記述例
version: 0.2 phases: install: commands: - printf "Installing dependencies..." - pip install awscli jsonschema PyYAML pre_build: commands: - find $FILENAME.yaml - EXISTS_STATUS=$? - | if [ $EXISTS_STATUS -eq 0 ]; then printf "go to build phase" fi build: commands: - | if [ $EXISTS_STATUS -eq 0 ]; then printf "Uploading $FILENAME to S3..." aws s3 cp $FILENAME.yaml s3:/Sample/$FILENAME.yaml else printf "Skip build phase due to file not exists" fi
実行するコマンド内で、$FILENAME
という記述を用いることで入力パラメータを受け取り、任意のファイルを指定できます。
(念の為、指定したファイルが存在するかどうかのチェックも行っています。)
変更のリリース
パイプラインの変更リリース時に、環境変数に入れたい値の入力を求められます。
今回は、S3に保存してある任意のyamlテンプレートを更新したいので、入力パラメータにそのファイル名を入力します。
おわりに
今回紹介したファイルのアップロード作業は、業務内で一部手動で実施していました。
ですが、今回紹介したCodePipeline V2を使用した実装をすることで、コマンド実行時のオペミス回避に寄与できました。
今回はファイルのアップロードをしましたが、そのほかにも、スタックのアップデートをしたければ、同様にコマンド内でテンプレートを指定してあげれば良いので、使い道が色々ありそうです。
実装時にyamlでの記述方法について述べている記事がなかったので、同じ課題を持つ人の助けになれば幸いです。