build #1019
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# build - github workflow | |
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json | |
# https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions | |
name: build | |
# name of GitHub event that triggers workflow | |
# https://help.github.com/en/actions/reference/events-that-trigger-workflows#watch-event-watch | |
on: | |
# trigger via webhook | |
# https://github.com/adamrushuk/devops-lab/blob/master/TriggerCustomAction.ps1#L28 | |
repository_dispatch: | |
types: [build] | |
# enable manual workflow | |
# https://docs.github.com/en/actions/configuring-and-managing-workflows/configuring-a-workflow#manually-running-a-workflow | |
workflow_dispatch: | |
inputs: {} | |
# permissions for oidc login | |
# https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect | |
permissions: | |
id-token: write # This is required for requesting the JWT | |
contents: read # This is required for actions/checkout | |
# global environment variables | |
# https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables | |
env: | |
# prefix: used for some globally unique name requirements | |
PREFIX: arshz | |
# debug | |
CI_DEBUG: true | |
# azure creds (used with OIDC auth) | |
ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }} | |
ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }} | |
ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }} | |
# other | |
# prod or staging. | |
# "" disables cert-manager annotations (use if you already have an existing TLS secret) | |
CERT_API_ENVIRONMENT: "" | |
DNS_RG_NAME: rg-dns | |
EMAIL_ADDRESS: certadmin@domain.com | |
ENABLE_TLS_INGRESS: true | |
FORCE_TEST_FAIL: false | |
K8S_TLS_SECRET_NAME: tls-secret | |
KEY_VAULT_CERT_NAME: wildcard-thehypepipe-co-uk | |
KEY_VAULT_NAME: kv-rush-aqy2 | |
KEY_VAULT_RESOURCE_GROUP_NAME: rg-keyvault-acmebot | |
# NOTE: "eastus" is cheaper than "uksouth" | |
LOCATION: eastus | |
NEXUS_USER_USERNAME: demo_user | |
ROOT_DOMAIN_NAME: thehypepipe.co.uk | |
# STORAGE_KEY: 'env var set by Get-StorageKey.ps1' | |
VELERO_ENABLED: true | |
WEAVE_SCOPE_ENABLED: false | |
# terraform | |
TF_IN_AUTOMATION: "true" | |
TF_INPUT: "false" | |
# https://developer.hashicorp.com/terraform/internals/debugging | |
TF_LOG: "ERROR" # TRACE, DEBUG, INFO, WARN or ERROR | |
TF_PLAN: "tfplan" | |
# https://github.com/hashicorp/terraform/releases | |
TF_VERSION: "1.6.6" | |
TF_WORKING_DIR: ./terraform | |
# azurerm provider oidc | |
# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/service_principal_oidc | |
# https://developer.hashicorp.com/terraform/language/settings/backends/azurerm#oidc_request_token | |
ARM_USE_OIDC: "true" | |
# Env var concatenation is currently not supported at Workflow or Job scope. See workaround below: | |
# https://github.community/t5/GitHub-Actions/How-can-we-concatenate-multiple-env-vars-at-workflow-and-job/td-p/48489 | |
jobs: | |
build-and-deploy: | |
# always pin versions | |
# view installed software: https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources | |
# https://github.com/actions/runner-images?tab=readme-ov-file#available-images | |
runs-on: ubuntu-22.04 | |
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idenvironment | |
environment: | |
name: dev | |
url: "https://argocd.${{ env.ROOT_DOMAIN_NAME }}" | |
# only run if owner triggered action | |
if: github.actor == github.event.repository.owner.login | |
steps: | |
# Checkout | |
# https://github.com/marketplace/actions/checkout | |
- uses: actions/checkout@v4 | |
# specify different branch | |
# NOT required as I've changed the default branch to develop | |
# with: | |
# ref: develop | |
# Init tasks - inc Env var concatenation | |
# https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#environment-files | |
- name: Init tasks - inc Env var concatenation (Workaround) | |
run: | | |
chmod -R +x ./scripts/ | |
echo "AKS_CLUSTER_NAME=${{ env.PREFIX }}-aks-001" >> $GITHUB_ENV | |
echo "AKS_RG_NAME=${{ env.PREFIX }}-rg-aks-dev-001" >> $GITHUB_ENV | |
echo "ARGOCD_FQDN=argocd.${{ env.ROOT_DOMAIN_NAME }}" >> $GITHUB_ENV | |
echo "DNS_DOMAIN_NAME=nexus.${{ env.ROOT_DOMAIN_NAME }}" >> $GITHUB_ENV | |
echo "DOCKER_FQDN=docker.${{ env.ROOT_DOMAIN_NAME }}" >> $GITHUB_ENV | |
echo "TERRAFORM_STORAGE_ACCOUNT=${{ env.PREFIX }}sttfstate${{ env.LOCATION }}001" >> $GITHUB_ENV | |
echo "TERRAFORM_STORAGE_CONTAINER=terraform" >> $GITHUB_ENV | |
echo "TERRAFORM_STORAGE_RG=${{ env.PREFIX }}-rg-tfstate-dev-001" >> $GITHUB_ENV | |
echo "VELERO_STORAGE_ACCOUNT=${{ env.PREFIX }}stbckuksouth001" >> $GITHUB_ENV | |
# Login | |
# https://github.com/Azure/login | |
- name: Login via OIDC to Azure Public Cloud (az cli and az powershell) | |
uses: azure/login@v1 | |
with: | |
client-id: ${{ secrets.ARM_CLIENT_ID }} | |
tenant-id: ${{ secrets.ARM_TENANT_ID }} | |
subscription-id: ${{ secrets.ARM_SUBSCRIPTION_ID }} | |
enable-AzPSSession: true | |
# This is required when developing after the initial build, and the AKS cluster may have been stopped | |
# Ensure AKS cluster is running, else timeouts will occur on k8s Terraform apply tasks | |
- name: Start AKS Cluster | |
continue-on-error: true | |
run: ./scripts/start_aks_cluster.sh | |
# Prereqs | |
- name: Create Storage Account for Terraform state | |
run: ./scripts/storage_create.sh | |
# TODO remove this step | |
# - name: Lookup Storage Key | |
# run: ./scripts/storage_key.sh | |
- name: Replace tokens in Terraform config files | |
run: pwsh -command "./scripts/Replace-Tokens.ps1" | |
env: | |
ARGOCD_ADMIN_PASSWORD: ${{ secrets.ARGOCD_ADMIN_PASSWORD }} | |
HELM_CHART_REPO_DEPLOY_PRIVATE_KEY: ${{ secrets.HELM_CHART_REPO_DEPLOY_PRIVATE_KEY }} | |
IFTTT_WEBHOOK_KEY: ${{ secrets.IFTTT_WEBHOOK_KEY }} | |
# Terraform | |
# https://github.com/hashicorp/setup-terraform | |
- uses: hashicorp/setup-terraform@v3 | |
with: | |
terraform_version: ${{ env.TF_VERSION }} | |
- name: Terraform Init / Validate | |
run: | | |
echo 'Running terraform init...' | |
terraform init \ | |
-backend-config="resource_group_name=$TERRAFORM_STORAGE_RG" \ | |
-backend-config="storage_account_name=$TERRAFORM_STORAGE_ACCOUNT" | |
# validate | |
echo 'Running terraform validate...' | |
terraform validate | |
working-directory: ${{ env.TF_WORKING_DIR }} | |
# https://github.com/aquasecurity/tfsec-action | |
- name: Run tfsec security scan | |
uses: aquasecurity/tfsec-action@v1.0.3 | |
with: | |
working_directory: ${{ env.TF_WORKING_DIR }} | |
soft_fail: true | |
# https://github.com/bridgecrewio/checkov-action | |
- name: Run Checkov security scan | |
id: checkov | |
uses: bridgecrewio/checkov-action@master | |
with: | |
directory: ${{ env.TF_WORKING_DIR }} | |
# check: CKV_AWS_1 # optional: run only a specific check_id. can be comma separated list | |
# optional: skip a specific check_id. can be comma separated list | |
skip_check: CKV2_AZURE_1,CKV_AZURE_4,CKV_AZURE_6,CKV2_AZURE_8,CKV2_AZURE_21,CKV_AZURE_33,CKV_AZURE_35,CKV_AZURE_117,CKV_AZURE_141 | |
quiet: true # optional: display only failed checks | |
soft_fail: true # optional: do not return an error code if there are failed checks | |
framework: terraform # optional: run only on a specific infrastructure {cloudformation,terraform,kubernetes,all} | |
output_format: sarif # optional: the output format, one of: cli, json, junitxml, github_failed_only, or sarif. Default: sarif | |
download_external_modules: true # optional: download external terraform modules from public git repositories and terraform registry | |
# log_level: DEBUG # optional: set log level. Default WARNING | |
# config_file: path/this_file | |
- name: 👀 Terraform Plan | |
id: plan | |
run: terraform plan -out=${{ env.TF_PLAN }} | |
working-directory: ${{ env.TF_WORKING_DIR }} | |
- name: 🚀 Terraform Apply | |
run: ./scripts/terraform_apply.sh | |
# only apply if changes are present | |
# https://www.terraform.io/docs/commands/plan.html#detailed-exitcode | |
# if: steps.plan.outputs.exitcode == 2 | |
env: | |
TF_PLAN: ${{ env.TF_PLAN }} | |
# Kubernetes | |
- name: Deploy kubernetes manifests | |
run: ./scripts/k8s_manifests_apply.sh | |
- name: Wait for resources to be "Ready" | |
run: ./scripts/wait.sh | |
# Ansible | |
- name: Run Ansible playbook | |
run: ./scripts/ansible.sh | |
env: | |
NEXUS_ADMIN_PASSWORD: ${{ secrets.NEXUS_ADMIN_PASSWORD }} | |
NEXUS_USER_PASSWORD: ${{ secrets.NEXUS_USER_PASSWORD }} | |
# Docker | |
# https://github.com/Azure/docker-login | |
- name: Docker repo login | |
uses: Azure/docker-login@v1 | |
with: | |
login-server: ${{ env.DOCKER_FQDN }} | |
username: ${{ env.NEXUS_USER_USERNAME }} | |
password: ${{ secrets.NEXUS_USER_PASSWORD }} | |
- name: Push images to Docker repo | |
run: ./scripts/push_docker_images.sh | |
# TODO: Remove once issue has been fixed | |
- name: Fix Function App version | |
run: pwsh -command "./scripts/Fix-FunctionApp.ps1" | |
env: | |
FUNCTION_APP_NAME: "${{ env.PREFIX }}-funcapp" | |
FUNCTION_APP_RG: "${{ env.PREFIX }}-rg-aks-dev-001" | |
# Pester tests | |
- name: 🧪 Run Pester tests | |
continue-on-error: true | |
run: pwsh -command "./scripts/Start-Test.ps1" | |
# https://github.com/actions/upload-artifact | |
- name: Archive test artifacts | |
uses: actions/upload-artifact@v3 | |
with: | |
name: test-results | |
path: test/pester-test-results.xml | |
if: always() | |
# remove NuGet proxy repo so pester report step doesnt fail | |
- name: Unregister NuGet proxy repo | |
run: pwsh -command "Unregister-PSRepository -Name nuget.org-proxy -Verbose" | |
# Shows at the bottom of a run: https://github.com/adamrushuk/devops-lab/runs/1035347513?check_suite_focus=true | |
# https://github.com/zyborg/pester-tests-report | |
# - name: Pester report | |
# uses: zyborg/pester-tests-report@v1 | |
# with: | |
# test_results_path: test/pester-test-results.xml | |
# report_name: pester_tests | |
# report_title: Pester Tests | |
# github_token: ${{ secrets.GITHUB_TOKEN }} | |
# - uses: dorny/test-reporter@v1.6.0 | |
# with: | |
# # artifact: test-results # artifact name | |
# name: Pester Tests Results # Name of the check run which will be created | |
# path: 'test/pester-test-results.xml' # Path to test results (inside artifact .zip) | |
# reporter: java-junit # Format of test results | |
# Notify | |
- name: Notify slack | |
continue-on-error: true | |
env: | |
SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} | |
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} | |
run: ./scripts/send_slack_message.sh "[devops-lab] Build complete" | |
# used for any windows-only tasks | |
test-windows: | |
needs: build-and-deploy | |
# https://github.com/actions/runner-images?tab=readme-ov-file#available-images | |
runs-on: windows-2022 | |
# https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idenvironment | |
environment: | |
name: dev | |
# only run if owner triggered action | |
if: github.actor == github.event.repository.owner.login | |
steps: | |
# Checkout | |
- uses: actions/checkout@v4 | |
# Init tasks - inc Env var concatenation | |
# https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#environment-files | |
- name: Init tasks - inc Env var concatenation (Workaround) | |
# * NOTE: different syntax required for Windows agents | |
run: | | |
echo "AKS_RG_NAME=${{ env.PREFIX }}-rg-aks-dev-001" | Out-File -Append -Encoding utf8 -FilePath "$env:GITHUB_ENV" | |
echo "AKS_CLUSTER_NAME=${{ env.PREFIX }}-aks-001" | Out-File -Append -Encoding utf8 -FilePath "$env:GITHUB_ENV" | |
echo "DNS_DOMAIN_NAME=nexus.${{ env.ROOT_DOMAIN_NAME }}" | Out-File -Append -Encoding utf8 -FilePath "$env:GITHUB_ENV" | |
# Login | |
# https://github.com/Azure/login | |
- name: Login via OIDC to Azure Public Cloud (az cli and az powershell) | |
uses: azure/login@v1 | |
with: | |
client-id: ${{ secrets.ARM_CLIENT_ID }} | |
tenant-id: ${{ secrets.ARM_TENANT_ID }} | |
subscription-id: ${{ secrets.ARM_SUBSCRIPTION_ID }} | |
enable-AzPSSession: true | |
# Chocolatey | |
- name: Test Nexus Chocolatey proxy repo | |
run: | | |
choco install velero --source "https://${{ env.DNS_DOMAIN_NAME }}/repository/chocolatey-proxy/" | |
# Velero CLI | |
- name: Test Velero CLI | |
# NOTE: Some functions cast values to a string to perform comparisons | |
# https://docs.github.com/en/free-pro-team@latest/actions/reference/context-and-expression-syntax-for-github-actions#functions | |
# ! WARNING: only single quotes work for boolean comparison | |
if: env.VELERO_ENABLED == 'true' | |
run: | | |
az aks get-credentials --resource-group "${{ env.AKS_RG_NAME }}" --name "${{ env.AKS_CLUSTER_NAME }}" --overwrite-existing --admin | |
echo "`nVelero version info:" | |
velero version || true | |
echo "`nVelero backup location info:" | |
velero backup-location get | |
echo "`nVelero backup info:" | |
velero backup get |