Skip to content

arunabhg/node-express-actions

Repository files navigation

Node.js Express CI to AWS S3 artifact using GitHub Actions OIDC - starter template


TLDR:* Using the below steps, whenever we make any changes to the code, it is automatically pushed to S3 with the help of OIDC (Open ID Connect) using GitHub Action's CI pipeline. We don't using any Secrets in GitHub Actions. Using OIDC, the connection between AWS and GitHub Actions exists for a short duration (min 1 hr) which can be extended.

Steps

  1. Create a new repo or clone this repo.

  2. We don't need to create a GitHub Secret or an IAM User to upload artifacts to S3 bucket. All we need is to create a role with the specific access. Refer - AWS-Actions - Configure AWS Credentials

  3. Using OpenID Connect (OIDC) we can adopt the following practices:
    3.1 No need to configure long-lived GitHub cloud secrets.
    3.2 We have more granular control over how workflows can use credentials.
    3.3 Using OIDC, the cloud provider (AWS, Azure, GCP), issues a short-lived access-token that is only valid for a single job, and then automatically expires.
    Refer - Overview of OpenId Connect

  4. Go to AWS console -> IAM -> Identity Providers & click on Add Provider.

  5. Select OpenID Connect and for the provider URL: https://token.actions.githubusercontent.com

  6. Click on Get Thumbprint.

  7. For the audience, use: sts.amazonaws.com and add the provider.

  8. Click on Assign Role -> Create a new role.
    8.1 AWS creates an identity type of Web Identity with audience of sts.amazonaws.com. Click Next: Permissions
    8.2 You can give S3FullAccess. Note - Permissions (List, Read, Write) should be for the specific buckets, not full access in production.
    8.3 Give the role a name, eg., Github-actions-role, add description, and click on Create Role.

  9. Go to the trust relationship of the role and click Edit Trust Policy.
    Add the line to it: "token.actions.githubusercontent.com:sub": "repo:octo-org/octo-repo:ref:refs/heads/octo-branch"
    Change the repo owner, name & branch as it applies & Click on Update Policy.
    For eg., in our case, the string will be - "token.actions.githubusercontent.com:sub": "repo:arunabhg/node-express-actions:ref:refs/heads/main"
    Note- In some cases we may get error Error: Not authorized to perform sts:AssumeRoleWithWebIdentity. In That case we have to Edit the Policy & write the policy as:

    "Condition": {
                "StringEquals": {
                    "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
                },
                "StringLike": {
                    "token.actions.githubusercontent.com:sub": "repo:arunabhg/node-express-actions:*"
                }
            }
    
    

Here the * after the repo name means the repo can be accessed by all refs and not only main.

  1. Go to the YAML file in your project's GitHub Workflows.
    10.1 Add an env section with the bucket name, region & permissions.
    env: BUCKET_NAME: "<aws-bucket-name>" AWS_REGION: "<aws-region>" GITHUB_REF: "main"
    10.2 Add a permissions section in the jobs part which lists the read and write permissions:
    permissions: id-token: write contents: read #required for actions/checkout
    Put this before the steps part.
    10.3 Add a section to configure the AWS credentials as the first step -

       - name: Configure AWS Credentials
           uses: aws-actions/configure-aws-credentials@v1
           with:
             role-to-assume: arn:aws:iam::754345194439:role/GitHub-actions-role
             role-session-name: Github-Actions-Role
             aws-region: ${{ env.AWS_REGION }}
    

    Note - Remember to change the arn and role-session-name as specified in the IAM Role, otherwise the Action will fail.
    10.4 Add a step to create a SHA hash. Add this section just below the above one.

        - name: Extract branch name
        shell: bash
        run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
        id: extract_branch
        - name: Extract commit hash
        shell: bash
        run: echo "##[set-output name=commit_hash;]$(echo "$GITHUB_SHA")"
        id: extract_hash
    

    10.5 As a last step in the workflow, make a directory in S3 and upload the artifact as a zip file to the folder in S3. Add the last step at the end of the workflow -

        - name: Make Artifact directory
        run: mkdir -p ./artifacts
    
        # Copy build directory to S3
        - name: Copy build to S3
        run: |
            zip -r ./artifacts/project.zip . -x node_modules/**\* .git/**\* dist/**\* dist/**\*
            aws s3 sync  ${GITHUB_WORKSPACE}/artifacts s3://${{ env.BUCKET_NAME }}/${{ steps.extract_branch.outputs.branch }}/latest
    

Note - Remember to give the correct names to your S3 bucket, folder, session, role-session, aws-region, etc. in the workflow, otherwise the workflow will fail.

About

Project template for creating a CI pipeline to S3 bucket using Github Actions & OIDC

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors