Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
December 19, 2021 02:47 am GMT

Secure AWS-CDK deployments with GitHub Actions

GitHub actions enables continuous integration, and the aws-cdk enables infrastructure as code.

This guide provides a secure way to automate the deployments of aws-cdk stacks, from GitHub actions to your AWS account.

It's more secure because you do not have to store long lived credentials in your GitHub account, and, because only the open ID connect with GitHubs fingerprint can assume the deployment role

How it works

We will utilise open ID connect, to grant GitHub a temporary federated identity. This identity will be trusted, to assume a role in your AWS account.

When the identity (GitHub) assumes the roles, we will secure it's access by doing two things:

  • Granting a temporary aws secret key and access key, that expires in an hour.
  • Using claims from the JWT presented by GitHub to AWS to narrow the scope of the allowed identities.

Setup

When we are done we will have:

  • A one-off GitHub action, that creates the identity provider and trust relationship using an aws-cdk stack.
  • Another GitHub action that uses the identity to gain temporary access, and deploy aws-cdk stacks.

Creating the bootstrap stack

We can create a new aws-cdk application:

mkdir bootstrapnpx [email protected] init app --language typescript

After that we will use two components from IAM to create a provider, and a principal.

We will use the principal to create a trust relationship between aws, and GitHub like so.

/** * Create an Identity provider for GitHub inside your AWS Account. This * allows GitHub to present itself to AWS IAM and assume a role. */const provider = new OpenIdConnectProvider(this, 'MyProvider', {  url: 'https://token.actions.githubusercontent.com',  clientIds: ['sts.amazonaws.com'],});

Then establish the trust relationship by defining the conditions for this provider to act as a principal.

I will provide an example that assumes you are https://github.com/simonireilly and you want to deploy from all repository branches of a repo called awesome-project

const githubOrganisation = "simonireilly"// Change this to the repo you want to push code fromconst repoName = "awesome-project"/** * Create a principal for the OpenID; which can allow it to assume * deployment roles. */const GitHubPrincipal = new OpenIdConnectPrincipal(provider).withConditions(  {    StringLike: {      'token.actions.githubusercontent.com:sub':        `repo:${githubOrganisation}/${repoName}:*`,    },  });

Finally you want to establish the role that can be assumed by the OIDC principal. This will allow GitHub actions to use the AWS Roles, and mutate the AWS Resources you give it access to.

/**  * Create a deployment role that has short lived credentials. The only  * principal that can assume this role is the GitHub Open ID provider.  *  * This role is granted authority to assume aws cdk roles; which are created  * by the aws cdk v2.  */new Role(this, 'GitHubActionsRole', {  assumedBy: GitHubPrincipal,  description:    'Role assumed by GitHubPrincipal for deploying from CI using aws cdk',  roleName: 'github-ci-role',  maxSessionDuration: Duration.hours(1),  inlinePolicies: {    CdkDeploymentPolicy: new PolicyDocument({      assignSids: true,      statements: [        new PolicyStatement({          effect: Effect.ALLOW,          actions: ['sts:AssumeRole'],          resources: [`arn:aws:iam::${this.account}:role/cdk-*`],        }),      ],    }),  },});

These permissions may be too broad for your use case. Consider adding a permissions boundary, or, opting to use a role other than the role automatically created by the cdk for its deployments

Deploying Bootstrap

With a set of created access keys, you can deploy the bootstrap. This enables someone with higher privilege to setup the link for your team

This keeps you from storing long lived credentials in GitHub.

name: Bootstrapon:  workflow_dispatch:    inputs:      AWS_ACCESS_KEY_ID:        description: "Access Key ID with Permissions to deploy IAM, and OIDC"        required: true      AWS_SECRET_ACCESS_KEY:        description: "Secret Access Key with Permissions to deploy IAM, and OIDC"        required: true      AWS_REGION:        description: "Region to deploy to."        required: truejobs:  deploy:    runs-on: ubuntu-latest    steps:      - name: Git clone the repository        uses: actions/checkout@v1      - name: Configure aws credentials        uses: aws-actions/configure-aws-credentials@master        with:          aws-access-key-id: ${{ github.event.inputs.AWS_ACCESS_KEY_ID }}          aws-secret-access-key: ${{ github.event.inputs.AWS_SECRET_ACCESS_KEY }}          aws-region: ${{ github.event.inputs.AWS_REGION }}      - uses: actions/setup-node@v2        with:          node-version: "14"      - run: yarn install      - name: Synth stack        run: yarn --cwd packages/bootstrap cdk synth      - name: Deploy stack        run: yarn --cwd packages/bootstrap cdk deploy --require-approval never

When you trigger this action the user must enter aws access keys and aws secrets that have the required privileges.

GitHub user interface showing drop-down to enter aws secrets

Post Bootstrap life

With this stack deployed you can now ship any aws-cdk v2 deployments from the trusted repository, to the linked AWS account, without storing long lived credentials.

All you need to do is instruct GitHUb actions to assume the github-ci-role role in your account, and it will get temporary credentials for one hour.

  deploy-infrastructure:    runs-on: ubuntu-latest    steps:      - name: Git clone the repository        uses: actions/checkout@v1      - name: Assume role using OIDC        uses: aws-actions/configure-aws-credentials@master        with:          role-to-assume: arn:aws:iam::<your-account-id-here>:role/github-ci-role          aws-region: ${{ env.AWS_REGION }}      - uses: actions/setup-node@v2        with:          node-version: "14"      - run: yarn install      - name: Synth infrastructure stack        run: yarn --cwd packages/infrastructure cdk synth      - name: Deploy infrastructure stack        run: yarn --cwd packages/infrastructure cdk deploy --require-approval never

Next steps might to be

Create another bootstrapping aws cdk stack, that allows only deploying from the main branch, and point this one at your production AWS account if you have one

{  StringLike: {    'token.actions.githubusercontent.com:sub':      `repo:${githubOrganisation}/${repository}:ref:/refs/head/main`,  },}

Follow up

If you are interested in this stuff, you might like microteams!

A guide I am writing for scale ups, that are growing from one person AWS start-ups to multi-team organisations.


Original Link: https://dev.to/simonireilly/secure-aws-cdk-deployments-with-github-actions-3jfk

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To