パブリックプレビューのAWS SAM パイプライン機能を試してみた

2021.07.24

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

いわさです。

AWSサーバーレスアプリケーションモデル(通称:SAM)は、CloudFormationを拡張し、サーバーレスアプリケーションに特化したSAM構文でテンプレートを作成することが出来る機能です。
SAMを使った開発を行う際に、ローカル実行やパッケージの作成にAWS SAM CLIを使用することが出来ます。

先日、そのAWS SAM CLIにパイプラインを構築するための"AWS SAMパイプライン"という機能がパブリックプレビューとして追加されたので、CodePipeline環境にて試してみました。

SAMの初期化

まずはSAMのアプリケーション作成を行います。
アプリケーション作成にはsam initを使用します。
今回はNode.jsで作成してみます。

iwasa.takahito@HOGE src % sam init                                       
Which template source would you like to use?
    1 - AWS Quick Start Templates
    2 - Custom Template Location
Choice: 1
What package type would you like to use?
    1 - Zip (artifact is a zip uploaded to S3)    
    2 - Image (artifact is an image uploaded to an ECR image repository)
Package type: 1

Which runtime would you like to use?
    1 - nodejs14.x
    2 - python3.8
    3 - ruby2.7
    4 - go1.x
    5 - java11
    6 - dotnetcore3.1
    7 - nodejs12.x
    8 - nodejs10.x
    9 - python3.7
    10 - python3.6
    11 - python2.7
    12 - ruby2.5
    13 - java8.al2
    14 - java8
    15 - dotnetcore2.1
Runtime: 1

Project name [sam-app]: 

Cloning from https://github.com/aws/aws-sam-cli-app-templates

AWS quick start application templates:
    1 - Hello World Example
    2 - Step Functions Sample App (Stock Trader)
    3 - Quick Start: From Scratch
    4 - Quick Start: Scheduled Events
    5 - Quick Start: S3
    6 - Quick Start: SNS
    7 - Quick Start: SQS
    8 - Quick Start: Web Backend
Template selection: 1

    -----------------------
    Generating application:
    -----------------------
    Name: sam-app
    Runtime: nodejs14.x
    Dependency Manager: npm
    Application Template: hello-world
    Output Directory: .

    Next steps can be found in the README file at ./sam-app/README.md

iwasa.takahito@HOGE src %

カレントディレクトリにSAMテンプレートおよび、各言語のコードが生成されます。

CodeCommitリポジトリの作成

SAMパイプラインを実行する前にコードリポジトリを作成しておきましょう。
Bitbucket、CodeCommit、GitHub、GitHub Enterprise Serverが選択出来ます。
今回はCodeCommitを使ってみます。

リモートリポジトリを作成したら、先程初期化したSAMテンプレート一式をプッシュしておきましょう。

git init
git add .
git commit -m "first commit"
git branch -M main
git remote add origin https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/sam-app
git push -u origin main

リモートブランチへ反映されました。

パイプラインブートストラップ実行&テンプレート作成

SAMパイプラインの実行でやるとは、まずアプリケーションディレクトリで以下のコマンドを実行します。

sam pipeline init --bootstrap

その後、対話形式でパイプラインの内容を設定していきます。
設定は2つのデプロイステージを作成しますので似た内容を2度打ちます。
MFAを有効化している場合、途中で頻繁にワンタイムパスワードを要求されます。
また、AWS CLIの作成済みプロファイルに対応していますのでスイッチロール環境でも利用可能です。

利用できるCI/CD基盤は、Jenkins、GitLab、GitHub Actions、AWS CodePipelineです。
今回はCodePipelineで進めてみます。

長いのでコマンド実行結果は対話する部分だけ記します。

iwasa.takahito@HOGE sam-app % sam pipeline init --bootstrap

Select template
    1 - AWS Quick Start Pipeline Templates
    2 - Custom Pipeline Template Location
Choice: 1

CI/CD system
    1 - Jenkins
    2 - GitLab CI/CD
    3 - GitHub Actions
    4 - AWS CodePipeline
Choice: 4

Do you want to go through stage setup process now? If you choose no, you can still reference other bootstrapped resources. [y/N]: y

Stage 1 Setup

[1] Stage definition
Stage name: stage1

[2] Account details
Select a credential source to associate with this stage: 3
Enter MFA code for arn:aws:iam::123456789012:mfa/cm-iwasa.takahito: 
Enter the region in which you want these resources to be created [ap-northeast-1]: 
Enter the pipeline IAM user ARN if you have previously created one, or we will create one for you []: 

[3] Reference application build resources
Enter the pipeline execution role ARN if you have previously created one, or we will create one for you []: 
Enter the CloudFormation execution role ARN if you have previously created one, or we will create one for you []: 
Please enter the artifact bucket ARN for your Lambda function. If you do not have a bucket, we will create one for you []: 
Does your application contain any IMAGE type Lambda functions? [y/N]: n

[4] Summary
Enter MFA code for arn:aws:iam::123456789012:mfa/cm-iwasa.takahito: 

Should we proceed with the creation? [y/N]: y
Enter MFA code for arn:aws:iam::123456789012:mfa/cm-iwasa.takahito: 
    Successfully created!
Enter MFA code for arn:aws:iam::123456789012:mfa/cm-iwasa.takahito: 

Do you want to go through stage setup process now? If you choose no, you can still reference other bootstrapped resources. [y/N]: y

Stage 2 Setup

[1] Stage definition
Stage name: stage2

[2] Account details
Select a credential source to associate with this stage: 3
Enter MFA code for arn:aws:iam::123456789012:mfa/cm-iwasa.takahito: 
Enter the region in which you want these resources to be created [ap-northeast-1]: 
Pipeline IAM user ARN: arn:aws:iam::210987654321:user/aws-sam-cli-managed-stage1-pipeline-r-PipelineUser-1ARZVKSDT288W

[3] Reference application build resources
Enter the pipeline execution role ARN if you have previously created one, or we will create one for you []: 
Enter the CloudFormation execution role ARN if you have previously created one, or we will create one for you []: 
Please enter the artifact bucket ARN for your Lambda function. If you do not have a bucket, we will create one for you []: 
Does your application contain any IMAGE type Lambda functions? [y/N]: N

[4] Summary
Enter MFA code for arn:aws:iam::123456789012:mfa/cm-iwasa.takahito: 
Should we proceed with the creation? [y/N]: y
Enter MFA code for arn:aws:iam::123456789012:mfa/cm-iwasa.takahito: 
    Successfully created!

What is the Git provider?
    1 - Bitbucket
    2 - CodeCommit
    3 - GitHub
    4 - GitHubEnterpriseServer
Choice []: 2
What is the CodeCommit repository name?: sam-app
What is the Git branch used for production deployments? [main]: 
What is the template file path? [template.yaml]: 

Select an index or enter the stage name: 1
What is the sam application stack name for stage 1? [sam-app]: 

Select an index or enter the stage name: 2
What is the sam application stack name for stage 2? [sam-app]:

パイプライン構築用のテンプレートやBuildSpecファイルなどが作られてるのでリモートブランチへプッシュしましょう。
ブートストラップコマンドでこれだけのファイルが自動生成されたことがわかります。

iwasa.takahito@HOGE sam-app % git add .
iwasa.takahito@HOGE sam-app % git commit -m "add pipeline."
[main dbb32c5] add pipeline.
 8 files changed, 819 insertions(+)
 create mode 100644 .aws-sam/pipeline/pipelineconfig.toml
 create mode 100755 assume-role.sh
 create mode 100644 codepipeline.yaml
 create mode 100644 pipeline/buildspec_build_package.yml
 create mode 100644 pipeline/buildspec_deploy.yml
 create mode 100644 pipeline/buildspec_feature.yml
 create mode 100644 pipeline/buildspec_integration_test.yml
 create mode 100644 pipeline/buildspec_unit_test.yml
iwasa.takahito@HOGE sam-app % git push
Enumerating objects: 14, done.
Counting objects: 100% (14/14), done.
Delta compression using up to 8 threads
Compressing objects: 100% (11/11), done.
Writing objects: 100% (13/13), 7.00 KiB | 2.33 MiB/s, done.
Total 13 (delta 2), reused 0 (delta 0), pack-reused 0
To https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/sam-app
   93b0d6e..dbb32c5  main -> main
iwasa.takahito@HOGE sam-app %

テンプレート実行&自動デプロイ

CloudFormationから、先程生成されたcodepipeline.yamlをアップロードします。
パラメータは追加で入力しなくても大丈夫です。

CloudFormationスタックが作成されたら、CodePipelineからパイプラインを確認してみます。

実行中のパイプラインがあります。
これが今デプロイしたパイプラインです。

Node.jsであれば無事デプロイまで完了すると思います。
ちなみに.NET Core 3.1で試したところ、途中のステージでエラーになりました。
解決策を調べて評価したので別途記事にします。

パイプラインの実行が完了したら DeployProdステージの詳細ログを確認しましょう。
最後のほうにエンドポイント情報が出力されていますので、ブラウザでアクセスしてみましょう。

初期構築したサーバーレスアプリケーションからの結果を受け取ることが出来ました。

コード変更と動作確認

パイプラインを組んだので、コード変更してみましょう。
リモートプッシュするだけでデプロイされます。

hello-worldのapp.jsにLambda関数のコードが含まれていますので、レスポンスに該当するmessageプロパティ値を変更しましょう。

変更したらリモートブランチへプッシュしましょう。

パイプラインが実行され、変更内容が反映されました。
反映時間はおおよそ5分程度でした。

まとめ

  • SAMパイプラインを使うと、パイプライン構築に必要なCloudFormationテンプレートが対話形式で作成可能。テンプレートから自分でCloudFormationスタックの作成は必要。
  • SAMパイプライン実行前にリポジトリは用意しておく必要がある
  • MFAのワンタイムパスワードは頻繁に問われる。リフレッシュ前に再利用してしまい無効なトークンとしてエラー中断されやすいので注意
  • 利用できるコードリポジトリはBitbucket、CodeCommit、GitHub、GitHub Enterprise Server
  • 利用できるCI/CD基盤は、Jenkins、GitLab、GitHub Actions、AWS CodePipeline

参考