How to connect Github to AWS CodePipelines?
Tags: aws, node, github
Published: 2022-01-16 00:19:25

AWS documentation describes two ways to connect your Github repository to CodePipelines. The [first](https://docs.aws.amazon.com/codepipeline/latest/userguide/connections-github.html) –recommended– way is easy to follow but it is only available via the AWS console or CLI. If you are using CDK you are left with the second option which I describe here.


![Github loves CodePipelines](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5a8mxadiiaokxml28cvx.png)

## Step 1: Create OAuth token to access your Github repository

The first step is to generate an access token to allow your pipeline to access and read your repository on Github. Follow the Github documentation to create your personal access token as described [here](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token).

Make sure to select the `admin:repo_hook` and `repo` permissions to allow your pipeline a read access and also allow it to install a webhook to trigger pipeline actions when you make a new commit.

## Step 2: Store the OAuth token in AWS Secrets Manager

In the second step, we need to store the token so that we can use it. The access token is an important security credential and therefore you do not want to store it as plain text. Alternatively, we will store it in Secrets Manager. This way you can reference it dynamically in your CDK code.

Set the access token and the AWS region you are using and create the secret via CLI:

``` bash
➜  ~ GITHUB_ACCESS_TOKEN='this is my secret'
➜  ~ REGION=us-east-1
➜  ~ aws secretsmanager  create-secret --name github-access-token-secret --description "Github access token" --secret-string $GITHUB_ACCESS_TOKEN --region $REGION
```

## Step 3: Setup a CloudFormation stack to deploy the pipeline

It is important to note that your CodePipeline is by itself a CFN resource that you can define using CDK. In the third step, we define a CFN stack to deploy our pipeline. In this example, I am using NodeJS CDK:

``` typescript
import * as cdk from 'aws-cdk-lib';
import { CodeBuildStep, CodePipeline, CodePipelineSource } from 'aws-cdk-lib/pipelines';
import { Construct } from 'constructs';

export class PipelineStack extends cdk.Stack {
    constructor(scope: Construct, id: string, props?: cdk.StackProps) {
        super(scope, id, props);

        // Set your Github username and repository name
        const branch = 'master';
        const gitHubUsernameRepository = 'mmoanis/feed-mohamed-app';

        const pipeline = new CodePipeline(this, 'Pipeline', {
            pipelineName: "MyCDKPipeline",
            synth: new CodeBuildStep('SynthStep', {
                input: CodePipelineSource.gitHub(gitHubUsernameRepository, branch, {
                    authentication: cdk.SecretValue.secretsManager('github-access-token-secret'),
                }),
                installCommands: [
                    'npm install -g aws-cdk'
                ],
                commands: [
                    'npm ci',
                    'npm run build',
                    'npx cdk synth'
                ]
            })
        });
    }
}
```

The CFN template will be generated with a dynamic reference to the secret stored in Secrets Manager with your Github personal access token.

## Step 4: Commit your code and deploy your stack

The final step, commit your code and push it to your branch. Then deploy your CFN stack from CLI to bootstrap your pipeline:

``` bash
cdk deploy
```

Once you deploy your CFN stack, your pipeline will start building and deploying your stack for you. Each commit to the specified branch will trigger an action on your pipeline which in turn will mutate it self –if you have changed it.

I created a complete Github repository with a full example that you can find [here](https://github.com/mmoanis/feed-mohamed-app).

Enjoy!