Introduction
In this article we will implement the CI/CD for the Azure API Management Service.
Azure API Management is a reliable, secure and scalable way to publish, consume and manage API's.
DevOps Architecture
Technology Used
GitHub, GitHub Actions
Python, REST API, ARM template
APIM Component
As part of the CI/CD, Below list of the component can be deployed.
APIs
Backends
NamedValues
Operations
Operations Policies
APIs policies
This can be customizable through Python Script to deploy only required component as per your requirement.
Code Snippet of Python Script.
# Change to True for Deploy else set False
deploy_apis=True
deploy_namedValues=False
deploy_backends=False
deploy_operations=True
deploy_policies=True
deploy_ops_policies=True
Component Deployment Sequence
Configuration Update
There might be some configuration that needs to be updated before Deploying to environment. For that We have created Python script which will update the ARM template with respect to environment Value specified in the properties File.
Python Script Details
Properties File Like
Setup Repo for CI/CD
As per the discussed method we can setup the CI/CD workflow. All the project related script and File is publicly available at.
Now lets setup each Part one by One.
Repo Setup
First we need to make sure the ARM template extracted from the Dev API Management Service and Imported to GitHub. Once you extract the ARM template there will be Two Files but we only required template.json File to be imported.
Properties Update
Next we need to see what are the Properties needs to be updated before we deploy to the Pre Prod and Prod. Since we extracted the template from Dev APIM all the configuration related to dev will be available in the ARM template. Hence to Deploy on other environment we need to update the ARM template and that will be achieved through Developed Python script.
In this case review the template and update the below files.
Example:
If you see the below example we are using the properties file where left value will be replaced by Right Value.
Deployment Script
You can fork the Deployment script and properties python script along with requirement.txt file and import to your Repo.
Workflow File
Since we are using the GitHub Actions for Demo you can get the Workflow file and Import to GitHub Account.
name: APIM-CherryPick-TemplateDeploy
# Manual trigger with parameters
on:
workflow_dispatch:
inputs:
#Name of your Source Cosmos DB
ENVIRONMENT:
description: 'Deployment Environment (npr/prp/prd)'
required: true
default: 'npr'
ARMtemplate_Path:
description: 'ARM template Json file to create apis/Collection. Path Relative tO GITHUB'
required: true
default: '/APIM/arm-template/'
apis_list:
description: 'List of APIs to Deploy--> , separated'
required: true
default: 'autouwrt-cust-dly,cardxlos-autouwrt-dpst-dly'
jobs:
#############################################################
# This is packaging up the files from Git to the Artifacts files
#############################################################
Build:
runs-on: ubuntu-latest
env:
input_commitid: '${{ github.event.inputs.INPUT_COMMITID }}'
# Checkout code
steps:
- name: Checkout repo
uses: actions/checkout@v2
# Publish Artifact: Publish: Deployment-Scripts
- name: 'Publish Artifact: APIM SYNC'
uses: actions/upload-artifact@v2
with:
name: 'deployment-scripts'
path: '${{ github.workspace }}/Deployment-Scripts/APIM-Sync/'
- name: Install dependencies
run: |
cd "$GITHUB_WORKSPACE/Deployment-Scripts/Update-Properties/"
python3 -m pip install --upgrade pip
pip install -r requirements.txt
# Optional: Add step to run tests here
- name: Update Properties on Non-Production Environment
if: ${{ github.event.inputs.ENVIRONMENT == 'npr' }}
run: |
cd "$GITHUB_WORKSPACE/APIM/arm-template/"
python3 $GITHUB_WORKSPACE/Deployment-Scripts/Update-Properties/properties-update.py \
'${{ github.workspace }}/APIM/npr-app-config.properties' \
'${{ github.workspace }}/APIM/arm-template/'
- name: Update Properties on Pre-Production Environment
if: ${{ github.event.inputs.ENVIRONMENT == 'prp' }}
run: |
cd "$GITHUB_WORKSPACE/APIM/arm-template/"
python3 $GITHUB_WORKSPACE/Deployment-Scripts/Update-Properties/properties-update.py \
'${{ github.workspace }}/APIM/prp-app-config.properties' \
'${{ github.workspace }}/APIM/arm-template/'
- name: Update Properties on Production Environment
if: ${{ github.event.inputs.ENVIRONMENT == 'prd' }}
run: |
cd "$GITHUB_WORKSPACE/APIM/arm-template/"
python3 $GITHUB_WORKSPACE/Deployment-Scripts/Update-Properties/properties-update.py \
'${{ github.workspace }}/APIM/prd-app-config.properties' \
'${{ github.workspace }}/APIM/arm-template/'
# Publish Artifact: Publish: Template JSON
- name: 'Publish Artifact: Template JSON'
uses: actions/upload-artifact@v2
with:
name: 'template-file'
path: '${{ github.workspace }}/${{ github.event.inputs.ARMtemplate_Path }}'
#############################################################
# Deploy to Dev
#############################################################
Dev:
if: ${{ github.event.inputs.Environment == 'npr' }}
needs: Build
runs-on: ubuntu-latest
env:
TargetAPIM_NAME: 'devops-apimtest-1'
TargetAPIM_RG: 'devops-confluent-test'
keyVaultName: 'akv-sp'
steps:
# Login to Azure
- name: Login via Az module
uses: Azure/login@v1.4.5
with:
creds: |
${{ secrets.SP_NPR }}
# Download secret from KeyVault Secrets
- name: Download publish profile from KeyVault Secrets
uses: Azure/get-keyvault-secrets@v1
with:
keyvault: ${{ env.keyVaultName }}
secrets: 'sp-npr-appid,sp-npr-secretkey,sp-npr-tenantid,sp-npr-subscriptionid'
id: AzureSPCred
# Download Artifact: deployment-scripts
- name: 'Download Artifact: ARM-Templates'
uses: actions/download-artifact@v2
with:
name: 'deployment-scripts'
path: ${{ github.workspace }}/Deployment-Scripts/APIM-Sync/
# Download Artifact: Publish: Template JSON
- name: 'Publish Artifact: Template JSON'
uses: actions/download-artifact@v2
with:
name: 'template-file'
path: '${{ github.workspace }}/${{ github.event.inputs.ARMtemplate_Path }}'
- name: Install dependencies
run: |
cd "$GITHUB_WORKSPACE/Deployment-Scripts/APIM-Sync/"
python3 -m pip install --upgrade pip
pip install -r requirements.txt
- name: Deploy Template
run: |
chmod +x $GITHUB_WORKSPACE/Deployment-Scripts/APIM-Sync/template-deploy-api-Management.py
python3 $GITHUB_WORKSPACE/Deployment-Scripts/APIM-Sync/template-deploy-api-Management.py
env:
ARMtemplate_Path: '${{ github.workspace }}/${{ github.event.inputs.ARMtemplate_Path }}'
TargetAPIM_NAME: ${{ env.TargetAPIM_NAME }}
TargetAPIM_RG: ${{ env.TargetAPIM_RG }}
CLIENT_SECRET: ${{ steps.AzureSPCred.outputs.sp-npr-secretkey }}
CLIENT_ID: ${{ steps.AzureSPCred.outputs.sp-npr-appid }}
TENANT_ID: ${{ steps.AzureSPCred.outputs.sp-npr-tenantid }}
SUBSCRIPTION_ID: ${{ steps.AzureSPCred.outputs.sp-npr-subscriptionid }}
apis_list: ${{ github.event.inputs.apis_list }}
Configure GitHub Actions
Azure Service Principle
For all the authentication we are using the Service Principle so if you want to use the same please create SP and set the Permission to access to API Management service and Key Vault
KeyVault
In the workflow we are using the Key Vault to fetch the below required details. Make sure the Key Vault access policies setup to access by Service Principle
sp-npr-appid
sp-npr-secretkey
sp-npr-tenantid
sp-npr-subscriptionid
- name: Download publish profile from KeyVault Secrets
uses: Azure/get-keyvault-secrets@v1
with:
keyvault: ${{ env.keyVaultName }}
secrets: 'sp-npr-appid,sp-npr-secretkey,sp-npr-tenantid,sp-npr-subscriptionid'
id: AzureSPCred
Workflow File
Workflow Input Details can be updated.
ENVIRONMENT
ARMtemplate_Path
apis_list
workflow_dispatch:
inputs:
#Name of your Source Cosmos DB
ENVIRONMENT:
description: 'Deployment Environment (npr/prp/prd)'
required: true
default: 'npr'
ARMtemplate_Path:
description: 'ARM template Json file to create apis/Collection. Path Relative tO GITHUB'
required: true
default: '/APIM/arm-template/'
apis_list:
description: 'List of APIs to Deploy--> , separated OR all for all the Object'
required: true
default: 'all'
Env Setting update as per the Environment
TargetAPIM_NAME --> Name of the APIM service
TargetAPIM_RG --> APIM Service Resource Group
keyVaultName --> KeyVault where SP credential info setup.
Dev:
if: ${{ github.event.inputs.Environment == 'npr' }}
needs: Build
runs-on: ubuntu-latest
env:
TargetAPIM_NAME: 'devops-apimtest-1'
TargetAPIM_RG: 'devops-confluent-test'
keyVaultName: 'akv-sp'
Create Service Principle secret in GitHub Actions Secret for the Connectivity to Azure.
Secret Name: SP_NPR [Service Principle Non Prod]
value:
{
"clientId": "Update me: Client ID ",
"clientSecret": "Update me: Client Secret",
"subscriptionId": "Update me: Subscription ID",
"tenantId": "Update me: Tenant ID",
"activeDirectoryEndpointUrl": "https://login.microsoftonline.com",
"resourceManagerEndpointUrl": " https://management.azure.com/",
"activeDirectoryGraphResourceId": " https://graph.windows.net/",
"sqlManagementEndpointUrl": " https://management.core.windows.net:8443/",
"galleryEndpointUrl": " https://gallery.azure.com/",
"managementEndpointUrl": " https://management.core.windows.net/"
}
steps:
# Login to Azure
- name: Login via Az module
uses: Azure/login@v1.4.5
with:
creds: |
${{ secrets.SP_NPR }}
Comentarios