Feature/avm integration #68
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
name: Deploy an Oracle DB in a Data Guard configuration on Azure with Bicep and Ansible | |
on: | |
workflow_dispatch: {} | |
push: | |
branches: [ main ] | |
paths: | |
- ".github/workflows/full-dg-bicep-deploy.yml" | |
- "bicep/bootstrap/data_guard/**" | |
- "bicep_units/**" | |
- "ansible/bootstrap/oracle/**" | |
pull_request: | |
branches: [ main ] | |
paths: | |
- ".github/workflows/full-dg-bicep-deploy.yml" | |
- "bicep/bootstrap/data_guard/**" | |
- "bicep_units/**" | |
- "ansible/bootstrap/oracle/**" | |
env: | |
#TF_LOG: "INFO" | |
AZ_LOCATION: "swedencentral" # can be parameterized | |
AZ_RG_BASENAME: "Oracle-test" # can be parameterized | |
VM_PRIMARY_NAME: "vm-primary-0" | |
VM_SECONDARY_NAME: "vm-secondary-0" | |
ORCL_DB_NAME: "ORCL" | |
SOFTWARE_RG: "binaryresource" | |
USER_ASSIGNED_IDENTITY: "oraclelza" | |
permissions: | |
id-token: write | |
contents: read | |
issues: write | |
pull-requests: write | |
jobs: | |
bicep: | |
name: '๐ง Bicep' | |
runs-on: ubuntu-latest | |
environment: test-deploy | |
strategy: | |
fail-fast: false | |
defaults: | |
run: | |
shell: bash | |
working-directory: ./bicep/bootstrap | |
steps: | |
# Checkout the repository to the GitHub Actions runner | |
- name: Checkout | |
uses: actions/checkout@v4 | |
#Check if the SSH key is empty | |
- name: ๐ Validate SSH Key is not empty | |
run: | | |
if [ -z "${{ secrets.SSH_PRIVATE_KEY }}" ] | |
then | |
echo "SSH_PRIVATE_KEY is empty, you should add a SSH key to the repository secrets. Name of the secret should be SSH_PRIVATE_KEY" | |
exit 1 | |
else | |
echo "SSH_PRIVATE_KEY is not empty" | |
fi | |
- name: ๐๏ธ Create the SSH public key for VM | |
run: | | |
cat > temp_ssh_key <<EOF | |
${{ secrets.SSH_PRIVATE_KEY }} | |
EOF | |
chmod 400 temp_ssh_key | |
ssh-keygen -f temp_ssh_key -y > temp_ssh_key.pub | |
echo "SSH_KEY=$(cat temp_ssh_key.pub)" >> $GITHUB_ENV | |
echo "SSH_KEY=${{env.SSH_KEY}}" | |
echo "currentDate=$(date)" >> $GITHUB_ENV | |
echo "currentDate=${{env.currentDate}}" | |
# Generate random string for suffix | |
- name: ๐ Generate Random String for Resource Group Name | |
id: resourcegroup-generator | |
run: echo random=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 8; echo) >> $GITHUB_ENV | |
- run: echo ResourceGroupName=${{env.AZ_RG_BASENAME}}-${{env.random}} >> $GITHUB_ENV | |
- run: echo ${{env.ResourceGroupName}} | |
#Login to Azure | |
- name: ๐ Login via Azure CLI | |
uses: azure/login@v1 | |
with: | |
client-id: ${{ secrets.AZURE_CLIENT_ID }} | |
tenant-id: ${{ secrets.AZURE_TENANT_ID }} | |
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} | |
- name: Get the ID of the user-assigned managed identity | |
run: echo usId=$(az identity show --name ${{ env.USER_ASSIGNED_IDENTITY }} --resource-group ${{ env.SOFTWARE_RG }} --query id --output tsv) >> $GITHUB_ENV | |
- name: ๐๏ธ Update the parameter file with run time values | |
run: | | |
# In the line "param resourceGroupName = '<rgName>'" replace <rgName> with the value of the variable ResourceGroupName | |
sed -i "s|resourceGroupName = '<rgName>'|resourceGroupName = '${{env.ResourceGroupName}}'|" data_guard/default/data_guard.bicepparam | |
# In the line "location = '<location>'" replace <location> with the value of the variable AZ_LOCATION | |
sed -i "s|location = '<location>|location = '${{env.AZ_LOCATION}}|" data_guard/default/data_guard.bicepparam | |
# In the line "sshPublicKey: '<sshKey>'' replace <sshKey> with the value of the variable SSH_KEY | |
sed -i "s|sshPublicKey: '<sshKey>'|sshPublicKey: '${{env.SSH_KEY}}'|g" data_guard/default/data_guard.bicepparam | |
# In the line "userAssignedId: '<userAssignedId>'" replace <userAssignedId> with the resource id of the variable USER_ASSIGNED_IDENTITY | |
sed -i "s|'<userAssignedId>'|'${{ env.usId }}'|" data_guard/default/data_guard.bicepparam | |
- name: Deploy infrastructure | |
#if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
run: | | |
az account set --subscription ${{ secrets.AZURE_SUBSCRIPTION_ID }} | |
az deployment sub create --location ${{env.AZ_LOCATION}} --name ${{env.ResourceGroupName}} --template-file main.bicep --parameters ./data_guard/default/data_guard.bicepparam resourceGroupName=${{env.ResourceGroupName}} location=${{env.AZ_LOCATION}} --verbose | |
outputs: | |
ResourceGroupName: ${{ env.ResourceGroupName }} | |
############################################################################################################################################## | |
# SSH Keys and parameter preparation for Ansible # | |
############################################################################################################################################## | |
ssh-keys: | |
needs: bicep | |
name: '๐งฎ Prepare and run Ansible Playbook' | |
runs-on: ubuntu-latest | |
environment: test-deploy | |
defaults: | |
run: | |
shell: bash | |
working-directory: ansible/bootstrap/oracle | |
steps: | |
- name: ๐ Checkout | |
uses: actions/checkout@v4 | |
- name: 'Install SSH Key' | |
uses: shimataro/ssh-key-action@v2 | |
with: | |
key: ${{ secrets.SSH_PRIVATE_KEY }} | |
name: 'github_actions_id_rsa' | |
known_hosts: "sometin" | |
# Login to Azure CLI | |
- name: ๐ Login via Azure CLI | |
uses: azure/login@v1 | |
with: | |
client-id: ${{ secrets.AZURE_CLIENT_ID }} | |
tenant-id: ${{ secrets.AZURE_TENANT_ID }} | |
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} | |
- name: ๐ Get/set dynamic values | |
run: echo "endTimeUtc=$(date -d '+2 hour' '+%FT%T')" >> $GITHUB_ENV | |
- run: echo "endTimeUtc=${{env.endTimeUtc}}" | |
- run: echo "ResourceGroupName=${{needs.bicep.outputs.ResourceGroupName}}" >> $GITHUB_ENV | |
- run: echo "ResourceGroupName=${{env.ResourceGroupName}}" | |
- run: echo "currentRunnerIP=$(curl https://api.ipify.org)" >> $GITHUB_ENV | |
- run: echo "currentRunnerIP=${{env.currentRunnerIP}}" | |
- run: echo "VM_Primary_IP_Address=$(az vm list-ip-addresses --resource-group ${{env.ResourceGroupName}} --name ${{env.VM_PRIMARY_NAME}} --query [0].virtualMachine.network.publicIpAddresses[0].ipAddress -o tsv)" >> $GITHUB_ENV | |
- run: echo "VM_Primary_IP_Address=${{env.VM_Primary_IP_Address}}" | |
- run: echo "VM_Secondary_IP_Address=$(az vm list-ip-addresses --resource-group ${{env.ResourceGroupName}} --name ${{env.VM_SECONDARY_NAME}} --query [0].virtualMachine.network.publicIpAddresses[0].ipAddress -o tsv)" >> $GITHUB_ENV | |
- run: echo "VM_Secondary_IP_Address=${{env.VM_Secondary_IP_Address}}" | |
- run: echo "SubscriptionID=$(az account show --query id -o tsv)" >> $GITHUB_ENV | |
- run: echo ${{env.SubscriptionID}} | |
# fixme add tags to resource group | |
- name: ๐ Login via Az PowerShell Module | |
uses: azure/login@v1 | |
with: | |
client-id: ${{ secrets.AZURE_CLIENT_ID }} | |
tenant-id: ${{ secrets.AZURE_TENANT_ID }} | |
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} | |
enable-AzPSSession: true | |
- name: โ Enable JIT on VM | |
uses: azure/powershell@v1 | |
with: | |
inlineScript: | | |
#Enable JIT on VMs | |
$JitPolicy1 = (@{id="/subscriptions/${{env.SubscriptionID}}/resourceGroups/${{env.ResourceGroupName}}/providers/Microsoft.Compute/virtualMachines/${{env.VM_PRIMARY_NAME}}";ports=(@{number=22;protocol="*";allowedSourceAddressPrefix=@("*"); maxRequestAccessDuration="PT3H"})}) | |
$JitPolicyArr1=@($JitPolicy1) | |
Set-AzJitNetworkAccessPolicy -Kind "Basic" -Location ${{env.AZ_LOCATION}} -Name "JIT-SSH-Policy-primary" -ResourceGroupName ${{env.ResourceGroupName}} -VirtualMachine $JitPolicyArr1 | |
$JitPolicy2 = (@{id="/subscriptions/${{env.SubscriptionID}}/resourceGroups/${{env.ResourceGroupName}}/providers/Microsoft.Compute/virtualMachines/${{env.VM_SECONDARY_NAME}}";ports=(@{number=22;protocol="*";allowedSourceAddressPrefix=@("*"); maxRequestAccessDuration="PT3H"})}) | |
$JitPolicyArr2=@($JitPolicy2) | |
Set-AzJitNetworkAccessPolicy -Kind "Basic" -Location ${{env.AZ_LOCATION}} -Name "JIT-SSH-Policy-secondary" -ResourceGroupName ${{env.ResourceGroupName}} -VirtualMachine $JitPolicyArr2 | |
#Start JIT on VM | |
$JitPolicyVm1 = (@{id="/subscriptions/${{env.SubscriptionID}}/resourceGroups/${{env.ResourceGroupName}}/providers/Microsoft.Compute/virtualMachines/${{env.VM_PRIMARY_NAME}}"; ports=(@{number=22;endTimeUtc="${{env.endTimeUtc}}";allowedSourceAddressPrefix=@("${{env.currentRunnerIP}}")})}) | |
$JitPolicyVm2 = (@{id="/subscriptions/${{env.SubscriptionID}}/resourceGroups/${{env.ResourceGroupName}}/providers/Microsoft.Compute/virtualMachines/${{env.VM_SECONDARY_NAME}}"; ports=(@{number=22;endTimeUtc="${{env.endTimeUtc}}";allowedSourceAddressPrefix=@("${{env.currentRunnerIP}}")})}) | |
$JitPolicyArr1=@($JitPolicyVm1) | |
$JitPolicyArr2=@($JitPolicyVm2) | |
Start-AzJitNetworkAccessPolicy -ResourceId "/subscriptions/${{env.SubscriptionID}}/resourceGroups/${{env.ResourceGroupName}}/providers/Microsoft.Security/locations/${{env.AZ_LOCATION}}/jitNetworkAccessPolicies/JIT-SSH-Policy-primary" -VirtualMachine $JitPolicyArr1 | |
Start-AzJitNetworkAccessPolicy -ResourceId "/subscriptions/${{env.SubscriptionID}}/resourceGroups/${{env.ResourceGroupName}}/providers/Microsoft.Security/locations/${{env.AZ_LOCATION}}/jitNetworkAccessPolicies/JIT-SSH-Policy-secondary" -VirtualMachine $JitPolicyArr2 | |
azPSVersion: "latest" | |
- name: ๐งฎ Get Known Hosts parameter using ssh-keyscan | |
run: | | |
ssh-keyscan -T 300 -H ${{env.VM_Primary_IP_Address}} >> /home/runner/.ssh/known_hosts | |
ssh-keyscan -T 300 -H ${{env.VM_Secondary_IP_Address}} >> /home/runner/.ssh/known_hosts | |
- name: ๐๏ธ Create the inventory file | |
run: | | |
cat > inventory <<EOF | |
[ora-x1] | |
${{env.VM_PRIMARY_NAME}} ansible_host=${{env.VM_Primary_IP_Address}} ansible_ssh_private_key_file=/home/runner/.ssh/github_actions_id_rsa ansible_user=oracle | |
[ora-x2] | |
${{env.VM_SECONDARY_NAME}} ansible_host=${{env.VM_Secondary_IP_Address}} ansible_ssh_private_key_file=/home/runner/.ssh/github_actions_id_rsa ansible_user=oracle | |
EOF | |
- name: ๐๏ธ Show the inventory file | |
run: cat inventory | |
# ############################################################################################################################################## | |
# # Ansible # | |
# ############################################################################################################################################## | |
- name: '๐๏ธ๐ฟ๐ง Invoke ansible playbook ๐ด๐ด๐ด' | |
run: ansible-playbook playbook_dg.yml -i inventory --extra-vars "data_guard=yes" | |
- name: Run Ansible playbook to test Oracle database state | |
run: ansible-playbook testplaybook_dg.yml -i inventory > ansible_output.txt | |
- name: Evaluate test output | |
run: | | |
lines=( | |
"INSTANCE_NAME\t STATUS DATABASE_STATUS" | |
"${{env.ORCL_DB_NAME}}\t\t OPEN\t ACTIVE" | |
) | |
found_all=true | |
for line in "${lines[@]}"; do | |
if ! grep -qF "$line" "ansible_output.txt"; then | |
found_all=false | |
break | |
fi | |
done | |
if $found_all; then | |
echo "All lines found in the output." | |
# Perform further actions based on the output | |
else | |
echo "Not all lines found in the output. Showing ansible output:" | |
cat ansible_output.txt | |
exit 1 # Exit with a non-zero code to indicate failure | |
fi |