AWS CodePipeline
AWS CodePipeline
Section titled “AWS CodePipeline”AWS CodePipeline offers a way to define workflows for continuous integration and delivery (CI/CD).
Various AWS services are used to implement each stage of a pipeline.
There is no need to provision upfront infrastructure as build agents are provisioned on demand. This can be cheaper than running a dedicated build server.
Stages
Section titled “Stages”A CodePipeline is divided into many stages, or steps in a workflow. A simple linear workflow might be
- source checkout
- build a docker image
- deploy the image as docker container
By configuring a git webhook, a pipeline can be triggered each time a commit is pushed to source control.
Artifact store
Section titled “Artifact store”Each stage of a pipeline is executed asynchronously, and may use output artifacts from a previous stage. Artifact storage is required to accommodate this. In 2022, S3 is only option.
Source checkout
Section titled “Source checkout”AWS provides git hosting via CodeCommit.
Source code residing on GitHub or BitBucket can be accessed using a CodeStar connections.
An archive artifact (zip of the source code) is an output of this stage. This can be sent to a downstream build stage.
This stage is handled by a AWS CodeBuild project.
CodePipeline will assume a role to run. It may need access to
- The S3 bucket for artifact storage
- The CodeStar connection to access source code
- The CodeBuild project to start the build job.
Terraform
Section titled “Terraform”Sample CodePipeline
# githubresource "aws_codestarconnections_connection" "github" { name = "github" provider_type = "GitHub"}
# S3 bucket where artifacts are stored for the pipelineresource "aws_s3_bucket" "example_codepipeline" { bucket = "example-codepipeline"}
resource "aws_s3_bucket_public_access_block" "example_codepipeline" { bucket = aws_s3_bucket.example_codepipeline.id
block_public_acls = true block_public_policy = true ignore_public_acls = true restrict_public_buckets = true}
resource "aws_s3_bucket_acl" "example_codepipeline" { bucket = aws_s3_bucket.example_codepipeline.id acl = "private"}
# pipeline roleresource "aws_iam_role" "example" { name = "example-codepipeline" assume_role_policy = <<EOF{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "codepipeline.amazonaws.com" }, "Action": "sts:AssumeRole" } ]}EOF}
resource "aws_iam_role_policy" "example" { name = "example-codepipeline" role = aws_iam_role.example.id policy = <<EOF{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "codestar-connections:UseConnection" ], "Resource": "${aws_codestarconnections_connection.github.arn}" }, { "Effect":"Allow", "Action": [ "s3:GetObject", "s3:GetObjectVersion", "s3:GetBucketVersioning", "s3:PutObjectAcl", "s3:PutObject" ], "Resource": [ "${aws_s3_bucket.example_codepipeline.arn}", "${aws_s3_bucket.example_codepipeline.arn}/*" ] }, { "Effect": "Allow", "Action": [ "codebuild:BatchGetBuilds", "codebuild:StartBuild" ], "Resource": [ "${aws_codebuild_project.example.arn}" ] } ]}EOF}
resource "aws_codepipeline" "example" { name = "example" role_arn = aws_iam_role.example.arn
artifact_store { location = aws_s3_bucket.example.bucket type = "S3" } stage { name = "Source" action { category = "Source" name = "Source" owner = "AWS" provider = "CodeStarSourceConnection" version = "1" output_artifacts = ["source_output"]
configuration = { ConnectionArn = aws_codestarconnections_connection.github.arn FullRepositoryId = "magicmonster/example" BranchName = "main" } } } stage { name = "Build"
action { name = "Build" category = "Build" owner = "AWS" provider = "CodeBuild" input_artifacts = ["source_output"] output_artifacts = ["build_output"] version = "1"
configuration = { ProjectName = aws_codebuild_project.example.name } } }}