Skip to content

Commit

Permalink
[DEVOPS-263] Add ephemeral deployments workflow (#61)
Browse files Browse the repository at this point in the history
<details open>
<summary><a href="https://amuniversal.atlassian.net/browse/DEVOPS-263"
title="DEVOPS-263" target="_blank">DEVOPS-263</a></summary>
  <br />
  <table>
    <tr>
      <th>Summary</th>
<td>Create workflow for deploying Azure Container Instances for
ephemeral deployments</td>
    </tr>
    <tr>
      <th>Type</th>
      <td>
<img alt="Story"
src="https://amuniversal.atlassian.net/images/icons/issuetypes/story.png"
/>
        Story
      </td>
    </tr>
    <tr>
      <th>Status</th>
      <td>In Progress</td>
    </tr>
    <tr>
      <th>Points</th>
      <td>N/A</td>
    </tr>
    <tr>
      <th>Labels</th>
      <td>-</td>
    </tr>
  </table>
</details>
<!--
do not remove this marker as it will break action-jira-linter's
functionality.
  added_by_jira_lint
-->
---

<!--
We appreciate the effort for this pull request but before that please
make sure you read the contribution guidelines, then fill out the blanks
below.

Please format the PR title appropriately based on the type of change:
  [<issue>]: <description>
Where <issue> is the related Jira Issue Key.
-->

## Description

- Add ephemeral deployments workflow

## Related Issues

<!-- List any related Jira issues here -->

- Jira Issue: DEVOPS-263
- Testing environment: [![Ephemeral
Deployments](https://github.com/Andrews-McMeel-Universal/puzzle-society_ui/actions/workflows/ephemeral-deployment.yml/badge.svg?branch=research%2FPUZSOC-5782%2Fephemeral-deployments)](https://github.com/Andrews-McMeel-Universal/puzzle-society_ui/actions/workflows/ephemeral-deployment.yml)
  • Loading branch information
ebronson68 authored Oct 9, 2023
1 parent 8e80049 commit 754a51c
Showing 1 changed file with 227 additions and 0 deletions.
227 changes: 227 additions & 0 deletions .github/workflows/ephemeral-deploy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
name: Ephemeral Deployment

on:
workflow_call:
inputs:
environment:
required: true
type: string
description: "Deploy Environment. This is used to pull in and set the github environment. Can be development, staging, or production."
environmentKeyVault:
required: false
type: string
description: "AKS Key vault."
repositoryName:
required: false
type: string
description: "GitHub Repository Name."
default: "${{ github.event.repository.name }}"
clusterResourceGroup:
required: false
type: string
description: "Azure Resource Group."
default: "AMU_EphemeralDeployments_RG"
dockerFilePath:
required: false
type: string
description: "Relative path to Dockerfile."
default: "."
dockerImageName:
required: false
type: string
description: "Docker image name."
default: "${{ github.event.repository.name }}"
azureResourceLocation:
required: false
type: string
description: "Location of resources in Azure"
default: "centralus"
secrets:
azureCredentials:
required: true
registryHostName:
required: true
registryUserName:
required: true
registryPassword:
required: true
githubPAT:
required: true

env:
githubPrBranch: ${{ github.head_ref }}
githubPrTitle: ${{ github.event.pull_request.title }}
githubPrDescription: ${{ github.event.pull_request.body }}

jobs:
prepare:
name: Preparation Step
if: ${{ github.event.action == 'labeled' && github.event.label.name == 'ephemeral-deployment' || github.event_name == 'pull_request' && github.event.action != 'labeled' && contains(github.event.pull_request.labels.*.name, 'ephemeral-deployment') }}
runs-on: ubuntu-latest
steps:
- name: Retrieve Jira ticket ID
id: jira-ticket
run: |
PR_BRANCH=$(echo "${{ env.githubPrBranch }}" | grep -Eo "\b[A-Z][A-Z0-9_]+-[1-9][0-9]*")
PR_TITLE=$(echo "${{ env.githubPrTitle }}" | grep -Eo "\b[A-Z][A-Z0-9_]+-[1-9][0-9]*")
PR_DESC=$(echo "${{ env.githubPrDescription }}" | grep -Eo "\b[A-Z][A-Z0-9_]+-[1-9][0-9]*")
for var in ${PR_BRANCH} ${PR_TITLE} ${PR_DESC}; do JIRA_TICKET_ID=$(echo $var | grep -E ".") && break ; done
JIRA_TICKET_ID_LC=$(echo "${JIRA_TICKET_ID}" | tr '[:upper:]' '[:lower:]')
echo "jiraTicketIdLc=${JIRA_TICKET_ID_LC}" >> $GITHUB_OUTPUT
echo "jiraTicketId=${JIRA_TICKET_ID}" >> $GITHUB_OUTPUT
- name: Fix repository name
id: repository-name
run: |
REPOSITORY_NAME=$(echo "${{ inputs.repositoryName }}" | tr '[:upper:]' '[:lower:]' | tr "_" "-")
echo "repositoryName=${REPOSITORY_NAME}" >> $GITHUB_OUTPUT
outputs:
jiraTicketId: ${{ steps.jira-ticket.outputs.jiraTicketId }}
jiraTicketIdLc: ${{ steps.jira-ticket.outputs.jiraTicketIdLc }}
repositoryName: ${{ steps.repository-name.outputs.repositoryName }}

deploy:
name: Deploy Azure Container Instance
if: ${{ github.event.action == 'labeled' && github.event.label.name == 'ephemeral-deployment' || github.event_name == 'pull_request' && github.event.action != 'closed' && github.event.action != 'labeled' && contains(github.event.pull_request.labels.*.name, 'ephemeral-deployment') }}
needs: [prepare]
runs-on: ubuntu-latest
environment:
name: ${{ needs.prepare.outputs.jiraTicketId }}
url: ${{ steps.hostname.outputs.hostname }}
steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Generate .env file from Azure Key Vaults
uses: Andrews-McMeel-Universal/get-envs@v1
with:
environment: ${{ inputs.environment }}
azurecredentials: ${{ secrets.azureCredentials }}
environmentKeyVault: ${{ inputs.environmentKeyVault }}

- name: Set environment variables
id: env-vars
shell: bash
run: |
ENVIRONMENT_VARIABLES=$(tr "\n" " " < .env)
TARGET_PORT=$(find . -iname "values.yaml" -exec grep "targetPort: " {} \; | awk -F ': ' '{print $2}' | uniq)
echo "targetPort=${TARGET_PORT}" >> $GITHUB_OUTPUT
echo "environmentVariables=${ENVIRONMENT_VARIABLES}" >> $GITHUB_OUTPUT
- name: Generate build args from Azure Key Vaults
shell: bash
run: |
ENVIRONMENT="${{ inputs.environment }}"
REPOSITORY_NAME="${{ inputs.repositoryName }}"
ENV_KEYVAULT_NAME="${{ inputs.environmentKeyVault }}"
BUILDARG_PREDICATE="--build-arg"
# Check if searching for key vaults by repository name or otherwise, if key vault name argument is given
if [ -z "${ENV_KEYVAULT_NAME}" ]; then
# Search for key vault using tags
KEYVAULT_NAME=$(az keyvault list --query "[?tags.\"repository-name\" == '${REPOSITORY_NAME}' && tags.environment == '${ENVIRONMENT}'].name" --output tsv)
else
KEYVAULT_NAME="${ENV_KEYVAULT_NAME}"
fi
# Get key vault object
KEYVAULT=$(az keyvault list --query "[?name == '${KEYVAULT_NAME}']" )
# Check if key vault exists
if ! echo "${KEYVAULT}" | grep -Eq "\w"; then
echo -e "${RED}Invalid value provided for 'KeyVaultName'. Please confirm a Key Vault exists under the name specified. Value provided: ${KEYVAULT_NAME}"
exit 1
fi
KEYVAULT_NAME="${KEYVAULT_NAME// /}"
# Set secrets list
SECRETS=$(az keyvault secret list --vault-name "${KEYVAULT_NAME}" --query "[?contentType == 'BuildArg Env' || contentType == 'BuildArg'].name" --output tsv)
# Loop through secrets and add them to .env
if echo "${SECRETS}" | grep -Eq "\w"; then
while IFS= read -r SECRET; do
# Convert to upper case snake case and remove quotes
SECRET_NAME=$(echo "${SECRET}" | tr '[:upper:][:lower:]' '[:lower:][:upper:]' | tr "-" "_" | tr -d '"')
# Get secret value and set it to the secret name
SECRET_VALUE=$(az keyvault secret show --vault-name "${KEYVAULT_NAME}" -n "${SECRET}" --query "value" --output tsv)
# Add secret to file
BUILDARGS="${BUILDARGS} ${BUILDARG_PREDICATE} ${SECRET_NAME}=${SECRET_VALUE}"
done < <(echo "${SECRETS[*]}")
fi
echo "buildArguments=${BUILDARGS}" >> $GITHUB_ENV
- name: Login to Azure Container Registry
uses: Azure/docker-login@v1
with:
login-server: ${{ secrets.registryHostName }}
username: ${{ secrets.registryUserName }}
password: ${{ secrets.registryPassword }}

- name: Build & Push Docker Image
id: docker
run: |
docker build ${{ inputs.dockerFilePath }} ${{ env.buildArguments }} -t "${{ secrets.registryHostName }}/${{ inputs.dockerImageName }}:${{ needs.prepare.outputs.jiraTicketId }}"
docker push -a "${{ secrets.registryHostName }}/${{ inputs.dockerImageName }}"
- name: Deploy Azure Container App
uses: azure/container-apps-deploy-action@v1
with:
registryUrl: ${{ secrets.registryHostName }}
registryUsername: ${{ secrets.registryUserName }}
registryPassword: ${{ secrets.registryPassword }}
imageToDeploy: ${{ secrets.registryHostName }}/${{ inputs.dockerImageName }}:${{ needs.prepare.outputs.jiraTicketId }}
containerAppName: ${{ needs.prepare.outputs.repositoryName }}-${{ needs.prepare.outputs.jiraTicketIdLc }}
resourceGroup: ${{ inputs.clusterResourceGroup }}
targetPort: ${{ steps.env-vars.outputs.targetPort }}
location: ${{ inputs.azureResourceLocation }}
environmentVariables: ${{ steps.env-vars.outputs.environmentVariables }}
ingress: external
disableTelemetry: true

- name: Get Container App Hostname
id: hostname
run: |
HOSTNAME=$(az containerapp list --query "[?name == '${{ needs.prepare.outputs.repositoryName }}-${{ needs.prepare.outputs.jiraTicketIdLc }}'].properties.configuration.ingress.fqdn" -o tsv)
echo "hostname=https://${HOSTNAME}" >> $GITHUB_OUTPUT
- name: Update Next URL variables
if: contains(steps.env-vars.outputs.environmentVariables, 'BASE_URL')
run: |
REPOSITORY_NAME=$(echo "${{ github.event.repository.name }}" | awk -F '_' '{print $1}' | tr -d "-")
HOSTNAME="${{ steps.hostname.outputs.hostname }}"
URL_VARS=""
while IFS= read -r line; do
var=$(echo "$line" | awk -F '=' '{print $1}' | sed "s|$|=${HOSTNAME}|g")
URL_VARS+="$var "
done < <(grep -E "localhost|${REPOSITORY_NAME}.com" .env)
az containerapp update -n "${{ needs.prepare.outputs.repositoryName }}-${{ needs.prepare.outputs.jiraTicketIdLc }}" -g "${{ inputs.clusterResourceGroup }}" --set-env-vars "${URL_VARS}"
destroy:
name: Destroy Azure Container Instance
if: ${{ github.event_name == 'pull_request' && github.event.action == 'closed' }}
needs: [prepare]
runs-on: ubuntu-latest
steps:
- name: Login via Az module
uses: azure/login@v1
with:
creds: "${{ secrets.azureCredentials }}"

- name: Delete Azure Resources
run: |
az containerapp delete --resource-group ${{ inputs.clusterResourceGroup }} --name ${{ needs.prepare.outputs.repositoryName }}-${{ needs.prepare.outputs.jiraTicketIdLc }} --yes
az acr repository delete -n ${{ secrets.registryHostName }} --image ${{ inputs.dockerImageName }}:${{ needs.prepare.outputs.jiraTicketId }} --yes
- name: Delete deployment environment
uses: strumwolf/delete-deployment-environment@v2
with:
token: ${{ secrets.githubPAT }}
environment: ${{ needs.prepare.outputs.jiraTicketId }}
ref: ${{ github.ref_name }}

0 comments on commit 754a51c

Please sign in to comment.