Skip to content

Commit

Permalink
feat: updated ci that is faster and better (#684)
Browse files Browse the repository at this point in the history
### Summary
This PR updates the code that is generated to `fogg_ci.yml` for github actions. It has been tested in a few iterations in [shared-infra](https://github.com/chanzuckerberg/shared-infra/blob/main/.github/workflows/new_ci.yml). The following new features include:

* auto fix terraform-docs and commit back to branch
* auto fix fogg apply and commit back to branch
* auto fix terraform fmt and commit back to branch
* caching fogg apply using action/cache
* only doing the above on envs/accounts/modules that have changed files
* no more code generation; changed directories are collect dynamically and run in parallel
* fewer bash scripting and more github actions (such as terraform-docs)
* no more SSH keys in secrets; all code is downloaded using a github app credentials (github app's have finer grain access controls and are easier to manage at an org-wide level)
* no more random ordering of steps based on `fogg apply`. should be the same `fogg_ci.yml` every time

### Test Plan
* Testing on shared-infra

### References

In testing on shared-infra, this has been [about 4 minutes faster](chanzuckerberg/shared-infra#5675) than the previous iteration, per PR commit.
  • Loading branch information
jakeyheath authored Jul 18, 2022
1 parent 2b3afd8 commit 3e78e17
Show file tree
Hide file tree
Showing 3 changed files with 261 additions and 433 deletions.
161 changes: 91 additions & 70 deletions templates/templates/.github/workflows/fogg_ci.yml.tmpl
Original file line number Diff line number Diff line change
@@ -1,86 +1,107 @@
# Auto-generated by fogg. Do not edit
# Make improvements in fogg, so that everyone can benefit.
{{- $githubActionsCI := . }}

on: push

{{- if $githubActionsCI.Env }}
env:
{{- range $k, $v := .Env }}
{{ $k }}: {{ $v }}
{{- end }}
{{- end }}

# cancel old runs if we push new commits to the same ref
concurrency:
group: {{ "${{ github.ref }}" }}
cancel-in-progress: true
group: {{`${{ github.ref }}`}}

jobs:
{{- range $idx, $testBucket := $githubActionsCI.TestBuckets }}
terraform_{{$idx}}:
fogg-apply:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python 3.x
uses: actions/setup-python@v1
- name: Generate token
id: generate_token
uses: chanzuckerberg/github-app-token@v1.1.4
with:
python-version: '3.6'
- run: |
mkdir /tmp/terraform-docs
cd /tmp/terraform-docs

# https://terraform-docs.io/user-guide/installation/#pre-compiled-binary
curl -sSLo ./terraform-docs.tar.gz https://github.com/terraform-docs/terraform-docs/releases/download/v0.16.0/terraform-docs-v0.16.0-linux-amd64.tar.gz
tar -xzf terraform-docs.tar.gz
chmod +x terraform-docs
echo "$PWD" >> $GITHUB_PATH
- run: python3 -m venv venv
- run: . venv/bin/activate
- run: pip install awscli --upgrade --user
- run: aws --version
{{- if not (eq (len $githubActionsCI.SSHKeySecrets) 0) }}
- name: Install SSH key
uses: webfactory/[email protected]
app_id: {{`${{ secrets.CZI_GITHUB_HELPER_APP_ID }}`}}
private_key: {{`${{ secrets.CZI_GITHUB_HELPER_PK }}`}}
- uses: actions/checkout@v3
with:
token: {{`${{ steps.generate_token.outputs.token }}`}}
- name: Cache Fogg
id: cache-fogg
uses: actions/cache@v3
with:
path: ~/.fogg/cache
key: fogg-cache-{{`${{ hashFiles('**/.fogg-version') }}`}}
- run: make setup
- run: .fogg/bin/fogg apply
env:
FOGG_GITHUBAPPTOKEN: {{`${{ steps.generate_token.outputs.token }}`}}
- uses: EndBug/add-and-commit@v9
with:
ssh-private-key: |
{{ range $idx, $secret := $githubActionsCI.SSHKeySecrets }}
{{`${{`}} secrets.{{ $secret }} {{`}}`}}
{{ end }}
{{ end }}
- run: FOGG_VERSION="v{{ $githubActionsCI.FoggVersion }}" make setup
- run: |
.fogg/bin/fogg apply
if [ "$(git status --porcelain)" != "" ]; then
echo "git tree is dirty after running fogg apply"
echo "ensure you run fogg apply on your branch"
git status
exit 1
fi
{{- if not (eq (len $githubActionsCI.AWSProfiles) 0) }}
- run: aws configure set aws_access_key_id {{`${{`}} secrets.IDACCT_AWS_ACCESS_KEY_ID {{`}}`}} --profile _idacct
- run: aws configure set aws_secret_access_key {{`${{`}} secrets.IDACCT_AWS_SECRET_ACCESS_KEY {{`}}`}} --profile _idacct
- run: aws --profile _idacct sts get-caller-identity
{{- end }}
{{- range $profileName, $profile := $githubActionsCI.AWSProfiles }}
- run: aws configure set profile.{{ $profileName }}.role_arn arn:aws:iam::{{ $profile.AccountID }}:role/{{ $profile.RoleName}}
- run: aws configure set profile.{{ $profileName }}.source_profile _idacct
- run: aws --profile {{ $profileName }} sts get-caller-identity
{{- end }}
# we only run the following if there are changes in the terraform/* directory
# to optimize CI time
# can use this filter to decide whether or not to run linters or tests.
- uses: dorny/[email protected]
add: -A
message: |
commit from fogg_ci -- ran fogg apply and pushed
find-changed-dirs:
runs-on: ubuntu-latest
outputs:
allChanges: {{`${{ steps.changedDirs.outputs.allChanges }}`}}
steps:
- uses: actions/checkout@v3
- uses: dorny/[email protected]
id: filter
with:
initial-fetch-depth: '1'
list-files: json
filters: |
terraform:
- 'terraform/**'
{{- range $component := $testBucket }}
- name: {{ $component.Dir }}
if: {{ "${{ steps.filter.outputs.terraform == 'true' }}" }}
changed:
- added|modified: 'terraform/**'
- uses: actions/github-script@v6
id: changedDirs
with:
script: |
const path = require("path")
const changedFiles = {{`${{ steps.filter.outputs.changed_files }}`}}
const changedDirs = changedFiles.map(f => path.dirname(f))
console.log(`Found the following changed dirs: ${JSON.stringify(changedDirs, null, 2)}\n OG: ${JSON.stringify(changedFiles, null, 2)} `)
const changedModules = [... new Set(changedDirs.filter(d => d.indexOf("modules") !== -1))]
const changedAccounts = [... new Set(changedDirs.filter(d => d.indexOf("accounts") !== -1 && d.split("/").length === 3))]
const changedEnvs = [... new Set(changedDirs.filter(d => d.indexOf("envs") !== -1 && d.split("/").length === 4))]
const allChanges = [...changedAccounts,...changedEnvs, ...changedModules]
console.log(`changedModules: ${JSON.stringify(changedModules)}`)
console.log(`changedAccounts: ${JSON.stringify(changedAccounts)}`)
console.log(`changedEnvs: ${JSON.stringify(changedEnvs)}`)
core.setOutput("allChanges", allChanges)
lint-changed-dirs:
runs-on: ubuntu-latest
needs: find-changed-dirs
strategy:
matrix:
tfmodule: {{`${{ fromJson(needs.find-changed-dirs.outputs.allChanges) }}`}}
if: {{`${{ needs.find-changed-dirs.outputs.allChanges != '[]' }}`}}
steps:
- name: Generate token
id: generate_token
uses: chanzuckerberg/[email protected]
with:
app_id: {{`${{ secrets.CZI_GITHUB_HELPER_APP_ID }}`}}
private_key: {{`${{ secrets.CZI_GITHUB_HELPER_PK }}`}}
- uses: actions/checkout@v3
with:
token: {{`${{ steps.generate_token.outputs.token }}`}}
- name: fix terraform docs
uses: terraform-docs/[email protected]
if: contains(matrix.tfmodule, 'modules') # only need to make docs on the modules
with:
working-dir: {{`${{matrix.tfmodule}}`}}
git-push: "true"
template: <!-- START -->\n{{`{{ .Content }}`}}\n<!-- END -->
ref: {{`${{ github.event.pull_request.head.ref }}`}}
git-commit-message: |
commit from fogg_ci -- ran terraform-docs and pushed
- name: fix terraform fmt
run: |
cd {{`${{matrix.tfmodule}}`}}
make fmt
- uses: EndBug/add-and-commit@v9
with:
add: -A
message: |
commit from fogg_ci -- ran terraform fmt and pushed
- name: tflint
run: |
cd {{ $component.Dir }}
make {{ $component.Command }}
{{- end }}
{{- end }}
make setup
cd {{`${{matrix.tfmodule}}`}}
${GITHUB_WORKSPACE}/.fogg/bin/tflint
Loading

0 comments on commit 3e78e17

Please sign in to comment.