From 352c19ca515d98049f400db83837b800351651f8 Mon Sep 17 00:00:00 2001 From: Glenn Musa <4622125+glennmusa@users.noreply.github.com> Date: Thu, 10 Feb 2022 15:09:28 -0500 Subject: [PATCH] Clean-up nightly deployments using Azure CLI (#642) --- .../mlz-bicep-azurecloud-pipelines.yml | 132 ++------------- .../mlz-bicep-azuregov-pipelines.yml | 131 ++------------- .../mlz-tf-azurecloud-pipelines.yml | 132 +++------------ .../mlz-tf-azuregov-pipelines.yml | 155 ++---------------- .../nightlybuild/templates/az-deployment.yml | 101 ++++++++++++ .../templates/clean-az-subscription.yml | 40 +++++ .../templates/terraform-apply.yml | 105 ++++++++++++ .../mlz-pr-bicep-azurecloud-pipelines.yml | 24 +-- .../mlz-pr-bicep-azuregov-pipelines.yml | 24 +-- .../mlz-pr-tf-azurecloud-pipelines.yml | 35 ++-- .../prbuild/mlz-pr-tf-azuregov-pipelines.yml | 36 ++-- .../prbuild/templates/az-what-if.yml | 26 +++ .../prbuild/templates/terraform-plan.yml | 51 ++++++ .gitignore | 1 + 14 files changed, 434 insertions(+), 559 deletions(-) create mode 100644 .azure-devops/nightlybuild/templates/az-deployment.yml create mode 100644 .azure-devops/nightlybuild/templates/clean-az-subscription.yml create mode 100644 .azure-devops/nightlybuild/templates/terraform-apply.yml create mode 100644 .azure-devops/prbuild/templates/az-what-if.yml create mode 100644 .azure-devops/prbuild/templates/terraform-plan.yml diff --git a/.azure-devops/nightlybuild/mlz-bicep-azurecloud-pipelines.yml b/.azure-devops/nightlybuild/mlz-bicep-azurecloud-pipelines.yml index ec28bdbf5..7c7872e5e 100644 --- a/.azure-devops/nightlybuild/mlz-bicep-azurecloud-pipelines.yml +++ b/.azure-devops/nightlybuild/mlz-bicep-azurecloud-pipelines.yml @@ -2,6 +2,7 @@ # Licensed under the MIT License. schedules: + - cron: "0 4 * * *" displayName: "Nightly - mlz bicep azure cloud" branches: @@ -10,125 +11,24 @@ schedules: always: true pool: - vmImage: ubuntu-latest -variables: - ServiceConnectionName: $(CAzureConnection) + vmImage: ubuntu-latest jobs: -- job: bicepCommercialCloud - steps: - - task: AzureCLI@2 - displayName: "Deploy MLZ Bicep" - inputs: - azureSubscription: $(ServiceConnectionName) - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - datetime=$(date +%s) # gets the current date time as an epoch - az deployment sub create \ - --name $(bDeploymentName) \ - --location $(Location) \ - --template-file $(TemplateFile) \ - --parameters resourcePrefix=$datetime - - - task: AzureCLI@2 - displayName: "Generate deploymentVariables.json for all addons and examples" - inputs: - azureSubscription: $(ServiceConnectionName) - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - az deployment sub show \ - --name $(bDeploymentName) \ - --query properties.outputs \ - > $(Build.SourcesDirectory)/src/bicep/examples/deploymentVariables.json - - - task: AzureCLI@2 - displayName: "Extract Values and Hydrate Variables for T3 Deployment" - inputs: - azureSubscription: $(ServiceConnectionName) - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - deploymentoutput=$(az deployment sub show \ - --name $(bDeploymentName) \ - --query '{ - hubSubId: properties.outputs.hub.value.subscriptionId, - hubRGroupName: properties.outputs.hub.value.resourceGroupName, - hubVNetworkName: properties.outputs.hub.value.virtualNetworkName, - hubVNetworkResourceId: properties.outputs.hub.value.virtualNetworkResourceId, - logAWspaceResourceId: properties.outputs.logAnalyticsWorkspaceResourceId.value, - firewallPrivateIP: properties.outputs.firewallPrivateIPAddress.value - }' \ - --output json) - - hubSubId=$(echo $deploymentoutput | jq '.hubSubId') \ - && echo "##vso[task.setvariable variable=hubSubscriptionId;]$hubSubId" - hubRGroupName=$(echo $deploymentoutput | jq '.hubRGroupName') \ - && echo "##vso[task.setvariable variable=hubResourceGroupName;]$hubRGroupName" - - hubVNetworkName=$(echo $deploymentoutput | jq '.hubVNetworkName') \ - && echo "##vso[task.setvariable variable=hubVirtualNetworkName;]$hubVNetworkName" - - hubVNetworkResourceId=$(echo $deploymentoutput | jq '.hubVNetworkResourceId') \ - && echo "##vso[task.setvariable variable=hubVirtualNetworkResourceId;]$hubVNetworkResourceId" - - logAWspaceResourceId=$(echo $deploymentoutput | jq '.logAWspaceResourceId') \ - && echo "##vso[task.setvariable variable=logAnalyticsWorkspaceResourceId;]$logAWspaceResourceId" - - firewallPrivateIP=$(echo $deploymentoutput | jq '.firewallPrivateIP') \ - && echo "##vso[task.setvariable variable=firewallPrivateIPAddress;]$firewallPrivateIP" - - - task: AzureCLI@2 - displayName: "T3 Bicep Deployment" - inputs: - azureSubscription: $(ServiceConnectionName) - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - az deployment sub create \ - --subscription $(workloadSubId) \ - --location $(Location) \ - --name $(workloadName) \ - --template-file $(T3TemplateFile) \ - --parameters \ - workloadName=$(workloadName) \ - hubSubscriptionId=$(hubSubscriptionId) \ - hubResourceGroupName=$(hubResourceGroupName) \ - hubVirtualNetworkName=$(hubVirtualNetworkName) \ - hubVirtualNetworkResourceId=$(hubVirtualNetworkResourceId) \ - logAnalyticsWorkspaceResourceId=$(logAnalyticsWorkspaceResourceId) \ - firewallPrivateIPAddress=$(firewallPrivateIPAddress) +- job: bicepCommercialCloud + displayName: "Nightly deployment of Mission LZ Bicep on AzureCloud" - - task: AzureCLI@2 - displayName: "Clean up Subscription Diagnostics Settings" - condition: always() - inputs: - azureSubscription: $(ServiceConnectionName) - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - az monitor diagnostic-settings subscription list \ - --query "value[].name" \ - --output tsv \ - | xargs -t -I % az monitor diagnostic-settings subscription delete \ - --yes \ - --name % + steps: - - task: AzureCLI@2 - displayName: "Clean up Resources" - condition: always() - inputs: - azureSubscription: $(ServiceConnectionName) - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - az group list \ - --query "[].name" \ - --output tsv \ - | xargs -t -I % az group delete \ - --yes \ - --no-wait \ - --name % + - template: templates/az-deployment.yml + parameters: + ServiceConnectionName: $(CAzureConnection) + DeploymentName: $(bDeploymentName) + Location: $(CLocation) + WorkloadSubId: $(CSubId) + WorkloadName: $(workloadName) + + - template: templates/clean-az-subscription.yml + parameters: + serviceConnectionName: $(CAzureConnection) diff --git a/.azure-devops/nightlybuild/mlz-bicep-azuregov-pipelines.yml b/.azure-devops/nightlybuild/mlz-bicep-azuregov-pipelines.yml index f658df6e2..07ec6da99 100644 --- a/.azure-devops/nightlybuild/mlz-bicep-azuregov-pipelines.yml +++ b/.azure-devops/nightlybuild/mlz-bicep-azuregov-pipelines.yml @@ -2,6 +2,7 @@ # Licensed under the MIT License. schedules: + - cron: "0 4 * * *" displayName: "Nightly - mlz bicep azure US Gov Cloud" branches: @@ -10,124 +11,24 @@ schedules: always: true pool: - vmImage: ubuntu-latest -variables: - GServiceConnectionName: $(GAzureConnection) + vmImage: ubuntu-latest jobs: -- job: bicepGovCloud - steps: - - task: AzureCLI@2 - displayName: "Deploy MLZ Bicep" - inputs: - azureSubscription: $(GServiceConnectionName) - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - datetime=$(date +%s) # gets the current date time as an epoch - az deployment sub create \ - --name $(bDeploymentName) \ - --location $(GLocation) \ - --template-file $(TemplateFile) \ - --parameters resourcePrefix=$datetime - - - task: AzureCLI@2 - displayName: "Generate deploymentVariables.json for all addons and examples" - inputs: - azureSubscription: $(GServiceConnectionName) - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - az deployment sub show \ - --name $(bDeploymentName) \ - --query properties.outputs \ - > $(Build.SourcesDirectory)/src/bicep/examples/deploymentVariables.json - - - task: AzureCLI@2 - displayName: "Extract Values and Hydrate Variables for T3 Deployment" - inputs: - azureSubscription: $(GServiceConnectionName) - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - deploymentoutput=$(az deployment sub show \ - --name $(bDeploymentName) \ - --query '{ - hubSubId:properties.outputs.hub.value.subscriptionId, - hubRGroupName:properties.outputs.hub.value.resourceGroupName, - hubVNetworkName:properties.outputs.hub.value.virtualNetworkName, - hubVNetworkResourceId:properties.outputs.hub.value.virtualNetworkResourceId, - logAWspaceResourceId:properties.outputs.logAnalyticsWorkspaceResourceId.value, - firewallPrivateIP:properties.outputs.firewallPrivateIPAddress.value }' \ - --output json) - hubSubId=$(echo $deploymentoutput | jq '.hubSubId') \ - && echo "##vso[task.setvariable variable=hubSubscriptionId;]$hubSubId" - - hubRGroupName=$(echo $deploymentoutput | jq '.hubRGroupName') \ - && echo "##vso[task.setvariable variable=hubResourceGroupName;]$hubRGroupName" - - hubVNetworkName=$(echo $deploymentoutput | jq '.hubVNetworkName') \ - && echo "##vso[task.setvariable variable=hubVirtualNetworkName;]$hubVNetworkName" - - hubVNetworkResourceId=$(echo $deploymentoutput | jq '.hubVNetworkResourceId') \ - && echo "##vso[task.setvariable variable=hubVirtualNetworkResourceId;]$hubVNetworkResourceId" - - logAWspaceResourceId=$(echo $deploymentoutput | jq '.logAWspaceResourceId') \ - && echo "##vso[task.setvariable variable=logAnalyticsWorkspaceResourceId;]$logAWspaceResourceId" - - firewallPrivateIP=$(echo $deploymentoutput | jq '.firewallPrivateIP') \ - && echo "##vso[task.setvariable variable=firewallPrivateIPAddress;]$firewallPrivateIP" +- job: bicepGovCloud + displayName: "Nightly deployment of Mission LZ Bicep on AzureUsGovernment" - - task: AzureCLI@2 - displayName: "T3 Bicep Deployment" - inputs: - azureSubscription: $(GServiceConnectionName) - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - az deployment sub create \ - --subscription $(GSubId) \ - --location $(GLocation) \ - --name $(workloadName) \ - --template-file $(T3TemplateFile) \ - --parameters \ - workloadName=$(workloadName) \ - hubSubscriptionId=$(hubSubscriptionId) \ - hubResourceGroupName=$(hubResourceGroupName) \ - hubVirtualNetworkName=$(hubVirtualNetworkName) \ - hubVirtualNetworkResourceId=$(hubVirtualNetworkResourceId) \ - logAnalyticsWorkspaceResourceId=$(logAnalyticsWorkspaceResourceId) \ - firewallPrivateIPAddress=$(firewallPrivateIPAddress) - - - task: AzureCLI@2 - displayName: "Clean up Subscription Diagnostics Settings" - condition: always() - inputs: - azureSubscription: $(GServiceConnectionName) - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - az monitor diagnostic-settings subscription list \ - --query "value[].name" \ - --output tsv \ - | xargs -t -I % az monitor diagnostic-settings subscription delete \ - --yes \ - --name % + steps: - - task: AzureCLI@2 - displayName: "Clean up Resources" - condition: always() - inputs: - azureSubscription: $(GServiceConnectionName) - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - az group list \ - --query "[].name" \ - --output tsv \ - | xargs -t -I % az group delete \ - --yes \ - --no-wait \ - --name % + - template: templates/az-deployment.yml + parameters: + ServiceConnectionName: $(GAzureConnection) + DeploymentName: $(bDeploymentName) + Location: $(GLocation) + WorkloadSubId: $(GSubId) + WorkloadName: $(workloadName) + + - template: templates/clean-az-subscription.yml + parameters: + serviceConnectionName: $(GAzureConnection) diff --git a/.azure-devops/nightlybuild/mlz-tf-azurecloud-pipelines.yml b/.azure-devops/nightlybuild/mlz-tf-azurecloud-pipelines.yml index 906662efd..d87891a1c 100644 --- a/.azure-devops/nightlybuild/mlz-tf-azurecloud-pipelines.yml +++ b/.azure-devops/nightlybuild/mlz-tf-azurecloud-pipelines.yml @@ -2,6 +2,7 @@ # Licensed under the MIT License. schedules: + - cron: "0 2 * * *" displayName: "Nightly - mlz Terraform azure cloud" branches: @@ -10,122 +11,27 @@ schedules: always: true pool: - vmImage: ubuntu-latest -variables: - ServiceConnectionName: $(CAzureConnection) + vmImage: ubuntu-latest jobs: -- job: CommercialCloud_TF - steps: - - task: TerraformInstaller@0 - inputs: - terraformVersion: 'latest' - - task: AzureCLI@2 - displayName: "Apply MLZ Terraform" - inputs: - azureSubscription: $(CAzureConnection) - scriptType: 'bash' - scriptLocation: 'inlineScript' - addSpnToEnvironment: true - inlineScript: | - export ARM_CLIENT_ID=$(ClientId) - export ARM_CLIENT_SECRET=$(ClientSecret) - export ARM_SUBSCRIPTION_ID=$(subId) - export ARM_TENANT_ID=$(tenantId) - terraform init - terraform plan -var "hub_subid=$(subid)" -input=false - terraform apply -var "hub_subid=$(subid)" -auto-approve -input=false - workingDirectory: '$(System.DefaultWorkingDirectory)/src/terraform/mlz' - useGlobalConfig: true - - - task: AzureCLI@2 - displayName: "Extract Values and Hydrate Variables for T3 Deployment" - inputs: - azureSubscription: $(CAzureConnection) - scriptType: 'bash' - scriptLocation: 'inlineScript' - addSpnToEnvironment: true - inlineScript: | - echo "##vso[task.setvariable variable=hubSubscriptionId;]$(terraform output -raw hub_subid)" - echo "##vso[task.setvariable variable=hubVirtualNetworkName;]$(terraform output -raw hub_vnetname)" - echo "##vso[task.setvariable variable=hubResourceGroupName;]$(terraform output -raw hub_rgname)" - echo "##vso[task.setvariable variable=firewallPrivateIPAddress;]$(terraform output -raw firewall_private_ip)" - echo "##vso[task.setvariable variable=lawsName;]$(terraform output -raw laws_name)" - echo "##vso[task.setvariable variable=lawsRgName;]$(terraform output -raw laws_rgname)" - echo "##vso[task.setvariable variable=tier1SubId;]$(terraform output -raw tier1_subid)" - echo "##vso[task.setvariable variable=tier3SubId;]$(terraform output -raw tier1_subid)" - workingDirectory: '$(System.DefaultWorkingDirectory)/src/terraform/mlz' - useGlobalConfig: true - - - task: AzureCLI@2 - displayName: "Apply T3 Workload Terraform" - inputs: - azureSubscription: $(CAzureConnection) - scriptType: 'bash' - scriptLocation: 'inlineScript' - addSpnToEnvironment: true - inlineScript: | - export ARM_CLIENT_ID=$(ClientId) - export ARM_CLIENT_SECRET=$(ClientSecret) - export ARM_SUBSCRIPTION_ID=$(subId) - export ARM_TENANT_ID=$(tenantId) - terraform init - terraform apply -var "hub_subid=$(hubSubscriptionId)" \ - -var "hub_rgname=$(hubResourceGroupName)" \ - -var "firewall_private_ip=$(firewallPrivateIPAddress)" \ - -var "hub_vnetname=$(hubVirtualNetworkName)" \ - -var "laws_name=$(lawsName)" -var "laws_rgname=$(lawsRgName)" \ - -var "tier1_subid=$(tier1SubId)" \ - -var "tier3_subid=$(tier3SubId)" \ - -auto-approve \ - -input=false - workingDirectory: '$(System.DefaultWorkingDirectory)/src/terraform/tier3' - useGlobalConfig: true +- job: CommercialCloud_TF + displayName: "Nightly deployment of Mission LZ Terraform on AzureCloud" - - task: AzureCLI@2 - displayName: "Destroy T3 Workload Terraform" - condition: always() - inputs: - azureSubscription: $(CAzureConnection) - scriptType: 'bash' - scriptLocation: 'inlineScript' - addSpnToEnvironment: true - inlineScript: | - export ARM_CLIENT_ID=$(ClientId) - export ARM_CLIENT_SECRET=$(ClientSecret) - export ARM_SUBSCRIPTION_ID=$(subId) - export ARM_TENANT_ID=$(tenantId) - terraform init - terraform destroy -var "hub_subid=$(hubSubscriptionId)" \ - -var "hub_rgname=$(hubResourceGroupName)" \ - -var "firewall_private_ip=$(firewallPrivateIPAddress)" \ - -var "hub_vnetname=$(hubVirtualNetworkName)" \ - -var "laws_name=$(lawsName)" \ - -var "laws_rgname=$(lawsRgName)" \ - -var "tier1_subid=$(tier1SubId)" \ - -var "tier3_subid=$(tier3SubId)" \ - -auto-approve \ - -input=false - workingDirectory: '$(System.DefaultWorkingDirectory)/src/terraform/tier3' - useGlobalConfig: true + steps: - - task: AzureCLI@2 - displayName: "Destroy MLZ Terraform" - condition: always() - inputs: - azureSubscription: $(CAzureConnection) - scriptType: 'bash' - scriptLocation: 'inlineScript' - addSpnToEnvironment: true - inlineScript: | - export ARM_CLIENT_ID=$(ClientId) - export ARM_CLIENT_SECRET=$(ClientSecret) - export ARM_SUBSCRIPTION_ID=$(subId) - export ARM_TENANT_ID=$(tenantId) - terraform init - terraform destroy -var "hub_subid=$(subid)" -auto-approve -input=false - workingDirectory: '$(System.DefaultWorkingDirectory)/src/terraform/mlz' - useGlobalConfig: true - \ No newline at end of file + - template: templates/terraform-apply.yml + parameters: + ServiceConnectionName: $(CAzureConnection) + ClientId: $(ClientId) + ClientSecret: $(ClientSecret) + SubscriptionId: $(CSubId) + TenantId: $(CTenantId) + Environment: $(CCloudEnv) + MetadataHost: $(CMetadataHost) + Location: $(CLocation) + + - template: templates/clean-az-subscription.yml + parameters: + serviceConnectionName: $(CAzureConnection) diff --git a/.azure-devops/nightlybuild/mlz-tf-azuregov-pipelines.yml b/.azure-devops/nightlybuild/mlz-tf-azuregov-pipelines.yml index fb9b1ce6b..1c64ef14f 100644 --- a/.azure-devops/nightlybuild/mlz-tf-azuregov-pipelines.yml +++ b/.azure-devops/nightlybuild/mlz-tf-azuregov-pipelines.yml @@ -12,145 +12,24 @@ schedules: pool: vmImage: ubuntu-latest -variables: - GServiceConnectionName: $(GAzureConnection) - jobs: -- job: GovCloud_TF - steps: - - task: TerraformInstaller@0 - inputs: - terraformVersion: 'latest' - - - task: AzureCLI@2 - displayName: "Apply MLZ Terraform" - inputs: - azureSubscription: $(GAzureConnection) - scriptType: 'bash' - addSpnToEnvironment: true - scriptLocation: 'inlineScript' - inlineScript: | - export ARM_CLIENT_ID=$(GClientId) - export ARM_CLIENT_SECRET=$(GClientSecret) - export ARM_SUBSCRIPTION_ID=$(GSubId) - export ARM_TENANT_ID=$(GTenantId) - export ARM_ENVIRONMENT=$(CloudEnv) - terraform init - terraform plan \ - -var "hub_subid=$(GSubid)" \ - -var metadata_host=$(MetadataHost) \ - -var environment=$(CloudEnv) \ - -var location=$(GLocation) \ - -input=false - terraform apply -var "hub_subid=$(GSubid)" \ - -var metadata_host=$(MetadataHost) \ - -var environment=$(CloudEnv) \ - -var location=$(GLocation) \ - -auto-approve \ - -input=false - workingDirectory: '$(System.DefaultWorkingDirectory)/src/terraform/mlz' - useGlobalConfig: true - - task: AzureCLI@2 - displayName: "Extract Values and Hydrate Variables for T3 Deployment" - inputs: - azureSubscription: $(GAzureConnection) - scriptType: 'bash' - scriptLocation: 'inlineScript' - addSpnToEnvironment: true - inlineScript: | - echo "##vso[task.setvariable variable=hubSubscriptionId;]$(terraform output -raw hub_subid)" - echo "##vso[task.setvariable variable=hubVirtualNetworkName;]$(terraform output -raw hub_vnetname)" - echo "##vso[task.setvariable variable=hubResourceGroupName;]$(terraform output -raw hub_rgname)" - echo "##vso[task.setvariable variable=firewallPrivateIPAddress;]$(terraform output -raw firewall_private_ip)" - echo "##vso[task.setvariable variable=lawsName;]$(terraform output -raw laws_name)" - echo "##vso[task.setvariable variable=lawsRgName;]$(terraform output -raw laws_rgname)" - echo "##vso[task.setvariable variable=tier1SubId;]$(terraform output -raw tier1_subid)" - echo "##vso[task.setvariable variable=tier3SubId;]$(terraform output -raw tier1_subid)" - workingDirectory: '$(System.DefaultWorkingDirectory)/src/terraform/mlz' - useGlobalConfig: true - - - task: AzureCLI@2 - displayName: "Apply T3 Workload Terraform" - inputs: - azureSubscription: $(GAzureConnection) - scriptType: 'bash' - scriptLocation: 'inlineScript' - addSpnToEnvironment: true - inlineScript: | - export ARM_CLIENT_ID=$(GClientId) - export ARM_CLIENT_SECRET=$(GClientSecret) - export ARM_SUBSCRIPTION_ID=$(GSubId) - export ARM_TENANT_ID=$(GTenantId) - export ARM_ENVIRONMENT=$(CloudEnv) - terraform init - terraform apply -var "hub_subid=$(hubSubscriptionId)" \ - -var metadata_host=$(MetadataHost) \ - -var environment=$(CloudEnv) \ - -var location=$(GLocation) \ - -var "hub_rgname=$(hubResourceGroupName)" \ - -var "firewall_private_ip=$(firewallPrivateIPAddress)" \ - -var "hub_vnetname=$(hubVirtualNetworkName)" \ - -var "laws_name=$(lawsName)" \ - -var "laws_rgname=$(lawsRgName)" \ - -var "tier1_subid=$(tier1SubId)" \ - -var "tier3_subid=$(tier3SubId)" \ - -auto-approve \ - -input=false - workingDirectory: '$(System.DefaultWorkingDirectory)/src/terraform/tier3' - useGlobalConfig: true +- job: GovCloud_TF + displayName: "Nightly deployment of Mission LZ Terraform on AzureUsGovernment" - - task: AzureCLI@2 - displayName: "Destroy T3 Workload Terraform" - condition: always() - inputs: - azureSubscription: $(GAzureConnection) - scriptType: 'bash' - scriptLocation: 'inlineScript' - addSpnToEnvironment: true - inlineScript: | - export ARM_CLIENT_ID=$(GClientId) - export ARM_CLIENT_SECRET=$(GClientSecret) - export ARM_SUBSCRIPTION_ID=$(GSubId) - export ARM_TENANT_ID=$(GTenantId) - export ARM_ENVIRONMENT=$(CloudEnv) - terraform init - terraform destroy -var "hub_subid=$(hubSubscriptionId)" \ - -var metadata_host=$(MetadataHost) \ - -var environment=$(CloudEnv) \ - -var location=$(GLocation) \ - -var "hub_rgname=$(hubResourceGroupName)" \ - -var "firewall_private_ip=$(firewallPrivateIPAddress)" \ - -var "hub_vnetname=$(hubVirtualNetworkName)" \ - -var "laws_name=$(lawsName)" \ - -var "laws_rgname=$(lawsRgName)" \ - -var "tier1_subid=$(tier1SubId)" \ - -var "tier3_subid=$(tier3SubId)" \ - -auto-approve \ - -input=false - workingDirectory: '$(System.DefaultWorkingDirectory)/src/terraform/tier3' - useGlobalConfig: true + steps: - - task: AzureCLI@2 - displayName: "Destroy MLZ Terraform" - condition: always() - inputs: - azureSubscription: $(GAzureConnection) - scriptType: 'bash' - addSpnToEnvironment: true - scriptLocation: 'inlineScript' - inlineScript: | - export ARM_CLIENT_ID=$(GClientId) - export ARM_CLIENT_SECRET=$(GClientSecret) - export ARM_SUBSCRIPTION_ID=$(GSubId) - export ARM_TENANT_ID=$(GTenantId) - export ARM_ENVIRONMENT=$(CloudEnv) - terraform init - terraform destroy -var "hub_subid=$(GSubid)" \ - -var metadata_host=$(MetadataHost) \ - -var environment=$(CloudEnv) \ - -var location=$(GLocation) \ - -auto-approve \ - -input=false - workingDirectory: '$(System.DefaultWorkingDirectory)/src/terraform/mlz' - useGlobalConfig: true + - template: templates/terraform-apply.yml + parameters: + ServiceConnectionName: $(GAzureConnection) + ClientId: $(GClientId) + ClientSecret: $(GClientSecret) + SubscriptionId: $(GSubId) + TenantId: $(GTenantId) + Environment: $(GCloudEnv) + MetadataHost: $(GMetadataHost) + Location: $(GLocation) + + - template: templates/clean-az-subscription.yml + parameters: + serviceConnectionName: $(GAzureConnection) diff --git a/.azure-devops/nightlybuild/templates/az-deployment.yml b/.azure-devops/nightlybuild/templates/az-deployment.yml new file mode 100644 index 000000000..cbec1963a --- /dev/null +++ b/.azure-devops/nightlybuild/templates/az-deployment.yml @@ -0,0 +1,101 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +parameters: + +- name: ServiceConnectionName + type: string +- name: DeploymentName + type: string +- name: Location + type: string +- name: WorkloadSubId + type: string +- name: WorkloadName + type: string + +steps: + + - task: AzureCLI@2 + displayName: "Deploy MLZ Bicep" + inputs: + azureSubscription: ${{ parameters.ServiceConnectionName }} + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + datetime=$(date +%s) # gets the current date time as an epoch + az deployment sub create \ + --name ${{ parameters.DeploymentName }} \ + --location ${{ parameters.Location }} \ + --template-file $(Build.SourcesDirectory)/src/bicep/mlz.bicep \ + --parameters resourcePrefix=$datetime + + - task: AzureCLI@2 + displayName: "Generate deploymentVariables.json for all addons and examples" + inputs: + azureSubscription: ${{ parameters.ServiceConnectionName }} + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + az deployment sub show \ + --name ${{ parameters.DeploymentName }} \ + --query properties.outputs \ + > $(Build.SourcesDirectory)/src/bicep/examples/deploymentVariables.json + + - task: AzureCLI@2 + displayName: "Extract Values and Hydrate Variables for T3 Deployment" + inputs: + azureSubscription: ${{ parameters.ServiceConnectionName }} + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + deploymentoutput=$(az deployment sub show \ + --name ${{ parameters.DeploymentName }} \ + --query '{ + hubSubId: properties.outputs.hub.value.subscriptionId, + hubRGroupName: properties.outputs.hub.value.resourceGroupName, + hubVNetworkName: properties.outputs.hub.value.virtualNetworkName, + hubVNetworkResourceId: properties.outputs.hub.value.virtualNetworkResourceId, + logAWspaceResourceId: properties.outputs.logAnalyticsWorkspaceResourceId.value, + firewallPrivateIP: properties.outputs.firewallPrivateIPAddress.value + }' \ + --output json) + + hubSubId=$(echo $deploymentoutput | jq '.hubSubId') \ + && echo "##vso[task.setvariable variable=hubSubscriptionId;]$hubSubId" + + hubRGroupName=$(echo $deploymentoutput | jq '.hubRGroupName') \ + && echo "##vso[task.setvariable variable=hubResourceGroupName;]$hubRGroupName" + + hubVNetworkName=$(echo $deploymentoutput | jq '.hubVNetworkName') \ + && echo "##vso[task.setvariable variable=hubVirtualNetworkName;]$hubVNetworkName" + + hubVNetworkResourceId=$(echo $deploymentoutput | jq '.hubVNetworkResourceId') \ + && echo "##vso[task.setvariable variable=hubVirtualNetworkResourceId;]$hubVNetworkResourceId" + + logAWspaceResourceId=$(echo $deploymentoutput | jq '.logAWspaceResourceId') \ + && echo "##vso[task.setvariable variable=logAnalyticsWorkspaceResourceId;]$logAWspaceResourceId" + + firewallPrivateIP=$(echo $deploymentoutput | jq '.firewallPrivateIP') \ + && echo "##vso[task.setvariable variable=firewallPrivateIPAddress;]$firewallPrivateIP" + + - task: AzureCLI@2 + displayName: "T3 Bicep Deployment" + inputs: + azureSubscription: ${{ parameters.ServiceConnectionName }} + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + az deployment sub create \ + --subscription ${{ parameters.WorkloadSubId }} \ + --location ${{ parameters.Location }} \ + --name ${{ parameters.WorkloadName }} \ + --template-file $(Build.SourcesDirectory)/src/bicep/examples/newWorkload/newWorkload.bicep \ + --parameters \ + workloadName=${{ parameters.WorkloadName }} \ + hubSubscriptionId=$(hubSubscriptionId) \ + hubResourceGroupName=$(hubResourceGroupName) \ + hubVirtualNetworkName=$(hubVirtualNetworkName) \ + hubVirtualNetworkResourceId=$(hubVirtualNetworkResourceId) \ + logAnalyticsWorkspaceResourceId=$(logAnalyticsWorkspaceResourceId) \ + firewallPrivateIPAddress=$(firewallPrivateIPAddress) diff --git a/.azure-devops/nightlybuild/templates/clean-az-subscription.yml b/.azure-devops/nightlybuild/templates/clean-az-subscription.yml new file mode 100644 index 000000000..9086b358e --- /dev/null +++ b/.azure-devops/nightlybuild/templates/clean-az-subscription.yml @@ -0,0 +1,40 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +parameters: + +- name: ServiceConnectionName + type: string + +steps: + +- task: AzureCLI@2 + displayName: "Delete All Diagnostics Settings in Subscription" + condition: always() + inputs: + azureSubscription: ${{ parameters.ServiceConnectionName }} + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + az monitor diagnostic-settings subscription list \ + --query "value[].name" \ + --output tsv \ + | xargs -t -I % az monitor diagnostic-settings subscription delete \ + --yes \ + --name % + +- task: AzureCLI@2 + displayName: "Delete All Resource Groups in Subscription" + condition: always() + inputs: + azureSubscription: ${{ parameters.ServiceConnectionName }} + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + az group list \ + --query "[].name" \ + --output tsv \ + | xargs -t -I % az group delete \ + --yes \ + --no-wait \ + --name % diff --git a/.azure-devops/nightlybuild/templates/terraform-apply.yml b/.azure-devops/nightlybuild/templates/terraform-apply.yml new file mode 100644 index 000000000..7aa4dffbd --- /dev/null +++ b/.azure-devops/nightlybuild/templates/terraform-apply.yml @@ -0,0 +1,105 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +parameters: + +- name: ServiceConnectionName + type: string +- name: ClientId + type: string +- name: ClientSecret + type: string +- name: SubscriptionId + type: string +- name: TenantId + type: string +- name: Environment + type: string +- name: MetadataHost + type: string +- name: Location + type: string + +steps: + + - task: TerraformInstaller@0 + inputs: + terraformVersion: 'latest' + + - task: AzureCLI@2 + displayName: "Apply MLZ Terraform" + inputs: + azureSubscription: ${{ parameters.ServiceConnectionName }} + scriptType: 'bash' + addSpnToEnvironment: true + scriptLocation: 'inlineScript' + inlineScript: | + export ARM_CLIENT_ID=${{ parameters.ClientId }} + export ARM_CLIENT_SECRET=${{ parameters.ClientSecret }} + export ARM_SUBSCRIPTION_ID=${{ parameters.SubscriptionId }} + export ARM_TENANT_ID=${{ parameters.TenantId }} + export ARM_ENVIRONMENT=${{ parameters.Environment }} + terraform init + terraform plan \ + -var "hub_subid=${{ parameters.SubscriptionId }}" \ + -var metadata_host=${{ parameters.MetadataHost}} \ + -var environment=${{ parameters.Environment }} \ + -var location=${{ parameters.Location }} \ + -input=false + terraform apply -var "hub_subid=${{ parameters.SubscriptionId }}" \ + -var metadata_host=${{ parameters.MetadataHost}} \ + -var environment=${{ parameters.Environment }} \ + -var location=${{ parameters.Location }} \ + -auto-approve \ + -input=false + workingDirectory: '$(System.DefaultWorkingDirectory)/src/terraform/mlz' + useGlobalConfig: true + + - task: AzureCLI@2 + displayName: "Extract Values and Hydrate Variables for T3 Deployment" + inputs: + azureSubscription: ${{ parameters.ServiceConnectionName }} + scriptType: 'bash' + scriptLocation: 'inlineScript' + addSpnToEnvironment: true + inlineScript: | + echo "##vso[task.setvariable variable=hubSubscriptionId;]$(terraform output -raw hub_subid)" + echo "##vso[task.setvariable variable=hubVirtualNetworkName;]$(terraform output -raw hub_vnetname)" + echo "##vso[task.setvariable variable=hubResourceGroupName;]$(terraform output -raw hub_rgname)" + echo "##vso[task.setvariable variable=firewallPrivateIPAddress;]$(terraform output -raw firewall_private_ip)" + echo "##vso[task.setvariable variable=lawsName;]$(terraform output -raw laws_name)" + echo "##vso[task.setvariable variable=lawsRgName;]$(terraform output -raw laws_rgname)" + echo "##vso[task.setvariable variable=tier1SubId;]$(terraform output -raw tier1_subid)" + echo "##vso[task.setvariable variable=tier3SubId;]$(terraform output -raw tier1_subid)" + workingDirectory: '$(System.DefaultWorkingDirectory)/src/terraform/mlz' + useGlobalConfig: true + + - task: AzureCLI@2 + displayName: "Apply T3 Workload Terraform" + inputs: + azureSubscription: ${{ parameters.ServiceConnectionName }} + scriptType: 'bash' + scriptLocation: 'inlineScript' + addSpnToEnvironment: true + inlineScript: | + export ARM_CLIENT_ID=${{ parameters.ClientId }} + export ARM_CLIENT_SECRET=${{ parameters.ClientSecret }} + export ARM_SUBSCRIPTION_ID=${{ parameters.SubscriptionId }} + export ARM_TENANT_ID=${{ parameters.TenantId }} + export ARM_ENVIRONMENT=${{ parameters.Environment }} + terraform init + terraform apply -var "hub_subid=$(hubSubscriptionId)" \ + -var metadata_host=${{ parameters.MetadataHost}} \ + -var environment=${{ parameters.Environment }} \ + -var location=${{ parameters.Location }} \ + -var "hub_rgname=$(hubResourceGroupName)" \ + -var "firewall_private_ip=$(firewallPrivateIPAddress)" \ + -var "hub_vnetname=$(hubVirtualNetworkName)" \ + -var "laws_name=$(lawsName)" \ + -var "laws_rgname=$(lawsRgName)" \ + -var "tier1_subid=$(tier1SubId)" \ + -var "tier3_subid=$(tier3SubId)" \ + -auto-approve \ + -input=false + workingDirectory: '$(System.DefaultWorkingDirectory)/src/terraform/tier3' + useGlobalConfig: true diff --git a/.azure-devops/prbuild/mlz-pr-bicep-azurecloud-pipelines.yml b/.azure-devops/prbuild/mlz-pr-bicep-azurecloud-pipelines.yml index ebcd08483..edc5bbc0d 100644 --- a/.azure-devops/prbuild/mlz-pr-bicep-azurecloud-pipelines.yml +++ b/.azure-devops/prbuild/mlz-pr-bicep-azurecloud-pipelines.yml @@ -13,22 +13,14 @@ pr: pool: vmImage: ubuntu-latest -variables: - ServiceConnectionName: $(CAzureConnection) - jobs: + - job: bicepCommercialCloud + displayName: "PR Checks for Mission LZ Bicep on AzureCloud" + steps: - - task: AzureCLI@2 - displayName: "What-if Bicep" - inputs: - azureSubscription: $(ServiceConnectionName) - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - datetime=$(date +%s) # gets the current date time as an epoch - az deployment sub what-if \ - --name $(bDeploymentName) \ - --location $(Location) \ - --template-file $(TemplateFile) \ - --parameters resourcePrefix=$datetime + - template: templates/az-what-if.yml + parameters: + ServiceConnectionName: $(CAzureConnection) + DeploymentName: $(bDeploymentName) + Location: $(CLocation) diff --git a/.azure-devops/prbuild/mlz-pr-bicep-azuregov-pipelines.yml b/.azure-devops/prbuild/mlz-pr-bicep-azuregov-pipelines.yml index 5d033c2b4..503f543aa 100644 --- a/.azure-devops/prbuild/mlz-pr-bicep-azuregov-pipelines.yml +++ b/.azure-devops/prbuild/mlz-pr-bicep-azuregov-pipelines.yml @@ -13,22 +13,14 @@ pr: pool: vmImage: ubuntu-latest -variables: - GServiceConnectionName: $(GAzureConnection) - jobs: + - job: bicepGovCloud + displayName: "PR Checks for Mission LZ Bicep on AzureUsGovernment" + steps: - - task: AzureCLI@2 - displayName: "What-if Bicep" - inputs: - azureSubscription: $(GServiceConnectionName) - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - datetime=$(date +%s) # gets the current date time as an epoch - az deployment sub what-if \ - --name $(bDeploymentName) \ - --location $(GLocation) \ - --template-file $(TemplateFile) \ - --parameters resourcePrefix=$datetime + - template: templates/az-what-if.yml + parameters: + ServiceConnectionName: $(GAzureConnection) + DeploymentName: $(bDeploymentName) + Location: $(GLocation) diff --git a/.azure-devops/prbuild/mlz-pr-tf-azurecloud-pipelines.yml b/.azure-devops/prbuild/mlz-pr-tf-azurecloud-pipelines.yml index 383f03b8e..6b9c3bb5f 100644 --- a/.azure-devops/prbuild/mlz-pr-tf-azurecloud-pipelines.yml +++ b/.azure-devops/prbuild/mlz-pr-tf-azurecloud-pipelines.yml @@ -13,28 +13,19 @@ pr: pool: vmImage: ubuntu-latest -variables: - ServiceConnectionName: $(CAzureConnection) - jobs: + - job: CommercialCloud_TF + displayName: "PR Checks for Mission LZ Terraform on AzureCloud" + steps: - - task: TerraformInstaller@0 - inputs: - terraformVersion: 'latest' - - task: AzureCLI@2 - displayName: "Terraform Plan" - inputs: - azureSubscription: $(CAzureConnection) - scriptType: 'bash' - scriptLocation: 'inlineScript' - addSpnToEnvironment: true - inlineScript: | - export ARM_CLIENT_ID=$(ClientId) - export ARM_CLIENT_SECRET=$(ClientSecret) - export ARM_SUBSCRIPTION_ID=$(subId) - export ARM_TENANT_ID=$(tenantId) - terraform init - terraform plan -var "hub_subid=$(subid)" -input=false - workingDirectory: '$(System.DefaultWorkingDirectory)/src/terraform/mlz' - useGlobalConfig: true + - template: templates/terraform-plan.yml + parameters: + ServiceConnectionName: $(CAzureConnection) + ClientId: $(ClientId) + ClientSecret: $(ClientSecret) + SubscriptionId: $(CSubId) + TenantId: $(CTenantId) + Environment: $(CCloudEnv) + MetadataHost: $(CMetadataHost) + Location: $(CLocation) diff --git a/.azure-devops/prbuild/mlz-pr-tf-azuregov-pipelines.yml b/.azure-devops/prbuild/mlz-pr-tf-azuregov-pipelines.yml index be619bd03..7a793e8d4 100644 --- a/.azure-devops/prbuild/mlz-pr-tf-azuregov-pipelines.yml +++ b/.azure-devops/prbuild/mlz-pr-tf-azuregov-pipelines.yml @@ -13,29 +13,19 @@ pr: pool: vmImage: ubuntu-latest -variables: - GServiceConnectionName: $(GAzureConnection) - jobs: + - job: GovCloud_TF + displayName: "PR Checks for Mission LZ Terraform on AzureUsGovernment" + steps: - - task: TerraformInstaller@0 - inputs: - terraformVersion: 'latest' - - task: AzureCLI@2 - displayName: "Terraform Plan" - inputs: - azureSubscription: $(GAzureConnection) - scriptType: 'bash' - addSpnToEnvironment: true - scriptLocation: 'inlineScript' - inlineScript: | - export ARM_CLIENT_ID=$(GClientId) - export ARM_CLIENT_SECRET=$(GClientSecret) - export ARM_SUBSCRIPTION_ID=$(GSubId) - export ARM_TENANT_ID=$(GTenantId) - export ARM_ENVIRONMENT=$(CloudEnv) - terraform init - terraform plan -var "hub_subid=$(GSubid)" -var metadata_host=$(MetadataHost) -var environment=$(CloudEnv) -var location=$(GLocation) -input=false - workingDirectory: '$(System.DefaultWorkingDirectory)/src/terraform/mlz' - useGlobalConfig: true + - template: templates/terraform-plan.yml + parameters: + ServiceConnectionName: $(GAzureConnection) + ClientId: $(GClientId) + ClientSecret: $(GClientSecret) + SubscriptionId: $(GSubId) + TenantId: $(GTenantId) + Environment: $(GCloudEnv) + MetadataHost: $(GMetadataHost) + Location: $(GLocation) diff --git a/.azure-devops/prbuild/templates/az-what-if.yml b/.azure-devops/prbuild/templates/az-what-if.yml new file mode 100644 index 000000000..0ed231bfb --- /dev/null +++ b/.azure-devops/prbuild/templates/az-what-if.yml @@ -0,0 +1,26 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +parameters: + +- name: ServiceConnectionName + type: string +- name: DeploymentName + type: string +- name: Location + type: string + +steps: + - task: AzureCLI@2 + displayName: "What-if Bicep" + inputs: + azureSubscription: ${{ parameters.ServiceConnectionName }} + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + datetime=$(date +%s) # gets the current date time as an epoch + az deployment sub what-if \ + --name ${{ parameters.DeploymentName }} \ + --location ${{ parameters.Location }} \ + --template-file $(Build.SourcesDirectory)/src/bicep/mlz.bicep \ + --parameters resourcePrefix=$datetime diff --git a/.azure-devops/prbuild/templates/terraform-plan.yml b/.azure-devops/prbuild/templates/terraform-plan.yml new file mode 100644 index 000000000..db5afa388 --- /dev/null +++ b/.azure-devops/prbuild/templates/terraform-plan.yml @@ -0,0 +1,51 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +parameters: + +- name: ServiceConnectionName + type: string +- name: ClientId + type: string +- name: ClientSecret + type: string +- name: SubscriptionId + type: string +- name: TenantId + type: string +- name: Environment + type: string +- name: MetadataHost + type: string +- name: Location + type: string + +steps: + + - task: TerraformInstaller@0 + displayName: "Install Terraform" + inputs: + terraformVersion: 'latest' + + - task: AzureCLI@2 + displayName: "Terraform Plan" + inputs: + azureSubscription: ${{ parameters.ServiceConnectionName }} + scriptType: 'bash' + addSpnToEnvironment: true + scriptLocation: 'inlineScript' + inlineScript: | + export ARM_CLIENT_ID=${{ parameters.ClientId }} + export ARM_CLIENT_SECRET=${{ parameters.ClientSecret }} + export ARM_SUBSCRIPTION_ID=${{ parameters.SubscriptionId }} + export ARM_TENANT_ID=${{ parameters.TenantId }} + export ARM_ENVIRONMENT=${{ parameters.Environment }} + terraform init + terraform plan \ + -var 'hub_subid=${{ parameters.SubscriptionId }}' \ + -var 'metadata_host=${{ parameters.MetadataHost }}' \ + -var 'environment=${{ parameters.Environment }}' \ + -var 'location=${{ parameters.Location }}' \ + -input=false + workingDirectory: '$(System.DefaultWorkingDirectory)/src/terraform/mlz' + useGlobalConfig: true diff --git a/.gitignore b/.gitignore index a7264cb4e..7606db2ba 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ crash.log # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan # example: *tfplan* *plan* +!terraform-plan.yml !src/bicep/** *.plan*