Setup Approval Action in CodePipeline
An Approval action can be added to the Codepipeline stage.
Once the pipeline advances to the approval stage, it will stop action and wait for manual approval.
In this case, we aim to configure the pipeline to send an email notification via SNS when it reaches the approval stage.
Environment
Configure CodePipeline to link four resources.
The first is CodeCommit.
CodeCommit is responsible for the source stage of CodePipeline.
It is used as a Git repository.
The second is CodeBuild.
CodeBuild is in charge of the build stage of CodePipeline.
It builds a Docker image from code pushed to CodeCommit.
The built image is pushed to ECR.
The third is SNS.
SNS is responsible for the approval stage of CodePipeline.
When the pipeline reaches the approval stage, the pipeline stops and the SNS sends an email notification.
Upon receiving the email notification, the user goes to the pipeline page and presses the approve button to resume the pipeline.
The fourth is the Lambda function.
The function’s function is to change the desired number of tasks for the ECS (Fargate) service.
Specifically, it changes the desired number from 0 to 1.
Create a deploy stage in CodePipeline.
Configure it to deploy to Fargate as described below.
Save your DockerHub account information in the SSM parameter store.
These will be used to pull the base image when generating images with DockerBuild, after signing in to DockerHub.
The trigger for CodePipeline to be started is conditional on a push to CodeCommit.
Specifically, we will have a rule in EventBridge that satisfies the above.
Create a Fargate type ECS on a private subnet.
Create an EC2 instance.
Use it as a client to access containers created on Fargate.
CloudFormation template files
Build the above configuration with CloudFormation.
The CloudFormation templates are located at the following URL
https://github.com/awstut-an-r/awstut-fa/tree/main/080
Explanation of key points of the template files
This page will cover how to create an approval stage in Codepipeline and email notification via SNS.
For basic information on CodePipeline, please refer to the following page
For information on how to create a deployment stage in CodePipeline and deploy to ECS (Fargate), please see the following page.
For information on how to define an action that calls a Lambda function within CodePipeline and change the desired number of ECS (Fargate) services, please see the following page.
For information on how to build Fargate on a private subnet, please see the following page.
Use CloudFormation custom resources to automatically delete objects in S3 buckets and images in ECR repositories when deleting CloudFormation stacks.
For more information, please refer to the following page
SNS
Resources:
Topic:
Type: AWS::SNS::Topic
Properties:
Subscription:
- Endpoint: !Ref MailAddress
Protocol: email
TopicName: !Ref Prefix
Code language: YAML (yaml)
Create an SNS topic.
Specify email as the notification destination.
For more information, see the following page.
CodePipeline
Resources:
Pipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
ArtifactStore:
Location: !Ref BucketName
Type: S3
Name: !Ref Prefix
RoleArn: !GetAtt CodePipelineRole.Arn
Stages:
- Actions:
- ActionTypeId:
Category: Source
Owner: AWS
Provider: CodeCommit
Version: 1
Configuration:
BranchName: !Ref BranchName
OutputArtifactFormat: CODE_ZIP
PollForSourceChanges: false
RepositoryName: !GetAtt CodeCommitRepository.Name
Name: Source
OutputArtifacts:
- Name: !Ref PipelineSourceArtifact
Region: !Ref AWS::Region
RunOrder: 1
Name: Source
- Actions:
- ActionTypeId:
Category: Build
Owner: AWS
Provider: CodeBuild
Version: 1
Configuration:
ProjectName: !Ref CodeBuildProject
InputArtifacts:
- Name: !Ref PipelineSourceArtifact
Name: Build
OutputArtifacts:
- Name: !Ref PipelineBuildArtifact
Region: !Ref AWS::Region
RunOrder: 1
Name: Build
- Actions:
- ActionTypeId:
Category: Approval
Owner: AWS
Provider: Manual
Version: 1
Configuration:
CustomData: hoge hoge hoge.
ExternalEntityLink: http://example.com
NotificationArn: !Ref TopicArn
InputArtifacts: []
Name: Approval
OutputArtifacts: []
Region: !Ref AWS::Region
RunOrder: 1
Name: Approval
- Actions:
- ActionTypeId:
Category: Deploy
Owner: AWS
Provider: ECS
Version: 1
Configuration:
ClusterName: !Ref ECSClusterName
FileName: !Ref ImageDefinitionFileName
ServiceName: !Ref ECSServiceName
InputArtifacts:
- Name: !Ref PipelineBuildArtifact
Name: Deploy
Region: !Ref AWS::Region
RunOrder: 1
Name: Deploy
- Actions:
- ActionTypeId:
Category: Invoke
Owner: AWS
Provider: Lambda
Version: 1
Configuration:
FunctionName: !Ref ECSFunctionName
InputArtifacts: []
Name: Invoke
OutputArtifacts: []
Region: !Ref AWS::Region
RunOrder: 1
Name: Invoke
Code language: YAML (yaml)
Define approval stage in the Stages property.
Within the Configuration property, configure the detailed settings for the approval stage. A particularly important parameter is the NotificationArn property. Specify the aforementioned SNS topic in this property.
The InputArtifacts and OutputArtifacts properties specify an empty array. This is because in this behavior, no reading or writing to the artifacts will occur.
The following are the IAM roles for CodePipeline
Resources:
CodePipelineRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- codepipeline.amazonaws.com
Action:
- sts:AssumeRole
Policies:
- PolicyName: PipelinePolicy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- lambda:invokeFunction
Resource:
- !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${ECSFunctionName}"
- Effect: Allow
Action:
- codecommit:CancelUploadArchive
- codecommit:GetBranch
- codecommit:GetCommit
- codecommit:GetRepository
- codecommit:GetUploadArchiveStatus
- codecommit:UploadArchive
Resource:
- !GetAtt CodeCommitRepository.Arn
- Effect: Allow
Action:
- codebuild:BatchGetBuilds
- codebuild:StartBuild
- codebuild:BatchGetBuildBatches
- codebuild:StartBuildBatch
Resource:
- !GetAtt CodeBuildProject.Arn
- Effect: Allow
Action:
- s3:PutObject
- s3:GetObject
- s3:GetObjectVersion
- s3:GetBucketAcl
- s3:GetBucketLocation
Resource:
- !Sub "arn:aws:s3:::${BucketName}"
- !Sub "arn:aws:s3:::${BucketName}/*"
- Effect: Allow
Action:
- sns:Publish
Resource:
- !Ref TopicArn
- Effect: Allow
Action:
- ecs:*
Resource: "*"
- Effect: Allow
Action:
- iam:PassRole
Resource: "*"
Condition:
StringLike:
iam:PassedToService:
- ecs-tasks.amazonaws.com
Code language: YAML (yaml)
Set permissions for the approval stage.
Allow “sns:Publish” for SNS topics.
(Reference)Application Container
Dockerfile
FROM amazonlinux
RUN yum update -y && yum install python3 python3-pip -y
RUN pip3 install bottle
COPY main.py ./
CMD ["python3", "main.py"]
EXPOSE 8080
Code language: Dockerfile (dockerfile)
The image for the app container will be based on Amazon Linux 2.
We will use Bottle, a Python web framework.
So after installing Python and pip, install this.
Copy the Python script (main.py) describing the app logic and set this to run.
As mentioned earlier, the app listens for HTTP requests on 8080/tcp, so expose this port.
main.py
from bottle import route, run
@route('/')
def hello():
return 'Hello CodePipeline.'
if __name__ == '__main__':
run(host='0.0.0.0', port=8080)
Code language: Python (python)
We will use Bottle to build a simple web server.
The simple configuration is to listen for HTTP requests at 8080/tcp and return “Hello CodePipeline.”
Architecting
We will use CloudFormation to build this environment and check the actual behavior.
Create CloudFormation stacks and check resources in stacks
Create a CloudFormation stack.
Please refer to the following pages for information on how to create stacks and check each stack.
After reviewing the resources in each stack, the following is the information on the main resources created at this time.
- ECR: fa-080
- CodeCommit: fa-080
- CodeBuild: fa-080
- CodePipeline: fa-080
- Lambda function: fa-080-function-ecs
- SNS Topics: fa-080
Authentication of email address
If you specify an email address as a subscriber to an SNS topic, you must authenticate that email address.
For details, please refer to the following page.
Resource Confirmation
Check each resource from the AWS Management Console.
Check CodePipeline.
The pipeline is failing to execute.
This is because the pipeline was triggered by the creation of CodeCommit when the CloudFormation stack was created.
Since we are not pushing code to CodeCommit at this time, an error occurred during the pipeline execution process.
Note the stage that is being created.
There is a stage named Approval that calls the SNS topic.
When the pipeline reaches this stage, it will stop and wait for approval.
Check Action
Now that we are ready, we push the code to CodeCommit.
First, pull CodeCommit.
$ git clone https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/fa-080
Cloning into 'fa-080'...
warning: You appear to have cloned an empty repository.
Code language: Bash (bash)
An empty repository has been pulled.
Add the Dockerfile and main.py to the repository.
$ ls -al
total 8
drwxrwxr-x 3 ec2-user ec2-user 51 Aug 20 23:54 .
drwxrwxr-x 3 ec2-user ec2-user 20 Aug 20 23:53 ..
-rw-rw-r-- 1 ec2-user ec2-user 187 Aug 12 11:01 Dockerfile
drwxrwxr-x 7 ec2-user ec2-user 119 Aug 20 23:53 .git
-rw-rw-r-- 1 ec2-user ec2-user 691 Aug 20 11:25 main.py
Code language: Bash (bash)
Push the two files to CodeCommit.
$ git add .
$ git commit -m 'first commit'
[master (root-commit) 6bfe691] first commit
...
2 files changed, 39 insertions(+)
create mode 100644 Dockerfile
create mode 100644 main.py
$ git push
...
* [new branch] master -> master
Code language: Bash (bash)
The push was successful.
After waiting for a while, check CodePipeline again.
Pipeline has been started.
The Source and Build stages have been completed successfully, and the Approval stage has been reached.
However, the status is “Pending” and the message “Waiting for approval” is displayed.
This means that the status will continue until an authorized user approves it.
You will receive an email from SNS Topic as follows
Thus, an email can let the user know that you are waiting for approval.
As for the authorization required for pipeline approval, the official AWS page indicates the following
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"codepipeline:ListPipelines"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"codepipeline:GetPipeline",
"codepipeline:GetPipelineState",
"codepipeline:GetPipelineExecution"
],
"Resource": "arn:aws:codepipeline:us-east-2:80398EXAMPLE:MyFirstPipeline"
},
{
"Effect": "Allow",
"Action": [
"codepipeline:PutApprovalResult"
],
"Resource": "arn:aws:codepipeline:us-east-2:80398EXAMPLE:MyFirstPipeline/MyApprovalStage/MyApprovalAction"
}
]
}
Code language: JSON / JSON with Comments (json)
https://docs.aws.amazon.com/codepipeline/latest/userguide/approvals-iam-permissions.html
Proceed with approval by a user who meets the above authorization.
Click “Approval” to approve.
The message “Approved” is displayed.
This means that the pipeline has been restarted by approving.
Wait for a while.
All stages of the pipeline have been completed.
Check the Fargate.
You can see that the desired number of tasks in ECS (Fargate) is 1 and the IP address of the task is “10.0.2.4”.
We will actually access the container in the task.
% aws ssm start-session --target i-0c41c5926230b480c
Starting session with SessionId: root-0c76e08548a26fec6
sh-4.2$
Code language: Bash (bash)
For more information on SSM Session Manager, please refer to the following page
Use the curl command to access the container in the task.
sh-4.2$ curl http://10.0.2.4:8080/
Hello CodePipeline.
Code language: Bash (bash)
The container responded.
It is indeed the string we set up in the Bottle app.
This indicates that the pipeline has indeed been executed.
By creating an approval stage in CodePipeline, we were able to pause the pipeline, receive email notifications via SNS, and resume the pipeline upon approval.
Summary
We have confirmed how to create an approval stage in CodePipeline and how to notify via SNS by email.