Created
June 20, 2023 09:01
-
-
Save liamfoneill/c673e7a1efcdf2a0c3dabb44fbd0ff25 to your computer and use it in GitHub Desktop.
This is an example of a 'proper' Azure DevOps Pipeline for deploying Infrastructure with Terraform. It leverage Environments and publishes and consume the Terraform plan in separate stages. It also use the Service Connection credentials from Azure DevOps so we aren't duplicating Service Principals for no good reason.
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
trigger: | |
- main | |
pool: | |
vmImage: ubuntu-latest | |
stages: | |
- stage: build | |
jobs: | |
- job: plan | |
displayName: Infrastructure Plan | |
steps: | |
- checkout: self | |
fetchDepth: 1 | |
- task: AzureCLI@2 | |
displayName: 'Prepare Credentials' | |
inputs: | |
addSpnToEnvironment: true | |
azureSubscription: 'Online(afe07a9d-e6de-4b4c-91eb-3ae7265a9245)' | |
scriptType: 'bash' | |
scriptLocation: 'inlineScript' | |
inlineScript: | | |
set -euo pipefail | |
echo "##vso[task.setvariable variable=AZURE_CLIENT_ID;issecret=true]${servicePrincipalId}" | |
echo "##vso[task.setvariable variable=AZURE_CLIENT_SECRET;issecret=true]${servicePrincipalKey}" | |
echo "##vso[task.setvariable variable=AZURE_SUBSCRIPTION_ID;issecret=true]$(az account show --query 'id' -o tsv)" | |
echo "##vso[task.setvariable variable=AZURE_TENANT_ID;issecret=true]${tenantId}" | |
- task: Bash@3 | |
displayName: 'Pin Terraform' | |
inputs: | |
targetType: 'inline' | |
script: | | |
set -euo pipefail | |
curl -SL "https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip" --output terraform.zip | |
# echo "${TERRAFORM_DOWNLOAD_SHA} terraform.zip" | sha256sum -c - | |
unzip "terraform.zip" | |
sudo mv terraform /usr/local/bin | |
terraform --version | |
rm terraform.zip | |
- task: Bash@3 | |
displayName: Terraform Init | |
env: | |
ARM_CLIENT_ID: $(AZURE_CLIENT_ID) | |
ARM_CLIENT_SECRET: $(AZURE_CLIENT_SECRET) | |
ARM_SUBSCRIPTION_ID: $(AZURE_SUBSCRIPTION_ID) | |
ARM_TENANT_ID: $(AZURE_TENANT_ID) | |
inputs: | |
targetType: 'inline' | |
script: | | |
set -euo pipefail | |
echo "Initialise" | |
terraform init \ | |
-input=false | |
echo "Sanity Check" | |
terraform validate | |
echo "Show Terraform Version and Providers" | |
terraform -v | |
terraform providers | |
workingDirectory: './Terraform/03-modules/' | |
- task: Bash@3 | |
name: 'terraform_plan' | |
displayName: 'Terraform Plan' | |
env: | |
ARM_CLIENT_ID: $(AZURE_CLIENT_ID) | |
ARM_CLIENT_SECRET: $(AZURE_CLIENT_SECRET) | |
ARM_SUBSCRIPTION_ID: $(AZURE_SUBSCRIPTION_ID) | |
ARM_TENANT_ID: $(AZURE_TENANT_ID) | |
inputs: | |
targetType: 'inline' | |
workingDirectory: './Terraform/03-modules/' | |
script: | | |
set -euo pipefail | |
if [ ${BUILD_REASON} == 'PullRequest' ]; then | |
export TF_CLI_ARGS="-lock=false" | |
fi | |
terraform plan \ | |
-input=false \ | |
-out ${BUILD_BUILDNUMBER}.tfplan | |
- task: ArchiveFiles@2 | |
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) | |
displayName: 'Create Plan Artifact' | |
inputs: | |
rootFolderOrFile: './Terraform/03-modules/' | |
includeRootFolder: false | |
archiveType: 'tar' | |
tarCompression: 'gz' | |
archiveFile: '$(Build.ArtifactStagingDirectory)/$(Build.BuildNumber).tgz' | |
replaceExistingArchive: true | |
- task: PublishPipelineArtifact@1 | |
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) | |
displayName: 'Publish Plan Artifact' | |
inputs: | |
targetPath: '$(Build.ArtifactStagingDirectory)' | |
artifactName: 'plan' | |
- stage: deploy | |
jobs: | |
- deployment: terraform | |
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) | |
displayName: 'Change Infrastructure' | |
environment: 'dev' | |
strategy: | |
runOnce: | |
deploy: | |
steps: | |
- task: ExtractFiles@1 | |
displayName: 'Extract Plan Artifact' | |
inputs: | |
archiveFilePatterns: '$(Pipeline.Workspace)/plan/$(Build.BuildNumber).tgz' | |
destinationFolder: '$(project_folder)/' | |
cleanDestinationFolder: true | |
- task: AzureCLI@2 | |
displayName: 'Prepare Credentials' | |
inputs: | |
addSpnToEnvironment: true | |
azureSubscription: 'Online(afe07a9d-e6de-4b4c-91eb-3ae7265a9245)' | |
scriptType: 'bash' | |
scriptLocation: 'inlineScript' | |
inlineScript: | | |
set -euo pipefail | |
echo "##vso[task.setvariable variable=AZURE_CLIENT_ID;issecret=true]${servicePrincipalId}" | |
echo "##vso[task.setvariable variable=AZURE_CLIENT_SECRET;issecret=true]${servicePrincipalKey}" | |
echo "##vso[task.setvariable variable=AZURE_SUBSCRIPTION_ID;issecret=true]$(az account show --query 'id' -o tsv)" | |
echo "##vso[task.setvariable variable=AZURE_TENANT_ID;issecret=true]${tenantId}" | |
- task: Bash@3 | |
displayName: 'Pin Terraform' | |
inputs: | |
targetType: 'inline' | |
script: | | |
set -euo pipefail | |
curl -SL "https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip" --output terraform.zip | |
# echo "${TERRAFORM_DOWNLOAD_SHA} terraform.zip" | sha256sum -c - | |
unzip "terraform.zip" | |
sudo mv terraform /usr/local/bin | |
terraform --version | |
rm terraform.zip | |
- task: Bash@3 | |
displayName: 'Terraform Apply' | |
env: | |
ARM_CLIENT_ID: $(AZURE_CLIENT_ID) | |
ARM_CLIENT_SECRET: $(AZURE_CLIENT_SECRET) | |
ARM_SUBSCRIPTION_ID: $(AZURE_SUBSCRIPTION_ID) | |
ARM_TENANT_ID: $(AZURE_TENANT_ID) | |
inputs: | |
targetType: 'inline' | |
workingDirectory: $(project_folder) | |
script: | | |
set -euo pipefail | |
terraform apply \ | |
-input=false \ | |
${BUILD_BUILDNUMBER}.tfplan |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment