🦥
sam pipelineで生成したpipeline.yamlを使用して、GitHub ActionsでCI/CDをやってみた
の続きです
構成
下記のCI/CDを実装します
featureブランチをpushしたタイミング
- テスト実施
- dev環境にdeploy
featureブランチをmasterにマージしたタイミング
- テスト実施
- prod環境にdeploy
- featureブランチ削除
構成
_________ _________
| feature | | master |
| dev | | prod |
| Stage 1 |->| Stage 2 |
|_________| |_________|
dev環境を作成する
最初にprodを作ると順序が逆になり、失敗しました
~/environment/sam-app $ sam pipeline bootstrap
sam pipeline bootstrap generates the required AWS infrastructure resources to connect
to your CI/CD system. This step must be run for each deployment stage in your pipeline,
prior to running the sam pipeline init command.
We will ask for [1] stage definition, [2] account details, and
[3] references to existing resources in order to bootstrap these pipeline resources.
[1] Stage definition
Enter a name for this stage. This will be referenced later when you use the sam pipeline init command:
Stage name: dev
[2] Account details
The following AWS credential sources are available to use:
To know more about configuration AWS credentials, visit the link below:
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html
1 - Environment variables (not available)
2 - default (named profile)
q - Quit and configure AWS credentials
Select a credential source to associate with this stage: 2
Associated account 123456789012 with stage dev.
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]: y
Please enter the ECR image repository ARN(s) for your Image type function(s).If you do not yet have a repository, we will create one for you []:
[4] Summary
Below is the summary of the answers:
1 - Account: 123456789012
2 - Stage name: dev
3 - Region: ap-northeast-1
4 - Pipeline user: [to be created]
5 - Pipeline execution role: [to be created]
6 - CloudFormation execution role: [to be created]
7 - Artifacts bucket: [to be created]
8 - ECR image repository: [to be created]
Press enter to confirm the values above, or select an item to edit the value:
This will create the following required resources for the 'dev' environment:
- Pipeline IAM user
- Pipeline execution role
- CloudFormation execution role
- Artifact bucket
- ECR image repository
Should we proceed with the creation? [y/N]: y
Creating the required resources...
Successfully created!
The following resources were created in your account:
- Pipeline IAM user
- Pipeline execution role
- CloudFormation execution role
- Artifact bucket
- ECR image repository
Pipeline IAM user credential:
AWS_ACCESS_KEY_ID: AKIA****************
AWS_SECRET_ACCESS_KEY: *****************************
View the definition in .aws-sam/pipeline/pipelineconfig.toml,
run sam pipeline bootstrap to generate another set of resources, or proceed to
sam pipeline init to create your pipeline configuration file.
Before running sam pipeline init, we recommend first setting up AWS credentials
in your CI/CD account. Read more about how to do so with your provider in
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-generating-example-ci-cd-others.html.
prodを作成する
~/environment/sam-app $ sam pipeline init --bootstrap
sam pipeline init generates a pipeline configuration file that your CI/CD system
can use to deploy serverless applications using AWS SAM.
We will guide you through the process to bootstrap resources for each stage,
then walk through the details necessary for creating the pipeline config file.
Please ensure you are in the root folder of your SAM application before you begin.
Select a pipeline structure template to get started:
Select template
1 - AWS Quick Start Pipeline Templates
2 - Custom Pipeline Template Location
Choice: 1
Cloning from https://github.com/aws/aws-sam-cli-pipeline-init-templates.git
CI/CD system
1 - Jenkins
2 - GitLab CI/CD
3 - GitHub Actions
4 - Bitbucket Pipelines
5 - AWS CodePipeline
Choice: 3
You are using the 2-stage pipeline template.
_________ _________
| | | |
| Stage 1 |->| Stage 2 |
|_________| |_________|
Checking for existing stages...
Only 1 stage(s) were detected, fewer than what the template requires: 2.
Do you want to go through stage setup process now? If you choose no, you can still reference other bootstrapped resources. [y/N]: y
For each stage, we will ask for [1] stage definition, [2] account details, and [3]
reference application build resources in order to bootstrap these pipeline
resources.
We recommend using an individual AWS account profiles for each stage in your
pipeline. You can set these profiles up using [little bit of info on how to do
this/docs].
Stage 2 Setup
[1] Stage definition
Enter a name for this stage. This will be referenced later when you use the sam pipeline init command:
Stage name: prod
[2] Account details
The following AWS credential sources are available to use:
To know more about configuration AWS credentials, visit the link below:
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html
1 - Environment variables (not available)
2 - default (named profile)
q - Quit and configure AWS credentials
Select a credential source to associate with this stage: 2
Associated account 123456789012 with stage prod.
Enter the region in which you want these resources to be created [ap-northeast-1]:
Pipeline IAM user ARN: arn:aws:iam::123456789012:user/aws-sam-cli-managed-dev-pipeline-reso-PipelineUser-***********
[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]: y
Please enter the ECR image repository ARN(s) for your Image type function(s).If you do not yet have a repository, we will create one for you []: arn:aws:ecr:ap-northeast-1:123456789012:repository/aws-sam-cli-managed-dev-pipeline-resources-imagerepository-***********
[4] Summary
Below is the summary of the answers:
1 - Account: 123456789012
2 - Stage name: prod
3 - Region: ap-northeast-1
4 - Pipeline user ARN: arn:aws:iam::123456789012:user/aws-sam-cli-managed-dev-pipeline-reso-PipelineUser-***********
5 - Pipeline execution role: [to be created]
6 - CloudFormation execution role: [to be created]
7 - Artifacts bucket: [to be created]
8 - ECR image repository ARN: arn:aws:ecr:ap-northeast-1:123456789012:repository/aws-sam-cli-managed-dev-pipeline-resources-imagerepository-***********
Press enter to confirm the values above, or select an item to edit the value:
This will create the following required resources for the 'prod' environment:
- Pipeline execution role
- CloudFormation execution role
- Artifact bucket
Should we proceed with the creation? [y/N]: y
Creating the required resources...
Successfully created!
The following resources were created in your account:
- Pipeline execution role
- CloudFormation execution role
- Artifact bucket
View the definition in .aws-sam/pipeline/pipelineconfig.toml,
run sam pipeline bootstrap to generate another set of resources, or proceed to
sam pipeline init to create your pipeline configuration file.
Checking for existing stages...
This template configures a pipeline that deploys a serverless application to a testing and a production stage.
What is the GitHub secret name for pipeline user account access key ID? [AWS_ACCESS_KEY_ID]:
What is the GitHub Secret name for pipeline user account access key secret? [AWS_SECRET_ACCESS_KEY]:
What is the git branch used for production deployments? [main]: master
What is the template file path? [template.yaml]:
We use the stage configuration name to automatically retrieve the bootstrapped resources created when you ran `sam pipeline bootstrap`.
Here are the stage names detected in .aws-sam/pipeline/pipelineconfig.toml:
1 - dev
2 - prod
Select an index or enter the stage 1's configuration name (as provided during the bootstrapping): 1
What is the sam application stack name for stage 1? [sam-app]: sam-app-dev
Stage 1 configured successfully, configuring stage 2.
Here are the stage names detected in .aws-sam/pipeline/pipelineconfig.toml:
1 - dev
2 - prod
Select an index or enter the stage 2's configuration name (as provided during the bootstrapping): 2
What is the sam application stack name for stage 2? [sam-app]: sam-app-prod
Stage 2 configured successfully.
SUMMARY
We will generate a pipeline config file based on the following information:
What is the GitHub secret name for pipeline user account access key ID?: AKIA****************
What is the GitHub Secret name for pipeline user account access key secret?: *****************************
What is the git branch used for production deployments?: master
What is the template file path?: template.yaml
Select an index or enter the stage 1's configuration name (as provided during the bootstrapping): 1
What is the sam application stack name for stage 1?: sam-app-dev
What is the pipeline execution role ARN for stage 1?: arn:aws:iam::123456789012:role/aws-sam-cli-managed-dev-pipe-PipelineExecutionRole-***********
What is the CloudFormation execution role ARN for stage 1?: arn:aws:iam::123456789012:role/aws-sam-cli-managed-dev-p-CloudFormationExecutionR-***********
What is the S3 bucket name for artifacts for stage 1?: aws-sam-cli-managed-dev-pipeline-artifactsbucket-***********
What is the ECR repository URI for stage 1?: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/aws-sam-cli-managed-dev-pipeline-resources-imagerepository-***********
What is the AWS region for stage 1?: ap-northeast-1
Select an index or enter the stage 2's configuration name (as provided during the bootstrapping): 2
What is the sam application stack name for stage 2?: sam-app-prod
What is the pipeline execution role ARN for stage 2?: arn:aws:iam::123456789012:role/aws-sam-cli-managed-prod-pip-PipelineExecutionRole-***********
What is the CloudFormation execution role ARN for stage 2?: arn:aws:iam::123456789012:role/aws-sam-cli-managed-prod-CloudFormationExecutionR-***********
What is the S3 bucket name for artifacts for stage 2?: aws-sam-cli-managed-prod-pipeline-artifactsbucket-***********
What is the ECR repository URI for stage 2?: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/aws-sam-cli-managed-dev-pipeline-resources-imagerepository-***********
What is the AWS region for stage 2?: ap-northeast-1
Successfully created the pipeline configuration file(s):
- .github/workflows/pipeline.yaml
.github/workflows/pipeline.yamlのコミット
生成されたものを修正して、このパスのままコミットする
pipeline.yaml 生成されたもの
name: Pipeline
on:
push:
branches:
- 'master'
- 'feature**'
delete:
branches:
- 'feature**'
env:
PIPELINE_USER_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
PIPELINE_USER_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
SAM_TEMPLATE: template.yaml
TESTING_STACK_NAME: sam-app-dev
TESTING_PIPELINE_EXECUTION_ROLE: arn:aws:iam::123456789012:role/aws-sam-cli-managed-dev-pipe-PipelineExecutionRole-***********
TESTING_CLOUDFORMATION_EXECUTION_ROLE: arn:aws:iam::123456789012:role/aws-sam-cli-managed-dev-p-CloudFormationExecutionR-***********
TESTING_ARTIFACTS_BUCKET: aws-sam-cli-managed-dev-pipeline-artifactsbucket-***********
TESTING_IMAGE_REPOSITORY: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/aws-sam-cli-managed-dev-pipeline-resources-imagerepository-***********
TESTING_REGION: ap-northeast-1
PROD_STACK_NAME: sam-app-prod
PROD_PIPELINE_EXECUTION_ROLE: arn:aws:iam::123456789012:role/aws-sam-cli-managed-prod-pip-PipelineExecutionRole-***********
PROD_CLOUDFORMATION_EXECUTION_ROLE: arn:aws:iam::123456789012:role/aws-sam-cli-managed-prod-CloudFormationExecutionR-***********
PROD_ARTIFACTS_BUCKET: aws-sam-cli-managed-prod-pipeline-artifactsbucket-***********
PROD_IMAGE_REPOSITORY: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/aws-sam-cli-managed-dev-pipeline-resources-imagerepository-***********
PROD_REGION: ap-northeast-1
jobs:
test:
if: github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: |
# trigger the tests here
delete-feature:
if: startsWith(github.event.ref, 'feature') && github.event_name == 'delete'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: aws-actions/setup-sam@v1
- name: Assume the testing pipeline user role
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ env.PIPELINE_USER_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ env.PIPELINE_USER_SECRET_ACCESS_KEY }}
aws-region: ${{ env.TESTING_REGION }}
role-to-assume: ${{ env.TESTING_PIPELINE_EXECUTION_ROLE }}
role-session-name: testing-packaging
role-duration-seconds: 3600
role-skip-session-tagging: true
- name: Delete feature branch stack
env:
FEATURE_BRANCH_NAME: ${{ github.event.ref }}
run: |
sam delete \
--stack-name $(echo ${FEATURE_BRANCH_NAME##*/} | tr -cd '[a-zA-Z0-9-]') \
--region ${TESTING_REGION} \
--no-prompts
build-and-deploy-feature:
# this stage is triggered only for feature branches (feature*),
# which will build the stack and deploy to a stack named with branch name.
if: startsWith(github.ref, 'refs/heads/feature')
needs: [test]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: aws-actions/setup-sam@v1
- run: sam build --template ${SAM_TEMPLATE} --use-container
- name: Assume the testing pipeline user role
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ env.PIPELINE_USER_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ env.PIPELINE_USER_SECRET_ACCESS_KEY }}
aws-region: ${{ env.TESTING_REGION }}
role-to-assume: ${{ env.TESTING_PIPELINE_EXECUTION_ROLE }}
role-session-name: feature-deployment
role-duration-seconds: 3600
role-skip-session-tagging: true
- name: Deploy to feature stack in the testing account
shell: bash
run: |
sam deploy --stack-name $(echo ${GITHUB_REF##*/} | tr -cd '[a-zA-Z0-9-]') \
--capabilities CAPABILITY_IAM \
--region ${TESTING_REGION} \
--s3-bucket ${TESTING_ARTIFACTS_BUCKET} \
--image-repository ${TESTING_IMAGE_REPOSITORY} \
--no-fail-on-empty-changeset \
--role-arn ${TESTING_CLOUDFORMATION_EXECUTION_ROLE}
build-and-package:
if: github.ref == 'refs/heads/master'
needs: [test]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: aws-actions/setup-sam@v1
- name: Build resources
run: sam build --template ${SAM_TEMPLATE} --use-container
- name: Assume the testing pipeline user role
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ env.PIPELINE_USER_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ env.PIPELINE_USER_SECRET_ACCESS_KEY }}
aws-region: ${{ env.TESTING_REGION }}
role-to-assume: ${{ env.TESTING_PIPELINE_EXECUTION_ROLE }}
role-session-name: testing-packaging
role-duration-seconds: 3600
role-skip-session-tagging: true
- name: Upload artifacts to testing artifact buckets
run: |
sam package \
--s3-bucket ${TESTING_ARTIFACTS_BUCKET} \
--image-repository ${TESTING_IMAGE_REPOSITORY} \
--region ${TESTING_REGION} \
--output-template-file packaged-testing.yaml
- uses: actions/upload-artifact@v2
with:
name: packaged-testing.yaml
path: packaged-testing.yaml
- name: Assume the prod pipeline user role
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ env.PIPELINE_USER_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ env.PIPELINE_USER_SECRET_ACCESS_KEY }}
aws-region: ${{ env.PROD_REGION }}
role-to-assume: ${{ env.PROD_PIPELINE_EXECUTION_ROLE }}
role-session-name: prod-packaging
role-duration-seconds: 3600
role-skip-session-tagging: true
- name: Upload artifacts to production artifact buckets
run: |
sam package \
--s3-bucket ${PROD_ARTIFACTS_BUCKET} \
--image-repository ${PROD_IMAGE_REPOSITORY} \
--region ${PROD_REGION} \
--output-template-file packaged-prod.yaml
- uses: actions/upload-artifact@v2
with:
name: packaged-prod.yaml
path: packaged-prod.yaml
deploy-testing:
if: github.ref == 'refs/heads/master'
needs: [build-and-package]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: aws-actions/setup-sam@v1
- uses: actions/download-artifact@v2
with:
name: packaged-testing.yaml
- name: Assume the testing pipeline user role
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ env.PIPELINE_USER_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ env.PIPELINE_USER_SECRET_ACCESS_KEY }}
aws-region: ${{ env.TESTING_REGION }}
role-to-assume: ${{ env.TESTING_PIPELINE_EXECUTION_ROLE }}
role-session-name: testing-deployment
role-duration-seconds: 3600
role-skip-session-tagging: true
- name: Deploy to testing account
run: |
sam deploy --stack-name ${TESTING_STACK_NAME} \
--template packaged-testing.yaml \
--capabilities CAPABILITY_IAM \
--region ${TESTING_REGION} \
--s3-bucket ${TESTING_ARTIFACTS_BUCKET} \
--image-repository ${TESTING_IMAGE_REPOSITORY} \
--no-fail-on-empty-changeset \
--role-arn ${TESTING_CLOUDFORMATION_EXECUTION_ROLE}
integration-test:
if: github.ref == 'refs/heads/master'
needs: [deploy-testing]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: |
# trigger the integration tests here
deploy-prod:
if: github.ref == 'refs/heads/master'
needs: [integration-test]
runs-on: ubuntu-latest
# Configure GitHub Action Environment to have a manual approval step before deployment to production
# https://docs.github.com/en/actions/reference/environments
# environment: <configured-environment>
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: aws-actions/setup-sam@v1
- uses: actions/download-artifact@v2
with:
name: packaged-prod.yaml
- name: Assume the prod pipeline user role
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ env.PIPELINE_USER_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ env.PIPELINE_USER_SECRET_ACCESS_KEY }}
aws-region: ${{ env.PROD_REGION }}
role-to-assume: ${{ env.PROD_PIPELINE_EXECUTION_ROLE }}
role-session-name: prod-deployment
role-duration-seconds: 3600
role-skip-session-tagging: true
- name: Deploy to production account
run: |
sam deploy --stack-name ${PROD_STACK_NAME} \
--template packaged-prod.yaml \
--capabilities CAPABILITY_IAM \
--region ${PROD_REGION} \
--s3-bucket ${PROD_ARTIFACTS_BUCKET} \
--image-repository ${PROD_IMAGE_REPOSITORY} \
--no-fail-on-empty-changeset \
--role-arn ${PROD_CLOUDFORMATION_EXECUTION_ROLE}
secretの登録
自動生成されたPipelineUserのACCESS_KEY_ID、SECRET_ACCESS_KEYをGITHUBのsecretとして登録する
Settings > Secrets > Actions > New repository secretで登録できる
env:
PIPELINE_USER_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
PIPELINE_USER_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
samconfig.tomlの変更
trueだと確認操作待ちになり失敗する
変更後
confirm_changeset = false
PipelineExecutionRolePermissionsの権限補正
自動生成されたままだと、delete-featureで権限が足りずにエラーになる
GetTemplate権限不足
Error: Failed to fetch the template for the stack: cicd, An error occurred (AccessDenied) when calling the GetTemplate operation: User: arn:aws:sts::***:assumed-role/aws-sam-cli-managed-dev-pipe-PipelineExecutionRole-1CQHYJJ1HT9ZN/testing-packaging is not authorized to perform: cloudformation:GetTemplate on resource: arn:aws:cloudformation:ap-northeast-1:***:stack/cicd/bb8844c0-c661-11ec-aa45-0a395be04137 because no identity-based policy allows the cloudformation:GetTemplate action
Error: Process completed with exit code 1.
DeleteObject権限不足
botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the DeleteObject operation: Access Denied
Error: Process completed with exit code 1.
DeleteStack権限不足
Error: Failed to delete the stack: cicd, An error occurred (AccessDenied) when calling the DeleteStack operation: User: arn:aws:sts::***:assumed-role/aws-sam-cli-managed-dev-pipe-PipelineExecutionRole-1CQHYJJ1HT9ZN/testing-packaging is not authorized to perform: cloudformation:DeleteStack on resource: arn:aws:cloudformation:ap-northeast-1:***:stack/cicd/bb8844c0-c661-11ec-aa45-0a395be04137 because no identity-based policy allows the cloudformation:DeleteStack action
Error: Process completed with exit code 1.
下記の権限をマネージドコンソールで追加する
PipelineExecutionRolePermissionsの修正
cloudformation:GetTemplate
cloudformation:DeleteStack
s3:DeleteObject
testの実装
pipeline.yaml test部分の変更後
jobs:
test:
if: github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Dependencies
run: pip install pytest pytest-mock boto3
- name: Assume the testing pipeline user role
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ env.PIPELINE_USER_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ env.PIPELINE_USER_SECRET_ACCESS_KEY }}
aws-region: ${{ env.TESTING_REGION }}
- name: docker-compose up
run: |
docker-compose up -d
- name: pytest
run: |
python -m pytest -s tests/ -v
integration-test
未実装のままです
で実装しました
Discussion