Skip to content

Commit

Permalink
feat(deploy-gh-action): deploying an application to AWS via GH actions
Browse files Browse the repository at this point in the history
  • Loading branch information
m-sureshraj committed Jul 29, 2024
1 parent 2ebf29a commit 34d24ec
Show file tree
Hide file tree
Showing 11 changed files with 15,435 additions and 65 deletions.
36 changes: 36 additions & 0 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# This workflow is associated with the `/deployment-with-github-actions` project directory.

name: example dir `deployment-with-github-actions` deployment

on:
push:
branches:
- main # run the workflow when a push is made to the main branch
paths:
- 'deployment-with-github-actions/**'

pull_request:
branches:
- main # run the workflow when the target branch of the PR is main
paths:
- 'deployment-with-github-actions/**'

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v4

- name: ⎔ Setup node
uses: actions/setup-node@v4
with:
node-version: 20

- name: Install dependencies
working-directory: ./deployment-with-github-actions
run: npm ci

- name: Unit test
working-directory: ./deployment-with-github-actions
run: npm run test
125 changes: 67 additions & 58 deletions .github/workflows/deploy-to-dev-env.yml
Original file line number Diff line number Diff line change
@@ -1,70 +1,79 @@
name: deploy the selected branch to development (dev) deployment
# This manual workflow allows us to deploy an example project to the development environment.
# It must be triggered manually and requires the name of the example project as its input.
# It uses AWS OpenID Connect (OIDC) to securely authenticate with AWS and deploy the necessary resources.

name: deploy an example project to the development environment

on:
workflow_dispatch:
inputs:
directory_name:
description: 'Which example project do you want to deploy'
required: true

#permissions:
# id-token: write # This is required for requesting the JWT
# contents: read # This is required for actions/checkout

env:
AWS_REGION : 'eu-west-2'
permissions:
contents: read # This is required for the actions/checkout step

jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ${{ github.event.inputs.directory_name }}
steps:
# - name: ⬇️ Checkout repo
# uses: actions/checkout@v4
#
# - name: ⎔ Setup node
# uses: actions/setup-node@v4
# with:
# node-version: 18
- name: ⬇️ Checkout repo
uses: actions/checkout@v4

- name: print the branch name
# working-directory: ./deployment-with-github-actions
run: |
echo "GITHUB_BASE_REF - ${{ github.base_ref }}"
echo "GITHUB_HEAD_REF - ${{ github.head_ref }}"
echo "GITHUB_REF - ${{ github.ref }}"
echo "GITHUB_REF_NAME - ${{ github.ref_name }}"
- name: ⎔ Setup node
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
cache-dependency-path: ${{ github.event.inputs.directory_name }}

- name: Install dependencies
run: npm ci

- name: Unit test
run: npm run test

deploy:
needs: build # This job depends on the build job.
runs-on: ubuntu-latest
# The environment name is set up in the repository settings. It manages the environment's variables and secrets.
# i.e. AWS_GITHUB_ACTIONS_DEPLOYMENT_IAM_ROLE_ARN and AWS_REGION
environment: development
permissions:
id-token: write # Fetch an OpenID Connect (OIDC) token.
defaults:
run: # steps that have the `run` command will use the given example project path as the working directory
working-directory: ${{ github.event.inputs.directory_name }}
steps:
- name: Git clone the repository
uses: actions/checkout@v4

- name: ⎔ Setup node
uses: actions/setup-node@v4
with:
node-version: 20

# - name: Unit test
# working-directory: ./deployment-with-github-actions
# run: npm run test
- name: Install dependencies
run: npm ci

- name: configure aws credentials
uses: aws-actions/configure-aws-credentials@v4
with:
mask-aws-account-id: true
role-to-assume: ${{ secrets.AWS_GITHUB_ACTIONS_DEPLOYMENT_IAM_ROLE_ARN }} # dev env -> secrets
role-session-name: github-action-sls-examples
aws-region: ${{ vars.AWS_REGION }} # dev env -> vars

- name: versions
run: |
echo "printing working directory - $(pwd)"
echo "node version - $(node -v)"
echo "aws cli version - $(aws --version)"
echo "sls version - $(npm run sls-version)"
# deploy:
# needs: build
# runs-on: ubuntu-latest
# steps:
# - name: Git clone the repository
# uses: actions/checkout@v4
#
# - name: ⎔ Setup node
# uses: actions/setup-node@v4
# with:
# node-version: 18
#
# - name: Install dependencies
# working-directory: ./deployment-with-github-actions
# run: npm ci
#
# - name: configure aws credentials
# uses: aws-actions/configure-aws-credentials@v4
# with:
# mask-aws-account-id: true
# role-to-assume: ${{ secrets.AWS_GITHUB_ACTIONS_ROLE_ARN }}
# role-session-name: github-action-sls-examples
# aws-region: ${{ env.AWS_REGION }}
#
# - name: versions
# working-directory: ./deployment-with-github-actions
# run: |
# pwd
# node -v
# aws --version
#
# - name: deploy
# working-directory: ./deployment-with-github-actions
# run: npm run deploy:dev
- name: deploy
run: npm run deploy:dev
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

A collection of example projects built with Serverless framework on AWS.

| Example | Description | Used Services |
| :------------------------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------- |
| [dynamodb-streams](/dynamodb-streams) | This example reimplements AWS developer guide [tutorial](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.Lambda.Tutorial.html) (`Process New Items with DynamoDB Streams and Lambda`) through the Serverless Framework. | Lambda, DynamoDB (with stream enabled), and SNS |
| [secrets-manager](/secrets-manager) | Demonstrates how to access Secrets Manager in a Lambda function using the `aws-sdk` and the `AWS Parameters and Secrets Lambda Extension` | Lambda and Secrets Manager |
| [event-bus-via-sns](/event-bus-via-sns) | Event Bus pattern in Serverless architectures using SNS, SQS, and Lambda | SNS, SQS, and Lambda |
| [attr-based-access-ctrl](/attr-based-access-ctrl) | A full-stack application demonstrating the implementation of [attribute-based access control](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction_attribute-based-access-control.html) (ABAC) | Cognito (User pool & Identity pool), Lambda, IAM, S3, and API Gateway |
| Example | Description | Used Services |
| :---------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------- |
| [dynamodb-streams](/dynamodb-streams) | This example reimplements AWS developer guide [tutorial](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.Lambda.Tutorial.html) (`Process New Items with DynamoDB Streams and Lambda`) through the Serverless Framework. | Lambda, DynamoDB (with stream enabled), and SNS |
| [secrets-manager](/secrets-manager) | Demonstrates how to access Secrets Manager in a Lambda function using the `aws-sdk` and the `AWS Parameters and Secrets Lambda Extension` | Lambda and Secrets Manager |
| [event-bus-via-sns](/event-bus-via-sns) | Event Bus pattern in Serverless architectures using SNS, SQS, and Lambda | SNS, SQS, and Lambda |
| [attr-based-access-ctrl](/attr-based-access-ctrl) | A full-stack application demonstrating the implementation of [attribute-based access control](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction_attribute-based-access-control.html) (ABAC) | Cognito (User pool & Identity pool), Lambda, IAM, S3, and API Gateway |
| [deployment-with-github-actions](/deployment-with-github-actions) | Demonstrates how to securely deploy an application to AWS using GitHub Actions | IAM (Roles and OIDC provider) and GitHub Actions |

### Credits

Expand Down
6 changes: 6 additions & 0 deletions deployment-with-github-actions/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# package directories
node_modules
jspm_packages

# Serverless directories
.serverless
18 changes: 18 additions & 0 deletions deployment-with-github-actions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# deployment-with-github-actions

This example project demonstrates how to securely deploy an application to AWS using GitHub Actions.
It uses [OpenID Connect (OIDC)](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect) for secure authentication with AWS.
This eliminates the need to store AWS credentials as long-lived GitHub secrets.

## Goals

- Build and run tests whenever a pull request that includes changes to this example project. [Workflow file: [build-test.yml](../.github/workflows/build-test.yml)]
- Manually deploy one of the example projects to `development` environment on AWS. [Workflow file: [deploy-to-dev-env.yml](../.github/workflows/deploy-to-dev-env.yml)]

## Prerequisites

- Add the GitHub OIDC provider to IAM,

## Setup

## Deployment
9 changes: 9 additions & 0 deletions deployment-with-github-actions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const handler = async (event) => {
return {
statusCode: 200,
body: JSON.stringify({ message: 'Deployed with GitHub Actions!!' }),
headers: {
'content-type': 'application/json',
},
};
}
36 changes: 36 additions & 0 deletions deployment-with-github-actions/infra/resources.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
GithubActionDeploymentRole:
Type: AWS::IAM::Role
Properties:
RoleName: github-action-deployment-role-${self:provider.stage}
MaxSessionDuration: 3600 # 1 hour
Description: This role will be used to deploy resources through Github Actions

# The trust policy that is associated with this role. Trust policies define which entities can assume the role.
# https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp_oidc.html#idp_oidc_Create_GitHub
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Federated:
# This is the ARN of the GitHub OIDC provider, which has been manually added to the AWS Identity Provider.
# https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html
- arn:aws:iam::${aws:accountId}:oidc-provider/token.actions.githubusercontent.com
Action:
- sts:AssumeRoleWithWebIdentity
Condition:
StringLike:
# Permits only the specified repository in the organization to assume this role.
# The wildcard is used to allow any branch within the repository to assume this role.
token.actions.githubusercontent.com:sub: !Sub repo:${self:custom.GithubRepoOwner}/${self:custom.GithubRepoName}:*
StringEquals:
token.actions.githubusercontent.com:aud: sts.amazonaws.com

# The permissions that are granted to the role.
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AdministratorAccess # AWS managed policy

Outputs:
GithubActionDeploymentRoleARN:
Value: !GetAtt GithubActionDeploymentRole.Arn
Description: ARN of the Github Action Deployment Role
Loading

0 comments on commit 34d24ec

Please sign in to comment.