Back to notes

The pipeline needs source code. The Source stage pulls it from GitHub using the same CodeConnection from post 2. This post defines the top-level pipeline resource and wires up the first stage.

CodePipeline Service Role

The pipeline needs an IAM role to operate. This is distinct from the Git Sync role in post 4, which grants CloudFormation permission to provision resources. This role grants the pipeline permission to do its job at runtime.

  CodePipelineServiceRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: codepipeline.amazonaws.com
            Action: 'sts:AssumeRole'
      Policies:
        - PolicyName: PipelineAccessPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:GetObjectVersion
                  - s3:GetBucketVersioning
                  - s3:PutObject
                  - s3:ListBucket
                  - s3:DeleteObject
                Resource:
                  - !GetAtt PipelineArtifactBucket.Arn
                  - !Sub '${PipelineArtifactBucket.Arn}/*'
              - Effect: Allow
                Action: 'codestar-connections:UseConnection'
                Resource: !ImportValue Example-GitHubConnectionArn
              - Effect: Allow
                Action:
                  - 'codebuild:BatchGetBuilds'
                  - 'codebuild:StartBuild'
                Resource: !GetAtt BuildProject.Arn

AssumeRolePolicyDocument is the trust policy. It allows the codepipeline.amazonaws.com service principal to assume this role. Without it, CodePipeline cannot use the role.

The Policies array contains one inline policy with three statements.

The first statement grants S3 permissions to the artifact bucket. It needs two resource entries: the bucket ARN for bucket-level actions like ListBucket and GetBucketVersioning, and a /* wildcard for object-level actions like GetObject, PutObject, and DeleteObject. The pipeline only needs access to the artifact bucket. The deploy project (with its own DeployServiceRole) handles site bucket writes.

The second statement grants codestar-connections:UseConnection scoped to the CodeConnection ARN, imported from the connection stack via !ImportValue Example-GitHubConnectionArn. This lets the Source stage authenticate with GitHub and pull your repository. The permission targets the specific connection, not a wildcard.

The third statement grants CodeBuild permissions scoped to the build project. BatchGetBuilds lets the pipeline check build status. StartBuild lets it trigger new builds.

The Pipeline Resource

The AWS::CodePipeline::Pipeline resource ties everything together. It references the service role above, the artifact bucket from post 8, and an array of stages. This post covers the Source stage. The Build and Deploy stages come in the next two posts.

  Pipeline:
    Type: 'AWS::CodePipeline::Pipeline'
    Properties:
      RoleArn: !GetAtt CodePipelineServiceRole.Arn
      ArtifactStore:
        Type: S3
        Location: !Ref PipelineArtifactBucket
      Stages:
        - Name: Source
          Actions:
            - Name: GitHubSource
              ActionTypeId:
                Category: Source
                Owner: AWS
                Provider: CodeStarSourceConnection
                Version: '1'
              OutputArtifacts:
                - Name: SourceArtifact
              Configuration:
                ConnectionArn: !ImportValue Example-GitHubConnectionArn
                FullRepositoryId: !Ref GitHubRepository
                BranchName: main
                OutputArtifactFormat: CODE_ZIP

RoleArn points to the CodePipeline service role defined above. This is the role the pipeline assumes when executing actions.

ArtifactStore tells the pipeline where to store intermediate artifacts. It uses the dedicated artifact bucket, not your site bucket.

Stages is an ordered array. The pipeline executes them top to bottom: Source, then Build, then Deploy.

Source Stage

The Source stage has one action that pulls code from GitHub.

ActionTypeId identifies this as a Source action using the CodeStarSourceConnection provider. This is the same provider type that Git Sync uses under the hood, but here it feeds a pipeline instead of CloudFormation directly.

ConnectionArn: !ImportValue Example-GitHubConnectionArn imports the connection ARN from the connection stack (post 2). No parameter needed. The value comes from the cross-stack export, so every site stack automatically uses the same connection.

FullRepositoryId: !Ref GitHubRepository is the owner/repo string for your GitHub repository.

BranchName: main tells the pipeline to trigger on pushes to the main branch. You can change this to any branch you want to deploy from.

OutputArtifactFormat: CODE_ZIP packages the repository contents as a zip file. This zip becomes the input artifact for the Build stage.

OutputArtifacts names the artifact SourceArtifact. The Build stage references this name to pick up where Source left off.

When you push to main, the CodeConnection detects the change and triggers the pipeline. The Source stage downloads the repo contents, zips them, and stores the zip in the artifact bucket. The Build stage picks it up from there.