Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit e3eb85c

Browse files
authored
greenfield infra code (#4687)
1 parent a949dc8 commit e3eb85c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+2872
-0
lines changed

.github/workflows/deploy.yaml

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
name: 'Deployment'
2+
on:
3+
workflow_dispatch:
4+
push:
5+
branches:
6+
- <change-me-to-main>
7+
pull_request:
8+
branches: [<change-me-to-main>]
9+
defaults:
10+
run:
11+
shell: bash
12+
13+
permissions:
14+
id-token: write
15+
contents: read
16+
17+
concurrency: ${{ github.head_ref || github.ref_name || github.run_id }}
18+
jobs:
19+
terraform:
20+
name: ${{matrix.runner}} - dev
21+
runs-on: ['${{ matrix.runner }}']
22+
strategy:
23+
max-parallel: 1
24+
matrix:
25+
include:
26+
- environment: dev
27+
runner: ubuntu-latest
28+
env:
29+
AWS_DEFAULT_REGION: us-east-1
30+
steps:
31+
- uses: actions/checkout@v2
32+
33+
- name: Configure AWS credentials
34+
uses: aws-actions/configure-aws-credentials@v1
35+
with:
36+
role-to-assume: ${{ secrets.OIDC_IAM_ROLE_ARN }}
37+
aws-region: us-east-1
38+
39+
- name: Login to Amazon ECR
40+
id: login-ecr
41+
uses: aws-actions/amazon-ecr-login@v1
42+
43+
- name: Build, tag, and push the web image to Amazon ECR
44+
id: build-web-image
45+
env:
46+
ECR_REGISTRY: ${{ secrets.ECR_REGISTRY }}
47+
ECR_REPOSITORY: ${{ secrets.WEB_ECR_REPOSITORY }}
48+
OKTA_DOMAIN: ${{ secrets.OKTA_DOMAIN }}
49+
TEALIUM_ENV: 'dev'
50+
LD_CLIENT_ID: ${{ secrets.LD_CLIENT_ID }}
51+
TEALIUM_TAG: ${{ secrets.TEALIUM_TAG }}
52+
API_URL: ${{ secrets.API_URL }}
53+
54+
run: |
55+
# Build a docker container and push it to ECR
56+
export IMAGE_TAG=$(git rev-parse --short "$GITHUB_SHA")
57+
docker build --quiet -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG --build-arg LD_CLIENT_ID=$LD_CLIENT_ID --build-arg TEALIUM_ENV=$TEALIUM_ENV --build-arg TEALIUM_TAG=TEALIUM_TAG --build-arg OKTA_DOMAIN=$OKTA_DOMAIN -f web/DockerfileECS .
58+
echo "Pushing image to ECR..."
59+
export WEB_IMAGE=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
60+
docker push $WEB_IMAGE
61+
echo "::set-output name=image::${WEB_IMAGE}"
62+
63+
- name: Build, tag, and push the api image to Amazon ECR
64+
id: build-api-image
65+
env:
66+
ECR_REGISTRY: ${{ secrets.ECR_REGISTRY }}
67+
ECR_REPOSITORY: ${{ secrets.API_ECR_REPOSITORY }}
68+
run: |
69+
# Build a docker container and push it to ECR
70+
export IMAGE_TAG=$(git rev-parse --short "$GITHUB_SHA")
71+
docker build --quiet -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -f api/DockerfileECS .
72+
echo "Pushing image to ECR..."
73+
export API_IMAGE=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
74+
docker push $API_IMAGE
75+
echo "::set-output name=image::${API_IMAGE}"
76+
77+
- uses: hashicorp/setup-terraform@v1
78+
with:
79+
terraform_wrapper: false
80+
- name: Terraform Init
81+
id: init
82+
working-directory: terraform/greenfield/ecs
83+
run: |
84+
rm -rf .terraform
85+
terraform init -backend-config=envs/dev/backend.tfvars -upgrade=true -no-color -input=false
86+
- name: Terraform Plan
87+
id: plan
88+
working-directory: terraform/greenfield/ecs
89+
run: |
90+
terraform plan -input=false -var-file=envs/dev/inputs.tfvars -var "web_image=$WEB_IMAGE" -var "aws_account=$AWS_ACCOUNT" -var "api_image=$API_IMAGE" -no-color
91+
env:
92+
AWS_ACCOUNT: ${{ secrets.AWS_ACCOUNT }}
93+
WEB_IMAGE: ${{steps.build-web-image.outputs.image}}
94+
API_IMAGE: ${{steps.build-api-image.outputs.image}}
95+
- name: Terraform Apply
96+
if: github.ref == 'refs/heads/gf-ecs'
97+
id: apply
98+
working-directory: terraform/greenfield/ecs
99+
run: |
100+
terraform apply -auto-approve -input=false -var-file=envs/dev/inputs.tfvars -var "aws_account=$AWS_ACCOUNT" -var "web_image=$WEB_IMAGE" -var "api_image=$API_IMAGE"
101+
env:
102+
AWS_ACCOUNT: ${{ secrets.AWS_ACCOUNT }}
103+
WEB_IMAGE: ${{steps.build-web-image.outputs.image}}
104+
API_IMAGE: ${{steps.build-api-image.outputs.image}}
105+
- name: Terraform destroy
106+
if: github.ref == 'refs/heads/destroy'
107+
id: destroy
108+
working-directory: terraform/greenfiel/ecs
109+
run: |
110+
terraform destroy -auto-approve -input=false -var-file=envs/dev/inputs.tfvars
111+
env:
112+
WEB_IMAGE: ${{steps.build-web-image.outputs.image}}
113+
API_IMAGE: ${{steps.build-api-image.outputs.image}}

.github/workflows/test.yaml

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
name: 'Deployment'
2+
on:
3+
workflow_dispatch:
4+
push:
5+
branches:
6+
- <change-me-to-main>
7+
pull_request:
8+
branches: [<change-me-to-main>]
9+
defaults:
10+
run:
11+
shell: bash
12+
13+
permissions:
14+
id-token: write
15+
contents: read
16+
17+
concurrency: ${{ github.head_ref || github.ref_name || github.run_id }}
18+
jobs:
19+
dependency_vulnerability_scan:
20+
runs-on: ubuntu-latest
21+
steps:
22+
- uses: actions/checkout@v3
23+
- uses: actions/setup-node@v3
24+
with:
25+
node-version: '16.19.1'
26+
# - name: save yarn package cache
27+
# continue-on-error: true
28+
# with:
29+
# id: cache-npm
30+
# uses: actions/cache@v3
31+
# # npm cache files are stored in `~/.npm` on Linux/macOS
32+
# path: ~/.cache/yarn
33+
# key: cms-eapd-yarn-packages-{{ checksum "yarn.lock" }}
34+
# restore-keys: |
35+
# ${{ runner.os }}-build-${{ cms-eapd-yarn-packages }}-
36+
# ${{ runner.os }}-build-
37+
# ${{ runner.os }}-
38+
- name: install dependencies
39+
continue-on-error: true
40+
run: yarn install --frozen-lockfile --cache-folder ~/.cache/yarn
41+
- name: setup nvm
42+
continue-on-error: true
43+
run: |
44+
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash
45+
export NVM_DIR="$HOME/.nvm"
46+
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
47+
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
48+
nvm install 16.19.1
49+
nvm alias default 16.19.1
50+
echo 'export NVM_DIR="$HOME/.nvm"' >> $GITHUB_ENV
51+
echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> $GITHUB_ENV
52+
53+
- name: dependency vulnerability scan
54+
continue-on-error: true
55+
run: yarn run audit
56+
- name: yaml test
57+
working-directory: ./web
58+
run: |
59+
yarn install --frozen-lockfile
60+
yarn add glob
61+
yarn add js-yaml
62+
node yaml-tests.js
63+
- name: backend_lint
64+
continue-on-error: true
65+
working-directory: ./api
66+
run: |
67+
npm install -g eslint
68+
yarn lint
69+
- name: frontend_lint
70+
continue-on-error: true
71+
working-directory: ./web
72+
run: |
73+
npm install -g eslint
74+
yarn lint

api/DockerfileECS

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
FROM node:16.19.1-bullseye-slim as builder
2+
3+
RUN mkdir /app
4+
WORKDIR /app
5+
6+
COPY package.json .
7+
COPY ./api/package.json ./api/package.json
8+
COPY yarn.lock .
9+
COPY common ./common
10+
11+
RUN chown -R node:node /app
12+
USER node:node
13+
14+
RUN yarn install --frozen-lockfile --non-interactive
15+
RUN npm rebuild
16+
17+
COPY api ./api
18+
19+
# ---
20+
21+
FROM node:16.19.1-bullseye-slim
22+
23+
USER node
24+
WORKDIR /home/node
25+
26+
COPY --from=builder --chown=node:node /app/package.json ./
27+
COPY --from=builder --chown=node:node /app/node_modules/ ./node_modules/
28+
COPY --from=builder --chown=node:node /app/common/ ./common/
29+
COPY --from=builder --chown=node:node /app/api/ ./api/
30+
31+
WORKDIR /home/node/api
32+
33+
CMD yarn run start

terraform/greenfield/.gitignore

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Local .terraform directories
2+
**/.terraform/*
3+
4+
# .tfstate files
5+
*.tfstate
6+
*.tfstate.*
7+
8+
# Crash log files
9+
crash.log
10+
11+
# Ignore any .tfvars files that are generated automatically for each Terraform run. Most
12+
# .tfvars files are managed as part of configuration and so should be included in
13+
# version control.
14+
#
15+
# example.tfvars
16+
17+
# Ignore override files as they are usually used to override resources locally and so
18+
# are not checked in
19+
override.tf
20+
override.tf.json
21+
*_override.tf
22+
*_override.tf.json
23+
24+
# Include override files you do wish to add to version control using negated pattern
25+
#
26+
# !example_override.tf
27+
28+
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
29+
# example: *tfplan*
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Local .terraform directories
2+
**/.terraform/*
3+
4+
# .tfstate files
5+
*.tfstate
6+
*.tfstate.*
7+
8+
# Crash log files
9+
crash.log
10+
11+
# Ignore any .tfvars files that are generated automatically for each Terraform run. Most
12+
# .tfvars files are managed as part of configuration and so should be included in
13+
# version control.
14+
#
15+
# example.tfvars
16+
17+
# Ignore override files as they are usually used to override resources locally and so
18+
# are not checked in
19+
override.tf
20+
override.tf.json
21+
*_override.tf
22+
*_override.tf.json
23+
24+
# Include override files you do wish to add to version control using negated pattern
25+
#
26+
# !example_override.tf
27+
28+
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
29+
# example: *tfplan*
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Terraform for GitHub OIDC
2+
3+
## Usage
4+
5+
This Terraform module is located in a sub-directory, since some users may wish
6+
to consume this module even if they don't need to set up self-hosted runners.
7+
Note that to refer to a sub-directory as a Terraform module source, you need to
8+
[include a double slash before the sub-directory](https://developer.hashicorp.com/terraform/language/modules/sources#modules-in-package-sub-directories).
9+
10+
```hcl
11+
module "github-actions-aws" {
12+
source = "modules//oidc/github" # double-slash denotes a sub-directory
13+
14+
subject_claim_filters = ["repo:{your GitHub org}/{your GitHub repo}:{GitHub ref}"]
15+
# audience_list = [] # optional, defaults to ["sts.amazonaws.com"]
16+
# thumbprint_list = [] # optional, defaults to ["6938fd4d98bab03faadb97b34396831e3780aea1"]
17+
# github_actions_permissions_policy_json_path = "" # optional, defaults to "github_actions_permission_policy.json"
18+
# add_read_only_access = bool # optional, defaults to false
19+
}
20+
```
21+
22+
## Permissions policy
23+
24+
This module assumes that the permissions policy for the IAM role will be named
25+
`github_actions_permission_policy.json` and located in the same folder as the
26+
root module (the path and filename are configurable via the
27+
`github_actions_permissions_policy_json_path` variable). An example policy:
28+
29+
```json
30+
{
31+
"Version": "2012-10-17",
32+
"Statement": [
33+
{
34+
"Action": ["securityhub:BatchImportFindings"],
35+
"Effect": "Allow",
36+
"Resource": "*"
37+
},
38+
{
39+
"Sid": "UpdateService",
40+
"Effect": "Allow",
41+
"Action": ["ecs:UpdateService"],
42+
"Resource": [
43+
"arn:aws:ecs:{your region}:{your account number}:service/{your self-hosted runner cluster name}/{your github runner service name}"
44+
]
45+
}
46+
]
47+
}
48+
```
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
region = "us-east-1"
3+
bucket = "eapd-tf-<replace_me_with_aws_account>"
4+
key = "bootstrap/dev/terraform.tfstate"

0 commit comments

Comments
 (0)