Infrastructure as code using Azure Bicep and GitHub Actions
This repository demonstrates how to write infrastructure-as-code using Bicep (a Domain Specific Language for deploying resources on Azure) and how to write CI/CD pipelines using GitHub Actions.
This repository contains end-to-end examples of Node & Laravel (PHP) apps deployed to App Service and Azure Container Apps. The examples deploy additional resources such as Container Registry, Service Bus, Postgres & Cosmos database, storage accounts, Key Vault and configure Front Door load balancer and Azure DNS.
Infrastructure has been laid out as tiers based on the foundation platform
tier. The platform resources are likely to be organisation-wide shared resources and defined once. The domain
tier builds on this and provides resources shared across applications in the same domain. Finally the application
tiers defines app or service-specific resources.
Resource names have been defined in json files. You'll find these as *-infra.json
files in the .bicep
folder. Defining these one-time allows different modules and workflows to access these resources without duplicating resource names across the iac files. It also provides an easy way to manage and update resource names without hunting through the code.
App | Stack | Deployment Target |
---|---|---|
app1 | NestJs (Node) | Container Apps |
app2 | Laravel (PHP) | Container Apps |
app3 | NestJs (Node) | App Service |
app4 | Laravel (PHP) | App Service |
Later in this guide you'll find a walkthrough how to run the scripts locally. Note: You'll probably need to change some of the resource names in infra json files and other settings to avoid naming conflicts due to some of the global Azure naming restrictions.
The examples come complete with GitHub Actions workflows. However these require some initial set-up of secrets such as Service Principal, credentials, Azure subscription details. The quick start guide details these settings.
You'll probably need to change the following:
- domain name in
*-infra.json
files - Update your domain's nameserver records on completion of platform provisioning to point to Azure DNS
Login to Azure:
az login
List subscriptions:
az account list --output table
Select one of your listed subscriptions:
az account set --subscription <Subscription Id>
Create platform resources:
az group create --name rg-bicep-examples-plat --location australiaeast
az deployment group create --name dp-platform-infra-au --resource-group rg-bicep-examples-plat --template-file .bicep/platform-infra.bicep --parameters postgresPassword=<super secure password>
Create domain resources:
az group create --name rg-bicep-examples-dmn --location australiaeast
az deployment sub create --name dp-domain-infra-au --template-file .bicep/domain-infra.bicep --location australiaeast --parameters platformResourceGroup=rg-bicep-examples-plat domainResourceGroup=rg-bicep-examples-dmn
Create app resources:
az deployment sub create --name dp-app1-infra-au --template-file .bicep/app1-infra.bicep --location australiaeast --parameters platformResourceGroup=rg-bicep-examples-plat domainResourceGroup=rg-bicep-examples-dmn dockerImage=mcr.microsoft.com/azuredocs/containerapps-helloworld:latest
az deployment sub create --name dp-app2-infra-au --template-file .bicep/app2-infra.bicep --location australiaeast --parameters platformResourceGroup=rg-bicep-examples-plat domainResourceGroup=rg-bicep-examples-dmn dockerImage=mcr.microsoft.com/azuredocs/containerapps-helloworld:latest
az deployment sub create --name dp-app3-infra-au --template-file .bicep/app3-infra.bicep --location australiaeast --parameters platformResourceGroup=rg-bicep-examples-plat domainResourceGroup=rg-bicep-examples-dmn
az deployment sub create --name dp-app4-infra-au --template-file .bicep/app4-infra.bicep --location australiaeast --parameters platformResourceGroup=rg-bicep-examples-plat domainResourceGroup=rg-bicep-examples-dmn
Delete resources:
az group delete --name rg-bicep-examples-dmn
az group delete --name rg-bicep-examples-plat
Create the following repository secrets:
Secret | Description |
---|---|
AZ_CREDS | Subscription-scoped Service Principal. |
POSTGRES_PASSWORD | Desired admin password. Should meet minimum password requirements |
SP_NAME | Name of the Subscription-scoped Service Principal |
SUBSCRIPTION_ID | Azure Subscription Id. Run az account list --output table |
Run pipelines in order:
- Provision Platform resources with Bicep
- Provision Domain resources with Bicep
- Provision App3 resources with Bicep
- Provision App4 resources with Bicep
- Build App1 (Nest Container App)
- Build App2 (Laravel Container App)
- Build App3 (Nest App Service)
- Build App4 (Laravel App Service)