Skip to content
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- name: Lints Markdown files
uses: DavidAnson/markdownlint-cli2-action@v20
with:
globs: '**/*.md'
globs: "**/*.md"
- name: Set up Python ${{ env.python_version }}
uses: actions/setup-python@v5
with:
Expand Down
133 changes: 133 additions & 0 deletions .github/workflows/reusable-terraform-apply.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
name: Reusable workflow to apply Terraform

on:
workflow_call:
inputs:
environment:
description: "GitHub environment"
type: string
required: true
working-directory:
description: "Working directory"
type: string
required: true
tfbackend-project:
description: "Terraform backend project"
type: string
required: true
custom-commands:
description: "Optional shell commands to run before apply"
type: string
required: false
default: ""
terraform-var-flags:
description: 'Extra -var "key=value" flags (space separated)'
type: string
required: false
default: ""
workflow-parts-version:
description: "GitHub workflow parts version (branch/tag/SHA)"
type: string
required: false
default: "main"
secrets:
atlas-publickey:
description: "Atlas public key"
required: true
atlas-privatekey:
description: "Atlas private key"
required: true
atlas-groupid:
description: "Atlas group IP"
required: true
tfbackend-connstring:
description: "Terraform backend connection string"
required: true
tfbackend-dbname:
description: "Terraform backend database name"
required: true
tfbackend-tenant:
description: "Terraform backend tenant"
required: true
tfbackend-username:
description: "Terraform backend user name"
required: true
tfbackend-userpwd:
description: "Terraform backend user password"
required: true
additional-vars:
description: "Additional variables"
required: false

jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
defaults:
run:
working-directory: ${{ inputs.working-directory }}
services:
tfbackend:
image: devprofr/terraform-backend-mongodb:latest
env:
Application__IsHttpsRedirectionEnabled: false
ConnectionStrings__MongoDb: ${{ secrets.tfbackend-connstring }}
MongoDb__ConnectionStringName: MongoDb
MongoDb__DatabaseName: ${{ secrets.tfbackend-dbname }}
ports:
- 8080:8080
steps:
- name: Clone repository
uses: actions/checkout@v6
- name: Checkout workflow parts
uses: actions/checkout@v6
with:
repository: devpro/github-workflow-parts
ref: ${{ inputs.workflow-parts-version }}
path: workflow-parts
- name: Add runner ID to MongoDB Atlas
# uses: devpro/github-workflow-parts/actions/mongodb-atlas/add-runner-ip@... cannot be used with an input parameter in it (must be static) so checkout is mandatory
uses: ./workflow-parts/actions/mongodb-atlas/add-runner-ip
with:
atlas-publickey: ${{ secrets.atlas-publickey }}
atlas-privatekey: ${{ secrets.atlas-privatekey }}
atlas-groupid: ${{ secrets.atlas-groupid }}
- name: Set additional variables
run: |
if [[ -z "${{ secrets.additional-vars }}" ]]; then
echo "No additional-vars bundle provided - skipping."
else
echo "${{ secrets.additional-vars }}" | while IFS='=' read -r key val; do
if [[ -n "$val" ]]; then
echo "::add-mask::$val"
fi
done
echo "${{ secrets.additional-vars }}" >> "$GITHUB_ENV"
fi
- name: Run optional custom commands
if: ${{ inputs.custom-commands != '' }}
run: |
${{ inputs.custom-commands }}
- name: Cache Terraform plugins
uses: actions/cache@v5
with:
path: |
~/.terraform.d/plugin-cache
key: terraform-${{ hashFiles('**/.terraform.lock.hcl') }}
- name: Install terraform
uses: hashicorp/setup-terraform@v3
- name: Terraform init
run: terraform init
- name: Terraform validate
run: terraform validate
- name: Terraform plan
run: terraform plan -out=plan.tfplan ${{ inputs.terraform-var-flags }}
- name: Terraform apply
run: terraform apply -auto-approve plan.tfplan ${{ inputs.terraform-var-flags }}
env:
TF_HTTP_ADDRESS: "http://localhost:8080/${{ secrets.tfbackend-tenant }}/state/${{ inputs.tfbackend-project }}"
TF_HTTP_LOCK_ADDRESS: "http://localhost:8080/${{ secrets.tfbackend-tenant }}/state/${{ inputs.tfbackend-project }}/lock"
TF_HTTP_UNLOCK_ADDRESS: "http://localhost:8080/${{ secrets.tfbackend-tenant }}/state/${{ inputs.tfbackend-project }}/lock"
TF_HTTP_USERNAME: "${{ secrets.tfbackend-username }}"
TF_HTTP_PASSWORD: "${{ secrets.tfbackend-userpwd }}"
89 changes: 89 additions & 0 deletions .github/workflows/reusable-terraform-validate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: Reusable workflow to validate Terraform project

on:
workflow_call:
inputs:
job-name:
description: "Job name"
required: false
type: string
default: "Validate"
working-directory:
description: "Working directory"
required: false
type: string
default: "."

jobs:
terraform-validate:
name: ${{ inputs.job-name }}
runs-on: ubuntu-latest
defaults:
run:
working-directory: ${{ inputs.working-directory }}
steps:
- name: Clone repository
uses: actions/checkout@v6
- name: Cache Terraform plugins
uses: actions/cache@v5
with:
path: |
~/.terraform.d/plugin-cache
key: terraform-${{ hashFiles('**/.terraform.lock.hcl') }}
- name: Install terraform
uses: hashicorp/setup-terraform@v3
- name: Check Terraform format
run: terraform fmt -recursive -check
- name: Terraform Init
run: terraform init -backend=false
- name: Terraform Validate
run: terraform validate
# Checkov is a static code analysis tool for infrastructure as code (IaC) and also a software composition analysis (SCA) tool for images and open source packages (ref. https://github.com/bridgecrewio/checkov)
- name: Run Checkov
uses: bridgecrewio/checkov-action@v12
with:
soft_fail: true
output_format: cli,sarif
output_file_path: console,results.sarif
# quiet: true
# directory: .
# framework: terraform kubernetes helm
# needs GitHub code security > code scanning, not available on private repos
# - name: Upload SARIF file
# uses: github/codeql-action/upload-sarif@v3
# if: success() || failure()
# with:
# sarif_file: results.sarif
- name: Upload SARIF as artifact
uses: actions/upload-artifact@v6
if: always()
with:
name: checkov-sarif-results
path: results.sarif
retention-days: 14
# TFLint is a pluggable terraform linter (ref. https://github.com/terraform-linters/tflint)
- name: Cache TFLint plugins
uses: actions/cache@v5
with:
path: ~/.tflint.d/plugins
key: tflint-${{ hashFiles('**/.tflint.hcl') }}
- name: Setup TFLint
uses: terraform-linters/setup-tflint@v6
with:
tflint_version: v0.60.0 # ref. https://github.com/terraform-linters/tflint/pkgs/container/tflint
- name: Initialize TFLint
run: tflint --init --recursive
env:
GITHUB_TOKEN: ${{ github.token }} # ref. https://github.com/terraform-linters/tflint/blob/master/docs/user-guide/plugins.md#avoiding-rate-limiting
- name: Run TFLint
run: tflint --recursive --format compact
- name: Run Trivy IaC scan
uses: aquasecurity/trivy-action@0.33.1
with:
scan-type: "config"
format: "sarif"
output: "trivy-results.sarif"
ignore-unfixed: true
severity: "HIGH,CRITICAL"
env:
TF_IN_AUTOMATION: true
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,15 @@ name: Add GitHub Actions runner public IP to MongoDB Atlas
description: Update project IP access list (temporary)

inputs:
atlas_publickey:
atlas-publickey:
description: MongoDB public key
required: true
atlas_privatekey:
atlas-privatekey:
description: MongoDB private key
required: true
atlas_groupid:
atlas-groupid:
description: MongoDB group ID
required: true
github_runid:
description: GitHub run ID
required: true

runs:
using: "composite"
Expand All @@ -36,11 +33,11 @@ runs:
PAYLOAD="[{\"ipAddress\": \"$RUNNER_IP\", \"comment\": \"GH Actions temp - run ${{ github.run_id }}\", \"deleteAfterDate\": \"$DELETE_AFTER\"}]"

# calls Atlas API v2 to add the entry (uses digest Auth via curl)
RESPONSE=$(curl -s -w "%{http_code}" --user "${{inputs.atlas_publickey}}:${{inputs.atlas_privatekey}}" --digest \
RESPONSE=$(curl -s -w "%{http_code}" --user "${{ inputs.atlas-publickey }}:${{ inputs.atlas-privatekey }}" --digest \
-H "Accept: application/vnd.atlas.2023-01-01+json" \
-H "Content-Type: application/json" \
--data "$PAYLOAD" \
"https://cloud.mongodb.com/api/atlas/v2/groups/${{inputs.atlas_groupid}}/accessList")
"https://cloud.mongodb.com/api/atlas/v2/groups/${{ inputs.atlas-groupid }}/accessList")

HTTP_CODE=${RESPONSE: -3}

Expand Down
Loading