Skip to content

twas-nd CICD

twas-nd CICD #47

Workflow file for this run

# Copyright (c) IBM Corporation.
# Copyright (c) Microsoft Corporation.
name: twas-nd CICD
# Controls when the action will run.
on:
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
inputs:
imageVersionNumber:
description: 'Provide image version number'
required: false
# Allows you to run this workflow using GitHub APIs
# PERSONAL_ACCESS_TOKEN=<GITHUB_PERSONAL_ACCESS_TOKEN>
# REPO_NAME=WASdev/azure.websphere-traditional.image
# curl --verbose -X POST -u "WASdev:${PERSONAL_ACCESS_TOKEN}" -H "Accept: application/vnd.github.everest-preview+json" -H "Content-Type: application/json" https://api.github.com/repos/${REPO_NAME}/actions/workflows/twas-ndBuild.yml/dispatches --data '{"ref": "main", "inputs": {"imageVersionNumber": "9.0.20230428"}}'
repository_dispatch:
types: [integration-test-twasnd, integration-test-all]
# sample request
# PERSONAL_ACCESS_TOKEN=<GITHUB_PERSONAL_ACCESS_TOKEN>
# REPO_NAME=WASdev/azure.websphere-traditional.image
# curl --verbose -X POST https://api.github.com/repos/${REPO_NAME}/dispatches -H "Accept: application/vnd.github.everest-preview+json" -H "Authorization: token ${PERSONAL_ACCESS_TOKEN}" --data '{"event_type": "integration-test-twasnd", "client_payload": {"imageVersionNumber": "9.0.20230428"}}'
# The integration-test-all event is used to run all integration tests (twas-base, twas-nd & ihs) in the repository with the same image version number.
# curl --verbose -X POST https://api.github.com/repos/${REPO_NAME}/dispatches -H "Accept: application/vnd.github.everest-preview+json" -H "Authorization: token ${PERSONAL_ACCESS_TOKEN}" --data '{"event_type": "integration-test-all", "client_payload": {"imageVersionNumber": "9.0.20230428"}}'
env:
repoName: azure.websphere-traditional.image
userName: ${{ secrets.USER_NAME }}
azureCredentials: ${{ secrets.AZURE_CREDENTIALS }}
entitledIbmUserId: ${{ secrets.ENTITLED_IBM_USER_ID }}
entitledIbmPassword: ${{ secrets.ENTITLED_IBM_USER_PWD }}
unEntitledIbmUserId: ${{ secrets.UNENTITLED_IBM_USER_ID }}
unEntitledIbmPassword: ${{ secrets.UNENTITLED_IBM_USER_PWD }}
vmAdminId: ${{ secrets.VM_ADMIN_ID }}
vmAdminPassword: ${{ secrets.VM_ADMIN_PASSWORD }}
testResourceGroup: imageTest-${{ github.repository_owner }}-${{ github.run_id }}-${{ github.run_number }}-twasND
vmName: vm-${{ github.run_id }}-${{ github.run_number }}
vhdStorageAccountName: storage${{ github.run_id }}${{ github.run_number }}
location: eastus
scriptLocation: https://raw.githubusercontent.com/${{ secrets.USER_NAME }}/azure.websphere-traditional.image/$GITHUB_REF_NAME/twas-nd/test/
utilitiesLocation: https://raw.githubusercontent.com/${{ secrets.USER_NAME }}/azure.websphere-traditional.image/$GITHUB_REF_NAME/utilities/
accessToken: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
twasClusterRepo: ${{ secrets.USER_NAME }}/azure.websphere-traditional.cluster
offerId: "2023-03-27-twas-cluster-base-image"
planId: "2023-03-27-twas-cluster-base-image"
offerType: "vm_image_offer"
clientId: ${{ secrets.CLIENT_ID }}
secretValue: ${{ secrets.SECRET_VALUE }}
tenantId: ${{ secrets.TENANT_ID }}
imageType: "x64Gen1"
operatingSystemFamily: "linux"
operatingSystemType: "redHat"
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
outputs:
imageVersionNumber: ${{ steps.setup-env-variables-based-on-dispatch-event.outputs.imageVersionNumber }}
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- name: Get versions of external dependencies
run: |
curl -Lo external-deps-versions.properties https://raw.githubusercontent.com/Azure/azure-javaee-iaas/main/external-deps-versions.properties
source external-deps-versions.properties
echo "azCliVersion=${AZ_CLI_VERSION}" >> $GITHUB_ENV
echo "refArmttk=${ARM_TTK_REFERENCE}" >> $GITHUB_ENV
echo "refJavaee=${AZURE_JAVAEE_IAAS_REFERENCE}" >> $GITHUB_ENV
- name: Setup environment variables
id: setup-env-variables-based-on-dispatch-event
run: |
if [ ${{ github.event_name }} == 'workflow_dispatch' ]; then
imageVersionNumber=${{ github.event.inputs.imageVersionNumber }}
else
imageVersionNumber=${{ github.event.client_payload.imageVersionNumber }}
fi
echo "##[set-output name=imageVersionNumber;]${imageVersionNumber}"
- name: Set up JDK 11
uses: actions/setup-java@v2
with:
distribution: 'microsoft'
java-version: '11'
- name: Checkout azure-javaee-iaas
uses: actions/checkout@v3
with:
repository: Azure/azure-javaee-iaas
path: azure-javaee-iaas
ref: ${{ env.refJavaee }}
- name: Checkout arm-ttk
uses: actions/checkout@v3
with:
repository: Azure/arm-ttk
path: arm-ttk
ref: ${{ env.refArmttk }}
- name: Checkout ${{ env.repoName }}
uses: actions/checkout@v3
with:
path: ${{ env.repoName }}
ref: ${{ github.event.inputs.ref }}
- name: Build azure-javaee-iaas
run: mvn -DskipTests clean install --file azure-javaee-iaas/pom.xml
- name: Azure login
uses: azure/login@v1
with:
creds: ${{ env.azureCredentials }}
- name: Build ${{ env.repoName }}
run: |
echo "Branch name is $GITHUB_REF_NAME"
mvn -Dgit.repo=${{ env.userName }} -Dgit.tag=$GITHUB_REF_NAME \
-DibmUserId=${{ env.entitledIbmUserId }} -DibmUserPwd=${{ env.entitledIbmPassword }} \
-DstorageAccount=${{ env.vhdStorageAccountName }} -DvmName=${{ env.vmName }} \
-DvmAdminId=${{ env.vmAdminId }} -DvmAdminPwd=${{ env.vmAdminPassword }} \
-Dtest.args="-Test All" -Ptemplate-validation-tests -Dtemplate.validation.tests.directory=../../arm-ttk/arm-ttk \
clean install --file ${{ env.repoName }}/twas-nd/pom.xml
- name: Deploy a RHEL 9.x VM and install twas ND server
run: |
cd ${{ env.repoName }}/twas-nd/target/cli
chmod a+x deploy.azcli
./deploy.azcli -n testDeployment -g ${{ env.testResourceGroup }} -l ${{ env.location }}
- name: Query public IP of VM
uses: azure/CLI@v1
with:
azcliversion: ${{ env.azCliVersion }}
inlineScript: |
echo "query public ip"
publicIP=$(az vm show \
--resource-group ${{ env.testResourceGroup }} \
--name ${{ env.vmName }} -d \
--query publicIps -o tsv)
echo "publicIP=${publicIP}" >> $GITHUB_ENV
- name: Output installation log
run: |
sudo apt-get install -y sshpass
timeout 1m sh -c 'until nc -zv $0 $1; do echo "nc rc: $?"; sleep 5; done' ${publicIP} 22
echo "Output stdout:"
result=$(sshpass -p ${{ env.vmAdminPassword }} -v ssh -p 22 -o StrictHostKeyChecking=no -o TCPKeepAlive=yes -o ServerAliveCountMax=20 -o ServerAliveInterval=15 -o ConnectTimeout=100 -v -tt ${{ env.vmAdminId }}@${publicIP} 'echo "${{ env.vmAdminPassword }}" | sudo -S cat /var/lib/waagent/custom-script/download/0/stdout')
echo "$result"
- name: Update the packages
run: |
sudo apt-get install -y sshpass
timeout 1m sh -c 'until nc -zv $0 $1; do echo "nc rc: $?"; sleep 5; done' ${publicIP} 22
sshpass -p ${{ env.vmAdminPassword }} -v ssh -p 22 -o StrictHostKeyChecking=no -o TCPKeepAlive=yes -o ServerAliveCountMax=20 -o ServerAliveInterval=15 -o ConnectTimeout=100 -v -tt ${{ env.vmAdminId }}@${publicIP} 'echo "${{ env.vmAdminPassword }}" | sudo -S yum update -y'
- name: Harden the VM using OpenSCAP tool
run: |
az vm extension set --name CustomScript \
--extension-instance-name apply-oscap-rules \
--resource-group ${{ env.testResourceGroup }} --vm-name ${{ env.vmName }} \
--publisher Microsoft.Azure.Extensions --version 2.0 \
--settings "{\"fileUris\": [\"${{ env.utilitiesLocation }}oscap.sh\"]}" \
--protected-settings "{\"commandToExecute\":\"bash oscap.sh ${{ env.vmAdminId }}\"}"
- name: Copy openscap scanning reports
run: |
sudo apt-get install -y sshpass
timeout 1m sh -c 'until nc -zv $0 $1; do echo "nc rc: $?"; sleep 5; done' ${publicIP} 22
sshpass -p ${vmAdminPassword} scp ${vmAdminId}@${publicIP}:/home/${vmAdminId}/scan_report_* .
- name: Upload openscap scanning report before remidation
uses: actions/upload-artifact@v3
with:
name: scan-report-before
path: scan_report_before.html
- name: Upload openscap scanning report after remidation
uses: actions/upload-artifact@v3
with:
name: scan-report-after
path: scan_report_after.html
- name: Deprovision the VM
run: |
sudo apt-get install -y sshpass
timeout 1m sh -c 'until nc -zv $0 $1; do echo "nc rc: $?"; sleep 5; done' ${publicIP} 22
sshpass -p ${{ env.vmAdminPassword }} -v ssh -p 22 -o StrictHostKeyChecking=no -o TCPKeepAlive=yes -o ServerAliveCountMax=20 -o ServerAliveInterval=15 -o ConnectTimeout=100 -v -tt ${{ env.vmAdminId }}@${publicIP} 'echo "${{ env.vmAdminPassword }}" | sudo -S waagent -deprovision+user -force'
- name: Generate the image
run: |
az vm deallocate --resource-group ${{ env.testResourceGroup }} --name ${{ env.vmName }}
az vm generalize --resource-group ${{ env.testResourceGroup }} --name ${{ env.vmName }}
az image create --resource-group ${{ env.testResourceGroup }} --name ${{ env.vmName }} --source ${{ env.vmName }}
verify_the_image:
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout ${{ env.repoName }}
uses: actions/checkout@v3
with:
path: ${{ env.repoName }}
ref: ${{ github.event.inputs.ref }}
- name: Azure login
uses: azure/login@v1
with:
creds: ${{ env.azureCredentials }}
- name: Verify the image
run: |
imageResourceId=$(az image show --name ${{ env.vmName }} --resource-group ${{ env.testResourceGroup }} --query id -o tsv)
echo "ndImageResourceId=${imageResourceId}" >> $GITHUB_ENV
echo "ihsImageResourceId=" >> $GITHUB_ENV
# Deploy VMs using different IBMids and verify installation
vmGroups=( ${{ env.testResourceGroup }}-entitled ${{ env.testResourceGroup }}-unentitled ${{ env.testResourceGroup }}-evaluation )
deploymentModes=( Entitled Unentitled Evaluation )
ibmUserIds=( ${{ env.entitledIbmUserId }} ${{ env.unEntitledIbmUserId }} "" )
ibmUserPwds=( ${{ env.entitledIbmPassword }} ${{ env.unEntitledIbmPassword }} "" )
for (( i=0; i<${#vmGroups[@]}; i++ )); do
rgName=${vmGroups[$i]}
az group create -n $rgName -l ${{ env.location }}
az deployment group create --resource-group $rgName --name testDeployment \
--template-file ${{ env.repoName }}/utilities/verifyTemplate.json \
--parameters deploymentMode=${deploymentModes[$i]} ibmUserId=${ibmUserIds[$i]} ibmUserPwd=${ibmUserPwds[$i]} \
imageResourceId=$imageResourceId vmAdminId=${{ env.vmAdminId }} vmAdminPwd=${{ env.vmAdminPassword }} \
scriptLocation=${{ env.scriptLocation }}
az group delete -n $rgName --yes --no-wait
done
- name: Verify the image with twas-cluster integration-test pipeline
run: |
# Trigger the workflow run
requestData={\"ref\":\"${GITHUB_REF_NAME}\",\"inputs\":{\"databaseType\":\"none\",\"ndImageResourceId\":\"${ndImageResourceId}\",\"ihsImageResourceId\":\"${ihsImageResourceId}\"}}
curl --verbose -L -X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${accessToken}"\
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/${{ env.twasClusterRepo }}/actions/workflows/integration-test.yaml/dispatches \
-d $(echo $requestData | jq -c)
# Wait until the workflow run starts
idAndStatus=$(curl -L \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${accessToken}"\
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/${{ env.twasClusterRepo }}/actions/workflows/integration-test.yaml/runs \
| jq -r '.workflow_runs[0] | {id, status}')
status=$(echo $idAndStatus | jq -r '.status')
while [[ $status != queued ]]
do
echo "Wait until the workflow run starts..."
idAndStatus=$(curl -L \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${accessToken}"\
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/${{ env.twasClusterRepo }}/actions/workflows/integration-test.yaml/runs \
| jq -r '.workflow_runs[0] | {id, status}')
status=$(echo $idAndStatus | jq -r '.status')
echo "The latest workflow run is ${idAndStatus}"
done
workflowRunId=$(echo $idAndStatus | jq '.id')
# Wait until the workflow run completes
status=$(curl -L \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${accessToken}"\
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/${{ env.twasClusterRepo }}/actions/runs/$workflowRunId \
| jq -r '.status')
while [[ $status != completed ]]
do
sleep 60
echo "Wait until the workflow run ${workflowRunId} completes..."
status=$(curl -L \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${accessToken}"\
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/${{ env.twasClusterRepo }}/actions/runs/$workflowRunId \
| jq -r '.status')
echo "Workflow run ${workflowRunId} is ${status}"
done
# Verify the workflow run result
jobs=$(curl -L \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${accessToken}"\
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/${{ env.twasClusterRepo }}/actions/runs/$workflowRunId/jobs)
successIntegTestJobCnt=$(echo $jobs | jq 'select(.jobs != null) | .jobs | map(select(.name=="integration-test" and .conclusion=="success")) | length')
if [[ $successIntegTestJobCnt != 1 ]]; then
echo "twas-cluster integration test workflow run ${workflowRunId} failed."
exit 1
else
echo "twas-cluster integration test workflow run ${workflowRunId} succeeded."
fi
update_sas_url:
needs: [ build, verify_the_image ]
runs-on: ubuntu-latest
steps:
- name: Azure login
uses: azure/login@v1
with:
creds: ${{ env.azureCredentials }}
- name: Generate SAS url
id: sas_url
run: |
# Get a minus-24-hour date and a plus-30-day date for the SAS token
minus24HoursUtc=$(date -u --date "$dte -24 hour" +%Y-%m-%dT%H:%MZ)
plus30DaysUtc=$(date -u --date "$dte 30 day" +%Y-%m-%dT%H:%MZ)
vhdStorageAccountAccessKey=$(az storage account keys list --account-name ${{ env.vhdStorageAccountName }} --query "[?keyName=='key1'].value" -o tsv)
sasToken=$(az storage container generate-sas \
--connection-string "DefaultEndpointsProtocol=https;AccountName=${{ env.vhdStorageAccountName }};AccountKey=${vhdStorageAccountAccessKey};EndpointSuffix=core.windows.net" \
--name vhds --permissions rl --start "${minus24HoursUtc}" --expiry "${plus30DaysUtc}" -o tsv)
blobStorageEndpoint=$( az storage account show -n ${{ env.vhdStorageAccountName }} -g ${{ env.testResourceGroup }} -o json | jq -r '.primaryEndpoints.blob' )
osDiskSasUrl=${blobStorageEndpoint}vhds/${{ env.vmName }}.vhd?$sasToken
dataDiskSasUrl=${blobStorageEndpoint}vhds/${{ env.vmName }}datadisk1.vhd?$sasToken
echo "osDiskSasUrl: ${osDiskSasUrl}, dataDiskSasUrl: ${dataDiskSasUrl}" > sas-url-twasnd.txt
echo "##[set-output name=osDiskSasUrl;]${osDiskSasUrl}"
echo "##[set-output name=dataDiskSasUrl;]${dataDiskSasUrl}"
- name: Upload SAS url
uses: actions/upload-artifact@v3
with:
name: sasurl-twasnd
path: sas-url-twasnd.txt
- name: Update offer sas url and version
uses: microsoft/[email protected]
if: ${{ needs.build.outputs.imageVersionNumber != '' }}
with:
offerId: ${{ env.offerId }}
planId: ${{ env.planId }}
offerType: ${{ env.offerType }}
clientId: ${{ env.clientId }}
tenantId: ${{ env.tenantId }}
secretValue: ${{ env.secretValue }}
imageType: ${{ env.imageType }}
imageVersionNumber: ${{ needs.build.outputs.imageVersionNumber }}
operatingSystemFamily: ${{ env.operatingSystemFamily }}
operatingSystemType: ${{ env.operatingSystemType }}
osDiskSasUrl: ${{steps.sas_url.outputs.osDiskSasUrl}}
dataDiskSasUrl: ${{steps.sas_url.outputs.dataDiskSasUrl}}
verbose: "false"
summary:
needs: [build, verify_the_image, update_sas_url]
runs-on: ubuntu-latest
steps:
- name: Output inputs from workflow_dispatch
run: echo "${{ toJSON(github.event.inputs) }}"
- name: Output client_payload from repository_dispatch
run: echo "${{ toJSON(github.event.client_payload) }}"
delete_resource:
needs: [ build, verify_the_image, update_sas_url,summary ]
runs-on: ubuntu-latest
if: always()
steps:
- name: Azure login
uses: azure/login@v1
with:
creds: ${{ env.azureCredentials }}
- name: Clean up all resources except for vhd storage account
continue-on-error: true
run: |
az image delete --ids \
$(az image show -g ${{ env.testResourceGroup }} -n ${{ env.vmName }} --query id -o tsv)
az vm delete --yes --ids \
$(az vm show -g ${{ env.testResourceGroup }} -n ${{ env.vmName }} --query id -o tsv)
az network nic delete --ids \
$(az network nic list -g ${{ env.testResourceGroup }} --query [0].id -o tsv)
az network vnet delete --ids \
$(az network vnet list -g ${{ env.testResourceGroup }} --query [0].id -o tsv)
az network public-ip delete --ids \
$(az network public-ip list -g ${{ env.testResourceGroup }} --query [0].id -o tsv)
az network nsg delete --ids \
$(az network nsg list -g ${{ env.testResourceGroup }} --query [0].id -o tsv)
- name: Delete resource groups during verification
continue-on-error: true
run: |
vmGroups=( ${{ env.testResourceGroup }}-entitled ${{ env.testResourceGroup }}-unentitled ${{ env.testResourceGroup }}-evaluation )
for (( i=0; i<${#vmGroups[@]}; i++ )); do
rgName=${vmGroups[$i]}
if $(az group exists --name $rgName); then
echo "Resource group $rgName exists. Deleting..."
az group delete --name $rgName --yes --no-wait
echo "Resource group $rgName has been scheduled for deletion."
else
echo "Resource group $rgName does not exist."
fi
done
- name: Delete testResourceGroup
if: ${{ needs.verify_the_image.result != 'success' }}
run: |
echo "The verify_the_image result is ${{ needs.verify_the_image.result }}, delete the testResourceGroup."
az group delete -n ${{ env.testResourceGroup }} --yes --no-wait