From f66ae2924de6a7a7bbe2125cb157a3bf22c9fecb Mon Sep 17 00:00:00 2001 From: Kimmo Forss Date: Wed, 23 Oct 2024 15:03:44 +0300 Subject: [PATCH] Bring in HotFix repairs (#651) * Refactor deploy control plane script to remove unnecessary Terraform installation and Azure CLI installation * Refactor deploy control plane script to include sourcing deploy_server.sh and fixing Terraform ownership * Refactor deploy control plane script to include sourcing deploy_server.sh and fixing Terraform ownership * Refactor deploy control plane script to include azurerm_role_assignment for deployer and storage_sapbits_contributor * Refactor deploy control plane script to remove unnecessary Terraform installation and Azure CLI installation * Refactor deploy control plane script to include sourcing deploy_server.sh and fixing Terraform ownership * Refactor deploy control plane script to include dynamic role assignment based on VM count * Refactor deploy scripts to simplify checkIfCloudShell function * Refactor deploy control plane script to include dynamic role assignment based on VM count and use managed service identity (MSI) for authentication * Refactor deploy scripts to include sourcing deploy_server.sh and fixing Terraform ownership * Refactor deploy control plane script to include dynamic role assignment based on VM count and use managed service identity (MSI) for authentication * Refactor deploy control plane script to include dynamic role assignment based on VM count and use managed service identity (MSI) for authentication * handle the realfilepath and the scriptdir variables as they might be replaced with other values in child scripts * Refactor deploy_controlplane.sh to use managed service identity (MSI) for authentication * Refactor deploy_controlplane.sh to remove ARM_USE_MSI variable and use managed service identity (MSI) for authentication * Refactor deploy_utils.sh to remove ARM_USE_MSI variable and use managed service identity (MSI) for authentication * Refactor deploy_controlplane.sh to remove ARM_USE_MSI variable and use managed service identity (MSI) for authentication * Refactor deploy_controlplane.sh to use managed service identity (MSI) for authentication * Refactor installer.sh to include terraform output command * Refactor installer.sh to comment out unnecessary terraform output command * Refactor variables_local.tf to use client_id instead of id for service principal object_id * Refactor deploy_controlplane.sh to use managed service identity (MSI) for authentication and remove unnecessary ARM_USE_MSI variable * Refactor deploy_controlplane.sh to use managed service identity (MSI) for authentication * chore: include OpenSSF Scorecard badge * Refactor variables_local.tf to use client_id instead of id for service principal object_id Refactor installer.sh to comment out unnecessary terraform output command * Refactor pipeline script to use correct variable for workload ARM subscription ID * Refactor pipeline script to use correct variable for workload ARM subscription ID * Refactor pipeline script to include ARM_OBJECT_ID variable * Refactor pipeline script to use correct variable for workload ARM_CLIENT_ID * Refactor pipeline script to use correct variable for workload ARM_CLIENT_ID * check terraform when running in cloudshell * Refactor pipeline script to include missing variable checks * Refactor pipeline script to remove unnecessary variable checks * Refactor pipeline script to use correct variables for workload ARM_CLIENT_ID * Refactor pipeline script to use correct variables for workload ARM_CLIENT_ID * Refactor pipeline script to include missing variable checks * Refactor pipeline script to update echo statements for installation method * Refactor pipeline script to update echo statements for installation method * Refactor pipeline script to use correct variables for workload ARM_CLIENT_ID * Refactor pipeline script to update echo statements for installation method * Refactor pipeline script to update echo statements for installation method * Refactor pipeline script to update echo statements for installation method and use correct variables for workload ARM_CLIENT_ID * Refactor pipeline script to update echo statements for installation method and use correct variables for workload ARM_CLIENT_ID * Refactor pipeline script to update echo statements for installation method and use correct variables for workload ARM_CLIENT_ID * Refactor pipeline script to update echo statements for installation method and use correct variables for workload ARM_CLIENT_ID * Refactor pipeline script to update echo statements for installation method and use correct variables for workload ARM_CLIENT_ID * Refactor pipeline script * Refactor pipeline script to update echo statements for installation method and use correct variables for workload ARM_CLIENT_ID * Refactor pipeline script to update echo statements and export variables for installation method and workload ARM_CLIENT_ID * Refactor pipeline script to update PATH variable in deploy_controlplane.sh * Refactor pipeline script to update echo statements and export variables for installation method, workload ARM_CLIENT_ID, and Terraform state information * Refactor pipeline script to update echo statements and export variables for installation method, workload ARM_CLIENT_ID, and Terraform state information * Refactor pipeline script to update echo statement for displaying the key vault information * Refactor pipeline script to update echo statements and export variables for installation method, workload ARM_CLIENT_ID, and Terraform state information * Refactor pipeline script to update usage of Azure CLI command in installer.sh * Refactor pipeline script to update echo statements and export variables for installation method, workload ARM_CLIENT_ID, and Terraform state information * Refactor pipeline script to update echo statements and export variables for installation method, workload ARM_CLIENT_ID, and Terraform state information * Refactor pipeline script to update echo statements and export variables for installation method, workload ARM_CLIENT_ID, and Terraform state information * Refactor pipeline script to update echo statements and export variables for installation method, workload ARM_CLIENT_ID, and Terraform state information * Refactor pipeline script to update echo statements and export variables for installation method, workload ARM_CLIENT_ID, and Terraform state information * Refactor pipeline script to update echo statements and export variables for installation method, workload ARM_CLIENT_ID, and Terraform state information * Refactor pipeline script to update echo statements and export variables for installation method, workload ARM_CLIENT_ID, and Terraform state information * Refactor provider configuration to use Azure Key Vault for subscription ID retrieval * Fixes #1: Added a new line to the installer script * Refactor pipeline script to fix unzip command in deploy control plane stage * Refactor pipeline script to update echo statements and export variables for installation method, workload ARM_CLIENT_ID, and Terraform state information * Refactor deploy_controlplane.sh script to save deployer_tfstate_key in config information * remove the deployer provider * Refactor deploy_controlplane.sh script to use the azurerm.deployer provider for retrieving key vault secrets * Refactor tfvar_variables.tf to add "tags" variable for providing tags to all resources * Refactor providers.tf to use local variable for subscription_id in deployer provider * Refactor providers.tf to remove subscription_id from deployer provider * Refactor deploy_controlplane.sh script to use local variables for deployer and library state file keys * Refactor deploy_controlplane.sh script to use local variables for deployer and library state file keys * Refactor azurerm provider versions to 4.6.0 * Refactor deploy_controlplane.sh script to use local variables for deployer and library state file keys * Refactor deploy_controlplane.sh script to use local variables for deployer and library state file keys * Refactor deploy_controlplane.sh script to use local variables for deployer and library state file keys * Refactor az keyvault set-policy command in deploy_controlplane.sh script * Refactor az keyvault set-policy command in deploy_controlplane.sh script * Add SPN to workload zone key vault * Remove the permission setting from the pipeline * Refactor echo statements in script_helpers.sh and installer.sh * Refactor echo statements in script_helpers.sh and installer.sh * Refactor echo statements in script_helpers.sh and installer.sh * Refactor echo statements in script_helpers.sh and installer.sh * Refactor echo statements in script_helpers.sh and installer.sh * Refactor echo statements in script_helpers.sh and installer.sh * Refactor echo statements in script_helpers.sh and installer.sh * Refactor echo statements in deploy_utils.sh for better readability * Refactor echo statement in 03-sap-system-deployment.yaml * Refactor echo statement in 03-sap-system-deployment.yaml for better readability * Refactor echo statement in 03-sap-system-deployment.yaml for better readability * Refactor echo statements for better readability and consistency * Refactor echo statements for better readability and consistency * Refactor echo statements for better readability and consistency * Refactor echo statements for better readability and consistency * Refactor echo statements for better readability and consistency * Refactor echo statements for better readability and consistency * Refactor echo statements for better readability and consistency * Refactor echo statements to use variable for workload TFvars * Refactor echo statements to use variable for workload TFvars * Refactor echo statements to use variable for workload TFvars * Refactor echo statement to use variable for Terraform Storage Account Id * Refactor echo statements to use variables for Terraform details * Refactor echo statements to use variables for Terraform details * Refactor echo statements to use variables for Terraform details * Refactor echo statements to use variables consistently * Refactor echo statements to use variables consistently * Refactor echo statements to use variables consistently and for Terraform details * Refactor echo statements to consistently use variables * Refactor echo statements to consistently use variables and improve Terraform details * Refactor echo statements to consistently use variables and improve Terraform details * Refactor echo statements to consistently use variables and improve Terraform details * Refactor echo statements to consistently use variables and improve Terraform details * Debugging * Refactor echo statements to consistently use variables and improve Terraform details * Refactor echo statements to consistently use variables and improve Terraform details * Refactor echo statements to consistently use variables and improve Terraform details * trimming * Refactor echo statements to consistently use variables and improve Terraform details * Refactor echo statements to consistently use variables and improve Terraform details * Refactor echo statements to consistently use variables and improve Terraform details * Refactor echo statements to consistently use variables and improve Terraform details * Refactor echo statements to consistently use variables and improve Terraform details * Refactor echo statements to consistently use variables and improve Terraform details * Refactor echo statements to consistently use variables and improve Terraform details * Refactor echo statements to consistently use variables and improve formatting * Refactor echo statements to consistently use variables and improve formatting * terraform * Refactor echo statements to consistently use variables and improve Terraform details * Refactor echo statements to consistently use variables and improve formatting * Refactor echo statements to consistently use variables and improve formatting * Refactor echo statements to consistently use variables and improve Terraform details * Refactor providers.tf to use Managed Service Identity (MSI) for authentication * Refactor echo statements to consistently use variables and improve formatting * Refactor echo statement to improve parameter file formatting * Refactor echo statements to improve formatting and use variables consistently * Refactor echo statements to consistently use variables and improve formatting * Refactor deploy control plane pipeline to improve configuration and extension installation * Refactor providers.tf to use remote state for subscription ID * Refactor echo statements to consistently use variables and improve formatting * Refactor echo statements to consistently use variables and improve formatting Refactor providers.tf to use remote state for subscription ID Refactor deploy control plane pipeline to improve configuration and extension installation Fix validation issue in script_helpers.sh Update providers.tf to handle null subscription ID Remove unused variable in variables_local.tf * Refactor echo statement to improve formatting in deploy_controlplane.sh * Refactor echo statements to improve formatting in deploy_controlplane.sh and script_helpers.sh * Refactor deploy_controlplane.sh and script_helpers.sh echo statements for improved formatting * Refactor key vault secrets to include service principal access * Refactor key vault secrets to include service principal access * Refactor key vault secrets to include service principal access * Refactor key vault secrets to include service principal access * Refactor echo statements for improved formatting in deploy_controlplane.sh and script_helpers.sh * Refactor permissions assignment in deploy_controlplane.sh * Refactor echo statements for improved formatting and include deployer subscription * Refactor echo statements for improved formatting and include deployer subscription * Refactor echo statements for improved formatting and include deployer subscription * Change to use ARM CLIENT ID * Refactor echo statement to include deployer subscription in 02-sap-workload-zone.yaml * Refactor echo statements for improved formatting and include deployer subscription in 02-sap-workload-zone.yaml * Refactor echo statements for improved formatting and include deployer subscription in 02-sap-workload-zone.yaml * Refactor echo statements for improved formatting and include deployer subscription in 02-sap-workload-zone.yaml * Refactor echo statements and include deployer subscription in 02-sap-workload-zone.yaml Change to use WL_ARM_CLIENT_ID instead of ARM_CLIENT_ID Update variable group and variable names in New-SDAFDevopsWorkloadZone.ps1 Update echo statements in script_helpers.sh for improved formatting * Refactor echo statements for improved formatting and include deployer subscription in 02-sap-workload-zone.yaml * Refactor echo statements for improved formatting and include deployer subscription in 03-sap-system-deployment.yaml * Refactor echo statements for improved formatting and include deployer subscription in 03-sap-system-deployment.yaml * indentation * Refactor echo statements for improved formatting and include deployer subscription in 03-sap-system-deployment.yaml * Refactor echo statements for improved formatting and include deployer subscription in 03-sap-system-deployment.yaml * Refactor echo statements for improved formatting and include deployer subscription in 03-sap-system-deployment.yaml * Refactor echo statements for improved formatting and fix indentation in 10-remover-terraform.yaml * Refactor echo statement for improved formatting in remover.sh * Refactor echo statements for improved formatting and remove unnecessary output in remover.sh and 10-remover-terraform.yaml * Refactor echo statements for improved formatting and remove unnecessary output in remover.sh and 10-remover-terraform.yaml * Refactor echo statements for improved formatting and remove unnecessary output in remover.sh and 10-remover-terraform.yaml * Refactor echo statements for improved formatting and remove unnecessary output in 01-deploy-control-plane.yaml * Refactor validate_dependencies function to check for the existence of the terraform binary file instead of the terraform directory. * Refactor echo statements for improved formatting and remove unnecessary output in deploy and remove pipelines * Refactor echo statements for improved formatting and remove unnecessary output in deploy and remove pipelines * Refactor echo statements for improved formatting and remove unnecessary output in set_secrets.sh * Refactor azuread_service_principal data source to conditionally include object_id in locals * Update SDAF version to 3.13.1.0 in ansible-input-api.yaml and version.txt * Refactor echo statements for improved formatting and remove unnecessary output in deploy and remove pipelines * Refactor echo statements for improved formatting and remove unnecessary output in deploy and remove pipelines * Refactor key_vault_sap_landscape.tf to conditionally include object_id in azurerm_key_vault_access_policy * Refactor echo statements for improved formatting and remove unnecessary output in deploy and remove pipelines * Refactor key_vault_sap_landscape.tf to conditionally include object_id in azurerm_key_vault_access_policy * Refactor key_vault_sap_landscape.tf to conditionally include object_id in azurerm_key_vault_access_policy * Refactor echo statements for improved formatting and remove unnecessary output in deploy and remove pipelines * Refactor echo statements for improved formatting and remove unnecessary output in deploy and remove pipelines * Refactor echo statements for improved formatting and remove unnecessary output in deploy and remove pipelines * Refactor echo statements for improved formatting in installer.sh * Refactor echo statements for improved formatting and remove unnecessary output in installer.sh * Refactor echo statements for improved formatting and remove unnecessary output in set_secrets.sh * Refactor echo statements for improved formatting and remove unnecessary output in installer.sh and providers.tf * Refactor echo statements for improved formatting and remove unnecessary output in installer.sh * Refactor installer.sh to fix path issue and pass parameters correctly * Refactor deploy_controlplane.sh to include state subscription parameter in installer.sh call * Refactor deploy_controlplane.sh to include correct subscription parameter in installer.sh call * Refactor deploy_controlplane.sh to include deployer subscription parameter and persist parameters * Refactor deploy_controlplane.sh to include state subscription parameter in installer.sh call * Refactor deploy_controlplane.sh to include state subscription parameter in installer.sh call * Refactor deploy_controlplane.sh to include correct subscription parameter in installer.sh call * Refactor deploy_controlplane.sh to include correct subscription parameter in installer.sh call and handle storage account authentication * Refactor deploy_controlplane.sh to remove unnecessary echo statement * Refactor deploy_controlplane.sh to remove unnecessary echo statements and improve parameter handling * Refactor deploy_controlplane.sh to improve parameter handling * Refactor deploy_controlplane.sh to improve storage account authentication handling * Refactor deploy_controlplane.sh to improve parameter handling and remove unnecessary echo statements * Refactor deploy_utils.sh to fix variable value retrieval from config file * Refactor parameter handling in script_helpers.sh and install_workloadzone.sh * Refactor install_workloadzone.sh to handle unknown region codes * Refactor install_workloadzone.sh to handle unknown region codes * Refactor install_workloadzone.sh to handle unknown region codes and improve parameter handling * Refactor install_workloadzone.sh to handle unknown region codes and improve parameter handling * Refactor region code handling in deploy_utils.sh and script_helpers.sh * Refactor install_workloadzone.sh to handle unknown region codes and improve parameter handling * Refactor install_workloadzone.sh to handle unknown region codes and improve parameter handling * Refactor install_workloadzone.sh to handle unknown region codes and improve parameter handling * Refactor install_workloadzone.sh to handle unknown region codes and improve parameter handling * Refactor install_workloadzone.sh to improve parameter handling and region code handling in deploy_utils.sh and script_helpers.sh * Refactor install_workloadzone.sh to improve parameter handling and region code handling * Refactor install_workloadzone.sh to improve parameter handling and region code handling * Refactor install_workloadzone.sh to improve parameter handling and region code handling * Refactor install_workloadzone.sh to improve parameter handling and region code handling * Refactor install_workloadzone.sh to improve parameter handling and region code handling * Refactor install_workloadzone.sh to remove unnecessary code * Refactor echo statements to improve readability and consistency * Refactor installer.sh to improve parameter handling and region code handling * Refactor installer.sh to improve parameter handling and region code handling * Refactor installer.sh to remove unnecessary echo statements * Refactor installer.sh to improve parameter handling and region code handling * Refactor storage_accounts.tf to include var.use_private_endpoint in the count condition * Refactor storage_accounts.tf to include var.use_private_endpoint in the count condition * Keyvault network rules * Refactor key_vault_sap_landscape.tf to include var.enable_firewall_for_keyvaults_and_storage in the default_action condition * Refactor installer.sh to handle empty SPN secret in set_executing_user_environment_variables * Refactor installer.sh to handle empty SPN secret in set_executing_user_environment_variables * Refactor module.tf to include enable_firewall_for_keyvaults_and_storage variable * Refactor installer.sh to handle empty SPN secret in set_executing_user_environment_variables and remove error file * Add Terraform output detaisl * Refactor Terraform plugin cache directory handling * Refactor Terraform destroy command in remover.sh * Refactor Terraform destroy command in remover.sh * Refactor echo statement in deploy pipeline to include return code from deployment * Refactor echo statement in deploy pipeline to include return code from deployment --------- Co-authored-by: Kimmo Forss Co-authored-by: hdamecharla --- deploy/pipelines/01-deploy-control-plane.yaml | 2138 ++++++++--------- deploy/pipelines/02-sap-workload-zone.yaml | 1397 +++++------ .../pipelines/03-sap-system-deployment.yaml | 902 +++---- deploy/pipelines/10-remover-terraform.yaml | 1789 +++++++------- deploy/pipelines/12-remove-control-plane.yaml | 1468 +++++------ deploy/scripts/install_workloadzone.sh | 2 +- deploy/scripts/installer.sh | 29 + 7 files changed, 3876 insertions(+), 3849 deletions(-) diff --git a/deploy/pipelines/01-deploy-control-plane.yaml b/deploy/pipelines/01-deploy-control-plane.yaml index b8aa970aa8..98bf3cbcd6 100644 --- a/deploy/pipelines/01-deploy-control-plane.yaml +++ b/deploy/pipelines/01-deploy-control-plane.yaml @@ -6,1100 +6,1096 @@ # +------------------------------------4--------------------------------------*/ parameters: - - name: deployer - displayName: "Deployer configuration name, use the following syntax: ENV-LOCA-VNET-INFRASTRUCTURE" - type: string - default: MGMT-WEEU-DEP01-INFRASTRUCTURE - - - name: library - displayName: "SAP Library configuration name, use the following syntax: ENV-LOCA-SAP_LIBRARY" - type: string - default: MGMT-WEEU-SAP_LIBRARY - - - name: environment - displayName: "Environment name, MGMT, DEV, QA, etc" - type: string - default: MGMT - - - name: use_webapp_param - displayName: "Deploy the configuration web application infrastructure" - type: boolean - default: true - - - name: deploy_webapp_software - displayName: "Deploy the configuration web application software" - type: boolean - default: true - - - name: use_deployer - displayName: Run on self hosted agent - type: boolean - default: false - - - name: sap_automation_repo_path - displayName: The local path on the agent where the sap_automation repo can be found - type: string - - - name: config_repo_path - displayName: The local path on the agent where the config repo can be found - type: string - - - name: connection_name - displayName: Service Connection Name - type: string - - - name: force_reset - displayName: Force a re-install - may require multiple re-runs - type: boolean +- name: deployer + displayName: "Deployer configuration name, use the following syntax: + ENV-LOCA-VNET-INFRASTRUCTURE" + type: string + default: MGMT-WEEU-DEP01-INFRASTRUCTURE + +- name: library + displayName: "SAP Library configuration name, use the following syntax: + ENV-LOCA-SAP_LIBRARY" + type: string + default: MGMT-WEEU-SAP_LIBRARY + +- name: environment + displayName: "Environment name, MGMT, DEV, QA, etc" + type: string + default: MGMT + +- name: use_webapp_param + displayName: "Deploy the configuration web application infrastructure" + type: boolean + default: true + +- name: deploy_webapp_software + displayName: "Deploy the configuration web application software" + type: boolean + default: true + +- name: use_deployer + displayName: Run on self hosted agent + type: boolean + default: false + +- name: sap_automation_repo_path + displayName: The local path on the agent where the sap_automation repo can be found + type: string + +- name: config_repo_path + displayName: The local path on the agent where the config repo can be found + type: string + +- name: connection_name + displayName: Service Connection Name + type: string + +- name: force_reset + displayName: Force a re-install - may require multiple re-runs + type: boolean stages: - - stage: Prepare_Deployer - condition: and(not(failed()), not(canceled())) - variables: - - template: variables/01-deploy-control-plane-variables.yaml - parameters: - deployer: ${{ parameters.deployer }} - library: ${{ parameters.library }} - environment: ${{ parameters.environment }} - use_webapp_param: ${{ parameters.use_webapp_param }} - use_deployer: ${{ parameters.use_deployer }} - displayName: Prepare the self hosted agent(s) - - jobs: - - job: Prepare_Deployer - displayName: Prepare the self hosted agent - workspace: - clean: all - steps: - - template: templates\download.yaml - - task: PostBuildCleanup@4 - # Set Variables. - - task: AzureCLI@2 - continueOnError: false - inputs: - azureSubscription: ${{parameters.connection_name}} - scriptType: bash - scriptLocation: inlineScript - addSpnToEnvironment: true - inlineScript: | - #!/bin/bash - - echo "##vso[build.updatebuildnumber]Deploying the control plane defined in $(deployerfolder) $(libraryfolder)" - green="\e[1;32m" - reset="\e[0m" - boldred="\e[1;31m" - cyan="\e[1;36m" - - export ARM_CLIENT_ID=$servicePrincipalId; echo 'ARM_CLIENT_ID' $ARM_CLIENT_ID - - export ARM_TENANT_ID=$tenantId - set -eu - - file_deployer_tfstate_key=$(deployerfolder).tfstate - - ENVIRONMENT=$(echo $(deployerfolder) | awk -F'-' '{print $1}' | xargs) - LOCATION=$(echo $(deployerfolder) | awk -F'-' '{print $2}' | xargs) - - deployer_environment_file_name=$CONFIG_REPO_PATH/.sap_deployment_automation/${ENVIRONMENT}${LOCATION} - - echo -e "$green--- Checkout $(Build.SourceBranchName) ---$reset" - cd $CONFIG_REPO_PATH - git checkout -q $(Build.SourceBranchName) - echo -e "$green--- Configure devops CLI extension ---$reset" - az config set extension.use_dynamic_install=yes_without_prompt --only-show-errors - - az extension add --name azure-devops --output none --only-show-errors - - echo "Environment: $ENVIRONMENT" - echo "Location: $LOCATION" - - echo "" - echo "Agent: $(this_agent)" - echo "Organization: $(System.CollectionUri)" - echo "Project: $(System.TeamProject)" - echo "" - az devops configure --defaults organization=$(System.CollectionUri) project='$(System.TeamProject)' --output none --only-show-errors - - export VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(variable_group)'].id | [0]") - - printf -v tempval '%s id:' $(variable_group) - printf -v val '%-20s' "${tempval}" - echo "$val $VARIABLE_GROUP_ID" - - if [ "${{ parameters.force_reset }}" = "True" ]; then - echo "##vso[task.logissue type=warning]Forcing a re-install" - echo "Running on: $(this_agent)" - sed -i 's/step=1/step=0/' $deployer_environment_file_name - sed -i 's/step=2/step=0/' $deployer_environment_file_name - sed -i 's/step=3/step=0/' $deployer_environment_file_name - - export FORCE_RESET=true - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Deployer_Key_Vault.value" --output tsv) - if [ -n "${az_var}" ]; then - key_vault="${az_var}" ; echo 'Deployer Key Vault' ${key_vault} - else - echo "Reading key vault from environment file" - key_vault=$(grep -m1 "^keyvault=" ${deployer_environment_file_name} |awk -F'=' '{print $2}' | xargs) - fi - - key_vault_id=$(az resource list --name "${key_vault}" --resource-type Microsoft.KeyVault/vaults --query "[].id | [0]" -o tsv) - export TF_VAR_deployer_kv_user_arm_id=${key_vault_id} - if [ -n "${key_vault_id}" ]; then - this_ip=$(curl -s ipinfo.io/ip) >/dev/null 2>&1 - az keyvault network-rule add --name ${key_vault} --ip-address ${this_ip} --subscription $(Terraform_Remote_Storage_Subscription) --only-show-errors --output none - ip_added=1 - fi - - tfstate_resource_id=$(az resource list --name $(Terraform_Remote_Storage_Account_Name) --subscription $(Terraform_Remote_Storage_Subscription) --resource-type Microsoft.Storage/storageAccounts --query "[].id | [0]" -o tsv) - if [ -n "${tfstate_resource_id}" ]; then - this_ip=$(curl -s ipinfo.io/ip) >/dev/null 2>&1 - az storage account network-rule add --account-name $(Terraform_Remote_Storage_Account_Name) --resource-group $(Terraform_Remote_Storage_Resource_Group_Name) --ip-address ${this_ip} --only-show-errors --output none - fi - - export REINSTALL_ACCOUNTNAME=$(Terraform_Remote_Storage_Account_Name) - export REINSTALL_SUBSCRIPTION=$(Terraform_Remote_Storage_Subscription) - export REINSTALL_RESOURCE_GROUP=$(Terraform_Remote_Storage_Resource_Group_Name) - step=0 - else - if [ -f ${deployer_environment_file_name} ]; then - step=$(cat ${deployer_environment_file_name} | grep step= | awk -F'=' '{print $2}' | xargs) - echo "Step: $(this_agent)" - if [ "0" != ${step} ]; then - exit 0 - fi - fi - fi - if [ -z ${VARIABLE_GROUP_ID} ]; then - echo "##vso[task.logissue type=error]Variable group $(variable_group) could not be found." - exit 2 - fi - echo -e "$green--- Variables ---$reset" - storage_account_parameter="" - echo -e "$green--- Validations ---$reset" - if [ -z ${TF_VAR_ansible_core_version} ]; then - export TF_VAR_ansible_core_version=2.15 - fi - export TF_VAR_use_webapp=$(use_webapp) - echo -e "$green--- Update .sap_deployment_automation/config as SAP_AUTOMATION_REPO_PATH can change on devops agent ---$reset" - cd $CONFIG_REPO_PATH - mkdir -p .sap_deployment_automation - echo SAP_AUTOMATION_REPO_PATH=$SAP_AUTOMATION_REPO_PATH >.sap_deployment_automation/config - echo -e "$green--- File Validations ---$reset" - if [ ! -f ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig) ]; then - echo -e "$boldred--- File ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig) was not found ---$reset" - echo "##vso[task.logissue type=error]File ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig) was not found." - exit 2 - fi - if [ ! -f ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig) ]; then - echo -e "$boldred--- File ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig) was not found ---$reset" - echo "##vso[task.logissue type=error]File ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig) was not found." - exit 2 - fi - # Check if running on deployer - if [ ! -f /etc/profile.d/deploy_server.sh ]; then - echo -e "$green--- Install dos2unix ---$reset" - sudo apt-get -qq install dos2unix - sudo apt-get -qq install zip - echo -e "$green--- Install terraform ---$reset" - wget -q $(tf_url) - return_code=$? - if [ 0 != $return_code ]; then - echo "##vso[task.logissue type=error]Unable to download Terraform version $(tf_version)." - exit 2 - fi - sudo mkdir -p /opt/terraform/bin/ - unzip -qq terraform_$(tf_version)_linux_amd64.zip - sudo mv terraform /opt/terraform/bin/terraform - sudo chmod +x /opt/terraform/bin/terraform - rm -f terraform_$(tf_version)_linux_amd64.zip - az extension add --name storage-blob-preview --allow-preview true --only-show-errors >/dev/null - fi - echo -e "$green--- Configure parameters ---$reset" - echo -e "$green--- Convert config files to UX format ---$reset" - dos2unix -q ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig) - dos2unix -q ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig) - echo -e "$green--- Configuring variables ---$reset" - deployer_environment_file_name=$CONFIG_REPO_PATH/.sap_deployment_automation/${ENVIRONMENT}$LOCATION - echo -e "$green--- Deploy the Control Plane ---$reset" - if [ -n "$(PAT)" ]; then - echo "Deployer Agent PAT: IsDefined" - fi - if [ -n "$(POOL)" ]; then - echo " Deployer Agent Pool: $(POOL)" - - fi - if [ -f ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/state.zip ]; then - pass=$(echo $(System.CollectionId) | sed 's/-//g') - echo "Unzipping state.zip" - unzip -qq -o -P "${pass}" ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/state.zip -d ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder) - fi - - if [ $(use_webapp) = "true" ]; then - echo "Deploy Web App: true" - - else - echo "Deploy Web App: false" - fi - - export TF_LOG_PATH=$CONFIG_REPO_PATH/.sap_deployment_automation/terraform.log - set +eu - - if [ "$USE_MSI" = "true" ]; then - export ARM_CLIENT_SECRET=$servicePrincipalKey - export ARM_SUBSCRIPTION_ID=$ARM_SUBSCRIPTION_ID - echo "Deployment credentials: Managed Identity" - - - $SAP_AUTOMATION_REPO_PATH/deploy/scripts/deploy_controlplane.sh \ - --deployer_parameter_file ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig) \ - --library_parameter_file ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig) \ - --subscription $ARM_SUBSCRIPTION_ID --auto-approve --ado --only_deployer --msi - else - export ARM_CLIENT_ID=$CP_ARM_CLIENT_ID - export ARM_CLIENT_SECRET=$CP_ARM_CLIENT_SECRET - export ARM_CLIENT_SECRET=$CP_ARM_CLIENT_SECRET - export ARM_TENANT_ID=$CP_ARM_TENANT_ID - export ARM_USE_OIDC=false - export ARM_USE_AZUREAD=true - - echo "Deployment credentials: Service Principal" - echo "Deployment credential ID (SPN): $CP_ARM_CLIENT_ID" - - az login --service-principal -u $ARM_CLIENT_ID -p=$ARM_CLIENT_SECRET --tenant $ARM_TENANT_ID --output none - - $SAP_AUTOMATION_REPO_PATH/deploy/scripts/deploy_controlplane.sh \ - --deployer_parameter_file ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig) \ - --library_parameter_file ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig) \ - --subscription $ARM_SUBSCRIPTION_ID --spn_id $ARM_CLIENT_ID \ - --spn_secret $ARM_CLIENT_SECRET --tenant_id $ARM_TENANT_ID \ - --auto-approve --ado --only_deployer - - fi - return_code=$? - echo "Deploy_controlplane returned $return_code." - - set -eu - - echo -e "$green--- Adding deployment automation configuration to devops repository ---$reset" - added=0 - cd $CONFIG_REPO_PATH - git pull -q - if [ -f ${deployer_environment_file_name} ]; then - file_deployer_tfstate_key=$(cat ${deployer_environment_file_name} | grep deployer_tfstate_key | awk -F'=' '{print $2}' | xargs) - if [ -z "$file_deployer_tfstate_key" ]; then - file_deployer_tfstate_key=$DEPLOYER_TFSTATE_KEY - fi - echo "Deployer State File $file_deployer_tfstate_key" - - file_key_vault=$(cat ${deployer_environment_file_name} | grep keyvault= | awk -F'=' '{print $2}' | xargs) - echo "Deployer Key Vault: ${file_key_vault}" - - deployer_random_id=$(cat ${deployer_environment_file_name} | grep deployer_random_id= | awk -F'=' '{print $2}' | xargs) - library_random_id=$(cat ${deployer_environment_file_name} | grep library_random_id= | awk -F'=' '{print $2}' | xargs) - - fi - echo -e "$green--- Update repo ---$reset" - if [ -f .sap_deployment_automation/${ENVIRONMENT}${LOCATION} ]; then - git add .sap_deployment_automation/${ENVIRONMENT}${LOCATION} - added=1 - fi - if [ -f ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/.terraform/terraform.tfstate ]; then - git add -f ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/.terraform/terraform.tfstate - added=1 - fi - if [ -f ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/terraform.tfstate ]; then - sudo apt-get install zip -y - pass=$(echo $(System.CollectionId) | sed 's/-//g') - zip -q -j -P "${pass}" ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/state ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/terraform.tfstate - git add -f ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/state.zip - added=1 - fi - if [ 1 = $added ]; then - git config --global user.email "$(Build.RequestedForEmail)" - git config --global user.name "$(Build.RequestedFor)" - git commit -m "Added updates from devops deployment $(Build.DefinitionName) [skip ci]" - git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" push --set-upstream origin $(Build.SourceBranchName) - fi - if [ -f $CONFIG_REPO_PATH/.sap_deployment_automation/${ENVIRONMENT}${LOCATION}.md ]; then - echo "##vso[task.uploadsummary]$CONFIG_REPO_PATH/.sap_deployment_automation/${ENVIRONMENT}${LOCATION}.md" - fi - echo -e "$green--- Adding variables to the variable group:" $(variable_group) "---$reset" - if [ 0 = $return_code ]; then - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Deployer_State_FileName.value" --out tsv) - if [ -z ${az_var} ]; then - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name Deployer_State_FileName --value ${file_deployer_tfstate_key} --output none --only-show-errors - else - az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name Deployer_State_FileName --value ${file_deployer_tfstate_key} --output none --only-show-errors - fi - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Deployer_Key_Vault.value" --out tsv) - if [ -z ${az_var} ]; then - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name Deployer_Key_Vault --value ${file_key_vault} --output none --only-show-errors - else - az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name Deployer_Key_Vault --value ${file_key_vault} --output none --only-show-errors - fi - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "ControlPlaneEnvironment.value" --out tsv) - if [ -z ${az_var} ]; then - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name ControlPlaneEnvironment --value ${ENVIRONMENT} --output none --only-show-errors - else - az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name ControlPlaneEnvironment --value ${ENVIRONMENT} --output none --only-show-errors - fi - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "ControlPlaneLocation.value" --out tsv) - if [ -z ${az_var} ]; then - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name ControlPlaneLocation --value ${LOCATION} --output none --only-show-errors - else - az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name ControlPlaneLocation --value ${LOCATION} --output none --only-show-errors - fi - - if [ -n "${deployer_random_id}" ] ; then - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "DEPLOYER_RANDOM_ID_SEED.value" --out tsv) - if [ -z ${az_var} ]; then - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name DEPLOYER_RANDOM_ID_SEED --value ${deployer_random_id} --output none --only-show-errors - else - az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name DEPLOYER_RANDOM_ID_SEED --value ${deployer_random_id} --output none --only-show-errors - fi - fi - - - fi - exit $return_code - - displayName: Prepare control plane - env: - CP_ARM_CLIENT_ID: $(CP_ARM_CLIENT_ID) - CP_ARM_CLIENT_SECRET: $(CP_ARM_CLIENT_SECRET) - ARM_SUBSCRIPTION_ID: $(CP_ARM_SUBSCRIPTION_ID) - CP_ARM_TENANT_ID: $(CP_ARM_TENANT_ID) - AZURE_DEVOPS_EXT_PAT: $(PAT) - CONFIG_REPO_PATH: ${{ parameters.config_repo_path }}/$(Deployment_Configuration_Path) - DEPLOYER_RANDOM_ID_SEED: $(DEPLOYER_RANDOM_ID_SEED) - DEPLOYER_TFSTATE_KEY: "${{ parameters.deployer }}.terraform.tfstate" - IS_PIPELINE_DEPLOYMENT: true - POOL: $(POOL) - SAP_AUTOMATION_REPO_PATH: ${{ parameters.sap_automation_repo_path }} - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - TF_APP_REGISTRATION_APP_ID: $(APP_REGISTRATION_APP_ID) - TF_IN_AUTOMATION: true - TF_LOG: $(TF_LOG) - TF_VAR_agent_ado_url: $(System.CollectionUri) - TF_VAR_agent_pat: $(PAT) - TF_VAR_agent_pool: $(POOL) - TF_VAR_ansible_core_version: $(ansible_core_version) - TF_VAR_app_registration_app_id: $(APP_REGISTRATION_APP_ID) - TF_VAR_deployer_kv_user_arm_id: $(Deployer_Key_Vault) - TF_VAR_spn_id: $(CP_ARM_OBJECT_ID) - TF_VAR_tf_version: $(tf_version) - TF_VAR_use_webapp: ${{ lower(parameters.use_webapp_param) }} - TF_VAR_webapp_client_secret: $(WEB_APP_CLIENT_SECRET) - USE_MSI: $(Use_MSI) - USE_WEBAPP: ${{ lower(parameters.use_webapp_param) }} - WEB_APP_CLIENT_SECRET: $(WEB_APP_CLIENT_SECRET) - - - - stage: Deploy_controlplane - dependsOn: - - Prepare_Deployer - condition: eq(dependencies.Prepare_Deployer.result, 'Succeeded') - pool: $(this_agent) - variables: - - template: variables/01-deploy-control-plane-variables.yaml - parameters: - deployer: ${{ parameters.deployer }} - library: ${{ parameters.library }} - environment: ${{ parameters.environment }} - use_webapp_param: ${{ parameters.use_webapp_param }} - use_deployer: ${{ parameters.use_deployer }} - displayName: Deploy the control plane - - jobs: - - job: Deploy_controlplane - displayName: Deploy the control plane - workspace: - clean: all - steps: - - task: PostBuildCleanup@4 - - template: templates\download.yaml - parameters: - getLatestFromBranch: true - - bash: | - #!/bin/bash - set -u - - echo "##vso[build.updatebuildnumber]Deploying the control plane defined in $(deployerfolder) $(libraryfolder)" - green="\e[1;32m" - reset="\e[0m" - boldred="\e[1;31m" - cyan="\e[1;36m" - - ENVIRONMENT=$(echo $(deployerfolder) | awk -F'-' '{print $1}' | xargs) - LOCATION=$(echo $(deployerfolder) | awk -F'-' '{print $2}' | xargs) - deployer_environment_file_name=${CONFIG_REPO_PATH}/.sap_deployment_automation/"${ENVIRONMENT}${LOCATION}" - file_deployer_tfstate_key=$(deployerfolder).tfstate - file_key_vault="" - file_REMOTE_STATE_SA="" - file_REMOTE_STATE_RG=$(deployerfolder) - REMOTE_STATE_SA="" - REMOTE_STATE_RG=$(deployerfolder) - - if [[ -f /etc/profile.d/deploy_server.sh ]]; then - path=$(grep -m 1 "export PATH=" /etc/profile.d/deploy_server.sh | awk -F'=' '{print $2}' | xargs) - export PATH=$path - fi - - echo -e "$green--- Information ---$reset" - echo "Environment: ${ENVIRONMENT}" - echo "Location: ${LOCATION}" - echo "Agent: $(this_agent)" - echo "Organization: $(System.CollectionUri)" - echo "Project: $(System.TeamProject)" - echo "Deployer Folder: $(deployerfolder)" - echo "Deployer TFvars: $(deployerconfig)" - echo "Library Folder: $(libraryfolder)" - echo "Library TFvars: $(libraryconfig)" - - echo "" - echo "Azure CLI version:" - echo "-------------------------------------------------" - az --version - echo "" - echo "Terraform version:" - echo "-------------------------------------------------" - if [ -f /opt/terraform/bin/terraform ]; then - tfPath="/opt/terraform/bin/terraform" - else - tfPath=$(which terraform) - fi - - "${tfPath}" --version - echo -e "$green--- Checkout $(Build.SourceBranchName) ---$reset" - cd "$CONFIG_REPO_PATH" || exit - git checkout -q $(Build.SourceBranchName) - - deployer_configfile="${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig)" - library_configfile="${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig)" - - deployer_configfile="${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig)" - library_configfile="${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig)" - - echo -e "$green--- Configure devops CLI extension ---$reset" - az config set extension.use_dynamic_install=yes_without_prompt --only-show-errors - az extension add --name azure-devops --output none --only-show-errors - - az devops configure --defaults organization=$(System.CollectionUri) project='$(System.TeamProject)' - - VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(variable_group)'].id | [0]") - export VARIABLE_GROUP_ID - if [ -z "${VARIABLE_GROUP_ID}" ]; then - echo "##vso[task.logissue type=error]Variable group $(variable_group) could not be found." - exit 2 - fi - - printf -v tempval '%s id:' $(variable_group) - printf -v val '%-20s' "${tempval}" - echo "$val $VARIABLE_GROUP_ID" - - echo -e "$green--- Variables ---$reset" - az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Deployer_Key_Vault.value" --output tsv) - if [ -n "${az_var}" ]; then - export key_vault="${az_var}" - else - if [ -f "${deployer_environment_file_name}" ] ; then - - key_vault=$(grep "^keyvault=" "${deployer_environment_file_name}" | awk -F'=' '{print $2}' | xargs) - az pipelines variable-group variable create --group-id "${VARIABLE_GROUP_ID}" --name Deployer_Key_Vault --value "${key_vault}" --output none --only-show-errors - fi +- stage: Prepare_Deployer + condition: and(not(failed()), not(canceled())) + variables: + - template: variables/01-deploy-control-plane-variables.yaml + parameters: + deployer: ${{ parameters.deployer }} + library: ${{ parameters.library }} + environment: ${{ parameters.environment }} + use_webapp_param: ${{ parameters.use_webapp_param }} + use_deployer: ${{ parameters.use_deployer }} + displayName: Prepare the self hosted agent(s) + + jobs: + - job: Prepare_Deployer + displayName: Prepare the self hosted agent + workspace: + clean: all + steps: + - template: templates\download.yaml + - task: PostBuildCleanup@4 + # Set Variables. + - task: AzureCLI@2 + continueOnError: false + inputs: + azureSubscription: ${{parameters.connection_name}} + scriptType: bash + scriptLocation: inlineScript + addSpnToEnvironment: true + inlineScript: | + #!/bin/bash + + echo "##vso[build.updatebuildnumber]Deploying the control plane defined in $(deployerfolder) $(libraryfolder)" + green="\e[1;32m" + reset="\e[0m" + boldred="\e[1;31m" + cyan="\e[1;36m" + + export ARM_CLIENT_ID=$servicePrincipalId; echo 'ARM_CLIENT_ID' $ARM_CLIENT_ID + + export ARM_TENANT_ID=$tenantId + set -eu + + file_deployer_tfstate_key=$(deployerfolder).tfstate + + ENVIRONMENT=$(echo $(deployerfolder) | awk -F'-' '{print $1}' | xargs) + LOCATION=$(echo $(deployerfolder) | awk -F'-' '{print $2}' | xargs) + + deployer_environment_file_name=$CONFIG_REPO_PATH/.sap_deployment_automation/${ENVIRONMENT}${LOCATION} + + echo -e "$green--- Checkout $(Build.SourceBranchName) ---$reset" + cd $CONFIG_REPO_PATH + git checkout -q $(Build.SourceBranchName) + echo -e "$green--- Configure devops CLI extension ---$reset" + az config set extension.use_dynamic_install=yes_without_prompt --only-show-errors + + az extension add --name azure-devops --output none --only-show-errors + + echo "Environment: $ENVIRONMENT" + echo "Location: $LOCATION" + + echo "" + echo "Agent: $(this_agent)" + echo "Organization: $(System.CollectionUri)" + echo "Project: $(System.TeamProject)" + echo "" + az devops configure --defaults organization=$(System.CollectionUri) project='$(System.TeamProject)' --output none --only-show-errors + + export VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(variable_group)'].id | [0]") + + printf -v tempval '%s id:' $(variable_group) + printf -v val '%-20s' "${tempval}" + echo "$val $VARIABLE_GROUP_ID" + + if [ "${{ parameters.force_reset }}" = "True" ]; then + echo "##vso[task.logissue type=warning]Forcing a re-install" + echo "Running on: $(this_agent)" + sed -i 's/step=1/step=0/' $deployer_environment_file_name + sed -i 's/step=2/step=0/' $deployer_environment_file_name + sed -i 's/step=3/step=0/' $deployer_environment_file_name + + export FORCE_RESET=true + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Deployer_Key_Vault.value" --output tsv) + if [ -n "${az_var}" ]; then + key_vault="${az_var}" ; echo 'Deployer Key Vault' ${key_vault} + else + echo "Reading key vault from environment file" + key_vault=$(grep -m1 "^keyvault=" ${deployer_environment_file_name} |awk -F'=' '{print $2}' | xargs) + fi + + key_vault_id=$(az resource list --name "${key_vault}" --resource-type Microsoft.KeyVault/vaults --query "[].id | [0]" -o tsv) + export TF_VAR_deployer_kv_user_arm_id=${key_vault_id} + if [ -n "${key_vault_id}" ]; then + this_ip=$(curl -s ipinfo.io/ip) >/dev/null 2>&1 + az keyvault network-rule add --name ${key_vault} --ip-address ${this_ip} --subscription $(Terraform_Remote_Storage_Subscription) --only-show-errors --output none + ip_added=1 + fi + + tfstate_resource_id=$(az resource list --name $(Terraform_Remote_Storage_Account_Name) --subscription $(Terraform_Remote_Storage_Subscription) --resource-type Microsoft.Storage/storageAccounts --query "[].id | [0]" -o tsv) + if [ -n "${tfstate_resource_id}" ]; then + this_ip=$(curl -s ipinfo.io/ip) >/dev/null 2>&1 + az storage account network-rule add --account-name $(Terraform_Remote_Storage_Account_Name) --resource-group $(Terraform_Remote_Storage_Resource_Group_Name) --ip-address ${this_ip} --only-show-errors --output none + fi + + export REINSTALL_ACCOUNTNAME=$(Terraform_Remote_Storage_Account_Name) + export REINSTALL_SUBSCRIPTION=$(Terraform_Remote_Storage_Subscription) + export REINSTALL_RESOURCE_GROUP=$(Terraform_Remote_Storage_Resource_Group_Name) + step=0 + else + if [ -f ${deployer_environment_file_name} ]; then + step=$(cat ${deployer_environment_file_name} | grep step= | awk -F'=' '{print $2}' | xargs) + echo "Step: $(this_agent)" + if [ "0" != ${step} ]; then + exit 0 fi - - az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Terraform_Remote_Storage_Subscription.value" --output tsv) - if [ -n "${az_var}" ]; then - export STATE_SUBSCRIPTION="${az_var}" + fi + fi + if [ -z ${VARIABLE_GROUP_ID} ]; then + echo "##vso[task.logissue type=error]Variable group $(variable_group) could not be found." + exit 2 + fi + echo -e "$green--- Variables ---$reset" + storage_account_parameter="" + echo -e "$green--- Validations ---$reset" + if [ -z ${TF_VAR_ansible_core_version} ]; then + export TF_VAR_ansible_core_version=2.15 + fi + export TF_VAR_use_webapp=$(use_webapp) + echo -e "$green--- Update .sap_deployment_automation/config as SAP_AUTOMATION_REPO_PATH can change on devops agent ---$reset" + cd $CONFIG_REPO_PATH + mkdir -p .sap_deployment_automation + echo SAP_AUTOMATION_REPO_PATH=$SAP_AUTOMATION_REPO_PATH >.sap_deployment_automation/config + echo -e "$green--- File Validations ---$reset" + if [ ! -f ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig) ]; then + echo -e "$boldred--- File ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig) was not found ---$reset" + echo "##vso[task.logissue type=error]File ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig) was not found." + exit 2 + fi + if [ ! -f ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig) ]; then + echo -e "$boldred--- File ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig) was not found ---$reset" + echo "##vso[task.logissue type=error]File ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig) was not found." + exit 2 + fi + # Check if running on deployer + if [ ! -f /etc/profile.d/deploy_server.sh ]; then + echo -e "$green--- Install dos2unix ---$reset" + sudo apt-get -qq install dos2unix + sudo apt-get -qq install zip + echo -e "$green--- Install terraform ---$reset" + wget -q $(tf_url) + return_code=$? + if [ 0 != $return_code ]; then + echo "##vso[task.logissue type=error]Unable to download Terraform version $(tf_version)." + exit 2 + fi + sudo mkdir -p /opt/terraform/bin/ + unzip -qq terraform_$(tf_version)_linux_amd64.zip + sudo mv terraform /opt/terraform/bin/terraform + sudo chmod +x /opt/terraform/bin/terraform + rm -f terraform_$(tf_version)_linux_amd64.zip + az extension add --name storage-blob-preview --allow-preview true --only-show-errors >/dev/null + fi + echo -e "$green--- Configure parameters ---$reset" + echo -e "$green--- Convert config files to UX format ---$reset" + dos2unix -q ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig) + dos2unix -q ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig) + echo -e "$green--- Configuring variables ---$reset" + deployer_environment_file_name=$CONFIG_REPO_PATH/.sap_deployment_automation/${ENVIRONMENT}$LOCATION + echo -e "$green--- Deploy the Control Plane ---$reset" + if [ -n "$(PAT)" ]; then + echo "Deployer Agent PAT: IsDefined" + fi + if [ -n "$(POOL)" ]; then + echo " Deployer Agent Pool: $(POOL)" + + fi + if [ -f ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/state.zip ]; then + pass=$(echo $(System.CollectionId) | sed 's/-//g') + echo "Unzipping state.zip" + unzip -qq -o -P "${pass}" ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/state.zip -d ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder) + fi + + if [ $(use_webapp) = "true" ]; then + echo "Deploy Web App: true" + + else + echo "Deploy Web App: false" + fi + + export TF_LOG_PATH=$CONFIG_REPO_PATH/.sap_deployment_automation/terraform.log + set +eu + + if [ "$USE_MSI" = "true" ]; then + export ARM_CLIENT_SECRET=$servicePrincipalKey + export ARM_SUBSCRIPTION_ID=$ARM_SUBSCRIPTION_ID + echo "Deployment credentials: Managed Identity" + + + $SAP_AUTOMATION_REPO_PATH/deploy/scripts/deploy_controlplane.sh \ + --deployer_parameter_file ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig) \ + --library_parameter_file ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig) \ + --subscription $ARM_SUBSCRIPTION_ID --auto-approve --ado --only_deployer --msi + else + export ARM_CLIENT_ID=$CP_ARM_CLIENT_ID + export ARM_CLIENT_SECRET=$CP_ARM_CLIENT_SECRET + export ARM_CLIENT_SECRET=$CP_ARM_CLIENT_SECRET + export ARM_TENANT_ID=$CP_ARM_TENANT_ID + export ARM_USE_OIDC=false + export ARM_USE_AZUREAD=true + + echo "Deployment credentials: Service Principal" + echo "Deployment credential ID (SPN): $CP_ARM_CLIENT_ID" + + az login --service-principal -u $ARM_CLIENT_ID -p=$ARM_CLIENT_SECRET --tenant $ARM_TENANT_ID --output none + + $SAP_AUTOMATION_REPO_PATH/deploy/scripts/deploy_controlplane.sh \ + --deployer_parameter_file ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig) \ + --library_parameter_file ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig) \ + --subscription $ARM_SUBSCRIPTION_ID --spn_id $ARM_CLIENT_ID \ + --spn_secret $ARM_CLIENT_SECRET --tenant_id $ARM_TENANT_ID \ + --auto-approve --ado --only_deployer + + fi + return_code=$? + echo "Deploy_controlplane returned $return_code." + + set -eu + + echo -e "$green--- Adding deployment automation configuration to devops repository ---$reset" + added=0 + cd $CONFIG_REPO_PATH + git pull -q + if [ -f ${deployer_environment_file_name} ]; then + file_deployer_tfstate_key=$(cat ${deployer_environment_file_name} | grep deployer_tfstate_key | awk -F'=' '{print $2}' | xargs) + if [ -z "$file_deployer_tfstate_key" ]; then + file_deployer_tfstate_key=$DEPLOYER_TFSTATE_KEY + fi + echo "Deployer State File $file_deployer_tfstate_key" + + file_key_vault=$(cat ${deployer_environment_file_name} | grep keyvault= | awk -F'=' '{print $2}' | xargs) + echo "Deployer Key Vault: ${file_key_vault}" + + deployer_random_id=$(cat ${deployer_environment_file_name} | grep deployer_random_id= | awk -F'=' '{print $2}' | xargs) + library_random_id=$(cat ${deployer_environment_file_name} | grep library_random_id= | awk -F'=' '{print $2}' | xargs) + + fi + echo -e "$green--- Update repo ---$reset" + if [ -f .sap_deployment_automation/${ENVIRONMENT}${LOCATION} ]; then + git add .sap_deployment_automation/${ENVIRONMENT}${LOCATION} + added=1 + fi + if [ -f ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/.terraform/terraform.tfstate ]; then + git add -f ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/.terraform/terraform.tfstate + added=1 + fi + if [ -f ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/terraform.tfstate ]; then + sudo apt-get install zip -y + pass=$(echo $(System.CollectionId) | sed 's/-//g') + zip -q -j -P "${pass}" ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/state ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/terraform.tfstate + git add -f ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/state.zip + added=1 + fi + if [ 1 = $added ]; then + git config --global user.email "$(Build.RequestedForEmail)" + git config --global user.name "$(Build.RequestedFor)" + git commit -m "Added updates from devops deployment $(Build.DefinitionName) [skip ci]" + git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" push --set-upstream origin $(Build.SourceBranchName) + fi + if [ -f $CONFIG_REPO_PATH/.sap_deployment_automation/${ENVIRONMENT}${LOCATION}.md ]; then + echo "##vso[task.uploadsummary]$CONFIG_REPO_PATH/.sap_deployment_automation/${ENVIRONMENT}${LOCATION}.md" + fi + echo -e "$green--- Adding variables to the variable group:" $(variable_group) "---$reset" + if [ 0 = $return_code ]; then + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Deployer_State_FileName.value" --out tsv) + if [ -z ${az_var} ]; then + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name Deployer_State_FileName --value ${file_deployer_tfstate_key} --output none --only-show-errors else - if [ -f "${deployer_environment_file_name}" ] ; then - export STATE_SUBSCRIPTION=$(grep "^STATE_SUBSCRIPTION=" "${deployer_environment_file_name}" | awk -F'=' '{print $2}' | xargs) - az pipelines variable-group variable create --group-id "${VARIABLE_GROUP_ID}" --name Terraform_Remote_Storage_Subscription --value "${STATE_SUBSCRIPTION}" --output none --only-show-errors - fi + az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name Deployer_State_FileName --value ${file_deployer_tfstate_key} --output none --only-show-errors fi - - az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "DEPLOYER_RANDOM_ID_SEED.value" --output tsv) - if [ -n "${az_var}" ]; then - deployer_random_id="${az_var}" + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Deployer_Key_Vault.value" --out tsv) + if [ -z ${az_var} ]; then + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name Deployer_Key_Vault --value ${file_key_vault} --output none --only-show-errors else - deployer_random_id=$(grep "^deployer_random_id=" "${deployer_environment_file_name}" | awk -F'=' '{print $2}' | xargs) - az pipelines variable-group variable create --group-id "${VARIABLE_GROUP_ID}" --name DEPLOYER_RANDOM_ID_SEED --value "${deployer_random_id}" --output none --only-show-errors + az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name Deployer_Key_Vault --value ${file_key_vault} --output none --only-show-errors fi - - az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Terraform_Remote_Storage_Account_Name.value" --output tsv) - if [ -n "${az_var}" ]; then - export REMOTE_STATE_SA="${az_var}" + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "ControlPlaneEnvironment.value" --out tsv) + if [ -z ${az_var} ]; then + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name ControlPlaneEnvironment --value ${ENVIRONMENT} --output none --only-show-errors else - if [ -f "${deployer_environment_file_name}" ] ; then - REMOTE_STATE_SA=$(grep "^REMOTE_STATE_SA=" "${deployer_environment_file_name}" | awk -F'=' '{print $2}' | xargs) - fi - fi - - echo "Terraform state subscription: $STATE_SUBSCRIPTION" - if [ -n "${REMOTE_STATE_RG}" ]; then - echo "Terraform state rg name: $REMOTE_STATE_RG" - fi - if [ -n "${REMOTE_STATE_SA}" ]; then - echo "Terraform storage account: $REMOTE_STATE_SA" - fi - - echo "Deployer Key Vault: ${key_vault}" - echo "Deployer TFvars: $(deployerconfig)" - - storage_account_parameter="" - if [ -n "${REMOTE_STATE_SA}" ]; then - storage_account_parameter=" --storageaccountname ${REMOTE_STATE_SA} " - else - sed -i 's/step=2/step=1/' "$deployer_environment_file_name" - sed -i 's/step=3/step=1/' "$deployer_environment_file_name" - fi - - keyvault_parameter="" - if [ -n "${key_vault}" ]; then - keyvault_parameter=" --vault ${key_vault} " - fi - - echo -e "$green--- Validations ---$reset" - - if [ -z "${TF_VAR_ansible_core_version}" ]; then - export TF_VAR_ansible_core_version=2.15 + az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name ControlPlaneEnvironment --value ${ENVIRONMENT} --output none --only-show-errors fi - if [ "$USE_WEBAPP" = "true" ]; then - echo "Deploy Web Application: true" - - if [ -z "${APP_REGISTRATION_APP_ID}" ]; then - echo "##vso[task.logissue type=error]Variable APP_REGISTRATION_APP_ID was not defined." - exit 2 - fi - - if [ -z "${WEB_APP_CLIENT_SECRET}" ]; then - echo "##vso[task.logissue type=error]Variable WEB_APP_CLIENT_SECRET was not defined." - exit 2 - fi - TF_VAR_app_registration_app_id=$(APP_REGISTRATION_APP_ID); - echo "App Registration ID: ${TF_VAR_app_registration_app_id}" - export TF_VAR_app_registration_app_id - TF_VAR_webapp_client_secret=$(WEB_APP_CLIENT_SECRET) - export TF_VAR_webapp_client_secret - export TF_VAR_use_webapp=true + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "ControlPlaneLocation.value" --out tsv) + if [ -z ${az_var} ]; then + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name ControlPlaneLocation --value ${LOCATION} --output none --only-show-errors else - echo "Deploy Web Application: false" - fi - - bootstrapped=0 - - if [ ! -f "$deployer_environment_file_name" ]; then - az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Terraform_Remote_Storage_Account_Name.value" --out tsv) - if [[ ${#az_var} -ne 0 ]]; then - echo "REMOTE_STATE_SA="${az_var} - echo "REMOTE_STATE_SA="${az_var} | tee -a "$deployer_environment_file_name" > /dev/null - echo "STATE_SUBSCRIPTION="$ARM_SUBSCRIPTION_ID | tee -a "$deployer_environment_file_name" > /dev/null - fi - - az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Terraform_Remote_Storage_Resource_Group_Name.value" --out tsv) - if [[ ${#az_var} -ne 0 ]]; then - echo "REMOTE_STATE_RG="${az_var} - echo "REMOTE_STATE_RG="${az_var} | tee -a "$deployer_environment_file_name" > /dev/null - echo "step=3" | tee -a "$deployer_environment_file_name" > /dev/null - - fi - - az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Deployer_State_FileName.value" --out tsv) - if [[ ${#az_var} -ne 0 ]]; then - echo "deployer_tfstate_key="${az_var} | tee -a "$deployer_environment_file_name" > /dev/null - fi - - az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Deployer_Key_Vault.value" --out tsv) - if [[ ${#az_var} -ne 0 ]]; then - echo "keyvault="${az_var} | tee -a "$deployer_environment_file_name" > /dev/null - bootstrapped=1 - fi - - fi - - echo -e "$green--- Update .sap_deployment_automation/config as SAP_AUTOMATION_REPO_PATH can change on devops agent ---$reset" - cd ${CONFIG_REPO_PATH} - mkdir -p .sap_deployment_automation - echo SAP_AUTOMATION_REPO_PATH=$SAP_AUTOMATION_REPO_PATH >.sap_deployment_automation/config - export SAP_AUTOMATION_REPO_PATH=$SAP_AUTOMATION_REPO_PATH - - echo -e "$green--- File Validations ---$reset" - if [ ! -f "${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig)" ]; then - echo -e "$boldred--- File "${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig)" was not found ---$reset" - echo "##vso[task.logissue type=error]File "${CONFIG_REPO_PATH}/${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig)" was not found." - exit 2 + az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name ControlPlaneLocation --value ${LOCATION} --output none --only-show-errors fi - if [ ! -f "${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig)" ]; then - echo -e "$boldred--- File ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig) was not found ---$reset" - echo "##vso[task.logissue type=error]File ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig) was not found." - exit 2 + if [ -n "${deployer_random_id}" ] ; then + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "DEPLOYER_RANDOM_ID_SEED.value" --out tsv) + if [ -z ${az_var} ]; then + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name DEPLOYER_RANDOM_ID_SEED --value ${deployer_random_id} --output none --only-show-errors + else + az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name DEPLOYER_RANDOM_ID_SEED --value ${deployer_random_id} --output none --only-show-errors + fi fi - # Check if running on deployer - if [[ ! -f /etc/profile.d/deploy_server.sh ]]; then - echo -e "$green--- Install dos2unix ---$reset" - sudo apt-get -qq install dos2unix - - sudo apt-get -qq install zip - - echo -e "$green --- Install terraform ---$reset" - - wget -q $(tf_url) - return_code=$? - if [ 0 != $return_code ]; then - echo "##vso[task.logissue type=error]Unable to download Terraform version $(tf_version)." - exit 2 - fi - unzip -qq terraform_$(tf_version)_linux_amd64.zip ; sudo mv terraform /bin/ - rm -f terraform_$(tf_version)_linux_amd64.zip - - az extension add --name storage-blob-preview >/dev/null - echo -e "$green--- az login ---$reset" - export ARM_CLIENT_ID=$CP_ARM_CLIENT_ID - export ARM_CLIENT_SECRET=$CP_ARM_CLIENT_SECRET - export ARM_TENANT_ID=$CP_ARM_TENANT_ID - export ARM_SUBSCRIPTION_ID=$CP_ARM_SUBSCRIPTION_ID - az login --service-principal --username "$ARM_CLIENT_ID" --password="$ARM_CLIENT_SECRET" --tenant "$ARM_TENANT_ID" --output none - return_code=$? - if [ 0 != $return_code ]; then - echo -e "$boldred--- Login failed ---$reset" - echo "##vso[task.logissue type=error]az login failed." - exit $return_code - fi - - az account set --subscription "$ARM_SUBSCRIPTION_ID" - - else - echo "Sourcing the deploy_server.sh" - . /etc/profile.d/deploy_server.sh ; /opt/bin/terraform/terraform --version - - if [ $USE_MSI != "true" ]; then - echo "Deployment credentials: Service Principal" - echo "Deployment credential ID (SPN): $CP_ARM_CLIENT_ID" - echo "Deployer subscription: $CP_ARM_SUBSCRIPTION_ID" - - export ARM_CLIENT_ID=$CP_ARM_CLIENT_ID - export ARM_CLIENT_SECRET=$CP_ARM_CLIENT_SECRET - export ARM_TENANT_ID=$CP_ARM_TENANT_ID - export ARM_SUBSCRIPTION_ID=$CP_ARM_SUBSCRIPTION_ID - unset ARM_USE_MSI - az login --service-principal --username "${ARM_CLIENT_ID}" --password="${ARM_CLIENT_SECRET}" --tenant "${ARM_TENANT_ID}" --output none - - return_code=$? - if [ 0 != $return_code ]; then - echo -e "$boldred--- Login failed ---$reset" - echo "##vso[task.logissue type=error]az login failed." - exit $return_code - fi - az account set --subscription $ARM_SUBSCRIPTION_ID - else - echo "Deployment credentials: Managed Identity" - - # export ARM_SUBSCRIPTION_ID=$ARM_SUBSCRIPTION_ID - export ARM_USE_MSI=true - export ARM_USE_AZUREAD=true - unset ARM_CLIENT_SECRET - az account set --subscription $ARM_SUBSCRIPTION_ID - fi - fi - - echo -e "$green--- Configure parameters ---$reset" - - echo -e "$green--- Convert config files to UX format ---$reset" - dos2unix -q "${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig)" - dos2unix -q "${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig)" - - echo -e "$green--- Configuring variables ---$reset" - - deployer_environment_file_name=${CONFIG_REPO_PATH}/.sap_deployment_automation/${ENVIRONMENT}$LOCATION - - export key_vault="" - ip_added=0 - - if [ -f "${deployer_environment_file_name}" ]; then - if [ 0 = $bootstrapped ]; then - key_vault=$(grep "^keyvault=" "${deployer_environment_file_name}" | awk -F'=' '{print $2}' | xargs) - export key_vault - if [ -n "${key_vault}" ]; then - key_vault_id=$(az resource list --name "${key_vault}" --resource-type Microsoft.KeyVault/vaults --query "[].id | [0]" -o tsv) - if [ -n "${key_vault_id}" ]; then - - if [ "azure pipelines" = "$(this_agent)" ]; then - this_ip=$(curl -s ipinfo.io/ip) >/dev/null 2>&1 - az keyvault network-rule add --name ${key_vault} --ip-address ${this_ip} --only-show-errors --output none - ip_added=1 - fi - fi - fi - fi - fi - - echo -e "$green--- Deploy the Control Plane ---$reset" - - if [ -n "$(POOL)" ]; then - echo "Deployer Agent Pool: $(POOL)" - fi - - if [ -f "${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/state.zip" ]; then - pass=$(echo $(System.CollectionId) | sed 's/-//g') - - echo "Unzipping the library state file" - unzip -o -qq -P "${pass}" "${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/state.zip" -d "${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)" - fi - - # ls -lart ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder) - - if [ -f "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/state.zip ]; then - pass=$(echo $(System.CollectionId) | sed 's/-//g') - - echo "Unzipping the deployer state file" - unzip -o -qq -P "${pass}" "${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/state.zip" -d "${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)" - fi - - # ls -lart "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder) - - export TF_LOG_PATH=${CONFIG_REPO_PATH}/.sap_deployment_automation/terraform.log - - sudo chmod +x $SAP_AUTOMATION_REPO_PATH/deploy/scripts/deploy_controlplane.sh - if [ $USE_MSI != "true" ]; then - echo "Deployment credentials: Service Principal" - echo "Deployment credential ID (SPN): $CP_ARM_CLIENT_ID" - echo "Deployer subscription: $CP_ARM_SUBSCRIPTION_ID" - - export TF_VAR_use_spn=true - - $SAP_AUTOMATION_REPO_PATH/deploy/scripts/deploy_controlplane.sh \ - --deployer_parameter_file "${deployer_configfile}" \ - --library_parameter_file "${library_configfile}" \ - --subscription $STATE_SUBSCRIPTION \ - --spn_secret "${ARM_CLIENT_SECRET}" \ - --tenant_id "${ARM_TENANT_ID}" \ - --auto-approve --ado \ - ${storage_account_parameter} ${keyvault_parameter} - else - echo "Deployment credentials: Managed Identity" - export TF_VAR_use_spn=false - - ${SAP_AUTOMATION_REPO_PATH}/deploy/scripts/deploy_controlplane.sh \ - --deployer_parameter_file "${deployer_configfile}" \ - --library_parameter_file "${library_configfile}" \ - --subscription "${STATE_SUBSCRIPTION}" --ado --msi \ - "${storage_account_parameter}" "${keyvault_parameter}" \ - --auto-approve - - fi - - return_code=$? - - if [ 0 != $return_code ]; then - echo "##vso[task.logissue type=error]Return code from deploy_controlplane $return_code." - if [ -f .sap_deployment_automation/"${ENVIRONMENT}${LOCATION}".err ]; then - error_message=$(cat .sap_deployment_automation/"${ENVIRONMENT}${LOCATION}".err) - echo "##vso[task.logissue type=error]Error message: $error_message." - fi - fi - - echo -e "$green--- Adding deployment automation configuration to devops repository ---$reset" - added=0 - cd "${CONFIG_REPO_PATH}" || exit - git fetch -q --all - git pull -q - - if [ -f "${deployer_environment_file_name}" ]; then - - file_deployer_tfstate_key=$(grep "^deployer_tfstate_key=" "${deployer_environment_file_name}" | awk -F'=' '{print $2}' | xargs) - echo "Deployer State: ${file_deployer_tfstate_key}" - - file_key_vault=$(grep "^keyvault=" "${deployer_environment_file_name}" | awk -F'=' '{print $2}' | xargs) - echo "Deployer Keyvault: ${file_key_vault}" - - file_REMOTE_STATE_SA=$(grep "^REMOTE_STATE_SA=" "${deployer_environment_file_name}" | awk -F'=' '{print $2}' | xargs) - echo "Terraform account: ${file_REMOTE_STATE_SA}" - - file_REMOTE_STATE_RG=$(grep "^REMOTE_STATE_RG=" "${deployer_environment_file_name}" | awk -F'=' '{print $2}' | xargs) - echo "Terraform rgname: ${file_REMOTE_STATE_SA}" - fi - - echo -e "$green--- Update repo ---$reset" - if [ -f .sap_deployment_automation/"${ENVIRONMENT}${LOCATION}" ]; then - git add .sap_deployment_automation/"${ENVIRONMENT}${LOCATION}" - added=1 - fi - - if [ -f .sap_deployment_automation/"${ENVIRONMENT}${LOCATION}".md ]; then - git add .sap_deployment_automation/"${ENVIRONMENT}${LOCATION}".md - added=1 - fi - - if [ -f "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/.terraform/terraform.tfstate ]; then - git add -f "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/.terraform/terraform.tfstate - added=1 - fi - # || true suppresses the exitcode of grep. To not trigger the strict exit on error - backend=$(grep "local" "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/.terraform/terraform.tfstate || true) - if [ -n "${backend}" ]; then - echo "Local Terraform state" - if [ -f "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/terraform.tfstate ]; then - sudo apt-get -qq install zip - echo "Compressing the deployer state file" - pass=$(echo $(System.CollectionId) | sed 's/-//g') - zip -q -j -P "${pass}" "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/state "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/terraform.tfstate - git add -f "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/state.zip - added=1 - fi - else - echo "Remote Terraform state" - if [ -f "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/terraform.tfstate ]; then - git rm -q --ignore-unmatch -f "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/terraform.tfstate - added=1 - fi - if [ -f "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/state.zip ]; then - git rm -q --ignore-unmatch -f "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/state.zip - added=1 - fi - fi - - # || true suppresses the exitcode of grep. To not trigger the strict exit on error - backend=$(grep "local" "${CONFIG_REPO_PATH}"/LIBRARY/$(libraryfolder)/.terraform/terraform.tfstate || true) - if [ -n "${backend}" ]; then - echo "Local Terraform state" - if [ -f "${CONFIG_REPO_PATH}"/LIBRARY/$(libraryfolder)/terraform.tfstate ]; then - sudo apt-get -qq install zip - echo "Compressing the library state file" - pass=$(echo $(System.CollectionId) | sed 's/-//g') - zip -q -j -P "${pass}" "${CONFIG_REPO_PATH}"/LIBRARY/$(libraryfolder)/state ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/terraform.tfstate - git add -f "${CONFIG_REPO_PATH}"/LIBRARY/$(libraryfolder)/state.zip - added=1 - fi - else - echo "Remote Terraform state" - if [ -f ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/terraform.tfstate ]; then - git rm -q -f --ignore-unmatch "${CONFIG_REPO_PATH}"/LIBRARY/$(libraryfolder)/terraform.tfstate - added=1 - fi - if [ -f ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/state.zip ]; then - git rm -q --ignore-unmatch -f "${CONFIG_REPO_PATH}"/LIBRARY/$(libraryfolder)/state.zip - added=1 - fi - fi - - if [ -f ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/.terraform/terraform.tfstate ]; then - git add -f "${CONFIG_REPO_PATH}"/LIBRARY/$(libraryfolder)/.terraform/terraform.tfstate - added=1 - fi - - if [ 1 = $added ]; then - git config --global user.email "$(Build.RequestedForEmail)" - git config --global user.name "$(Build.RequestedFor)" - git commit -m "Added updates from control plane deployment $(Build.DefinitionName) [skip ci]" + fi + exit $return_code + + displayName: Prepare control plane + env: + CP_ARM_CLIENT_ID: $(CP_ARM_CLIENT_ID) + CP_ARM_CLIENT_SECRET: $(CP_ARM_CLIENT_SECRET) + ARM_SUBSCRIPTION_ID: $(CP_ARM_SUBSCRIPTION_ID) + CP_ARM_TENANT_ID: $(CP_ARM_TENANT_ID) + AZURE_DEVOPS_EXT_PAT: $(PAT) + CONFIG_REPO_PATH: ${{ parameters.config_repo_path }}/$(Deployment_Configuration_Path) + DEPLOYER_RANDOM_ID_SEED: $(DEPLOYER_RANDOM_ID_SEED) + DEPLOYER_TFSTATE_KEY: "${{ parameters.deployer }}.terraform.tfstate" + IS_PIPELINE_DEPLOYMENT: true + POOL: $(POOL) + SAP_AUTOMATION_REPO_PATH: ${{ parameters.sap_automation_repo_path }} + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + TF_APP_REGISTRATION_APP_ID: $(APP_REGISTRATION_APP_ID) + TF_IN_AUTOMATION: true + TF_LOG: $(TF_LOG) + TF_VAR_agent_ado_url: $(System.CollectionUri) + TF_VAR_agent_pat: $(PAT) + TF_VAR_agent_pool: $(POOL) + TF_VAR_ansible_core_version: $(ansible_core_version) + TF_VAR_app_registration_app_id: $(APP_REGISTRATION_APP_ID) + TF_VAR_deployer_kv_user_arm_id: $(Deployer_Key_Vault) + TF_VAR_spn_id: $(CP_ARM_OBJECT_ID) + TF_VAR_tf_version: $(tf_version) + TF_VAR_use_webapp: ${{ lower(parameters.use_webapp_param) }} + TF_VAR_webapp_client_secret: $(WEB_APP_CLIENT_SECRET) + USE_MSI: $(Use_MSI) + USE_WEBAPP: ${{ lower(parameters.use_webapp_param) }} + WEB_APP_CLIENT_SECRET: $(WEB_APP_CLIENT_SECRET) + +- stage: Deploy_controlplane + dependsOn: + - Prepare_Deployer + condition: eq(dependencies.Prepare_Deployer.result, 'Succeeded') + pool: $(this_agent) + variables: + - template: variables/01-deploy-control-plane-variables.yaml + parameters: + deployer: ${{ parameters.deployer }} + library: ${{ parameters.library }} + environment: ${{ parameters.environment }} + use_webapp_param: ${{ parameters.use_webapp_param }} + use_deployer: ${{ parameters.use_deployer }} + displayName: Deploy the control plane + + jobs: + - job: Deploy_controlplane + displayName: Deploy the control plane + workspace: + clean: all + steps: + - task: PostBuildCleanup@4 + - template: templates\download.yaml + parameters: + getLatestFromBranch: true + - bash: | + #!/bin/bash + set -u + + echo "##vso[build.updatebuildnumber]Deploying the control plane defined in $(deployerfolder) $(libraryfolder)" + green="\e[1;32m" + reset="\e[0m" + boldred="\e[1;31m" + cyan="\e[1;36m" + + ENVIRONMENT=$(echo $(deployerfolder) | awk -F'-' '{print $1}' | xargs) + LOCATION=$(echo $(deployerfolder) | awk -F'-' '{print $2}' | xargs) + deployer_environment_file_name=${CONFIG_REPO_PATH}/.sap_deployment_automation/"${ENVIRONMENT}${LOCATION}" + file_deployer_tfstate_key=$(deployerfolder).tfstate + file_key_vault="" + file_REMOTE_STATE_SA="" + file_REMOTE_STATE_RG=$(deployerfolder) + REMOTE_STATE_SA="" + REMOTE_STATE_RG=$(deployerfolder) + + if [[ -f /etc/profile.d/deploy_server.sh ]]; then + path=$(grep -m 1 "export PATH=" /etc/profile.d/deploy_server.sh | awk -F'=' '{print $2}' | xargs) + export PATH=$path + fi + + echo -e "$green--- Information ---$reset" + echo "Environment: ${ENVIRONMENT}" + echo "Location: ${LOCATION}" + echo "Agent: $(this_agent)" + echo "Organization: $(System.CollectionUri)" + echo "Project: $(System.TeamProject)" + echo "Deployer Folder: $(deployerfolder)" + echo "Deployer TFvars: $(deployerconfig)" + echo "Library Folder: $(libraryfolder)" + echo "Library TFvars: $(libraryconfig)" + + echo "" + echo "Azure CLI version:" + echo "-------------------------------------------------" + az --version + echo "" + echo "Terraform version:" + echo "-------------------------------------------------" + if [ -f /opt/terraform/bin/terraform ]; then + tfPath="/opt/terraform/bin/terraform" + else + tfPath=$(which terraform) + fi + + "${tfPath}" --version + echo -e "$green--- Checkout $(Build.SourceBranchName) ---$reset" + cd "$CONFIG_REPO_PATH" || exit + git checkout -q $(Build.SourceBranchName) + + deployer_configfile="${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig)" + library_configfile="${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig)" + + deployer_configfile="${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig)" + library_configfile="${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig)" + + echo -e "$green--- Configure devops CLI extension ---$reset" + az config set extension.use_dynamic_install=yes_without_prompt --only-show-errors + az extension add --name azure-devops --output none --only-show-errors + + az devops configure --defaults organization=$(System.CollectionUri) project='$(System.TeamProject)' + + VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(variable_group)'].id | [0]") + export VARIABLE_GROUP_ID + if [ -z "${VARIABLE_GROUP_ID}" ]; then + echo "##vso[task.logissue type=error]Variable group $(variable_group) could not be found." + exit 2 + fi + + printf -v tempval '%s id:' $(variable_group) + printf -v val '%-20s' "${tempval}" + echo "$val $VARIABLE_GROUP_ID" + + echo -e "$green--- Variables ---$reset" + az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Deployer_Key_Vault.value" --output tsv) + if [ -n "${az_var}" ]; then + export key_vault="${az_var}" + else + if [ -f "${deployer_environment_file_name}" ] ; then + + key_vault=$(grep "^keyvault=" "${deployer_environment_file_name}" | awk -F'=' '{print $2}' | xargs) + az pipelines variable-group variable create --group-id "${VARIABLE_GROUP_ID}" --name Deployer_Key_Vault --value "${key_vault}" --output none --only-show-errors + fi + fi + + az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Terraform_Remote_Storage_Subscription.value" --output tsv) + if [ -n "${az_var}" ]; then + export STATE_SUBSCRIPTION="${az_var}" + else + if [ -f "${deployer_environment_file_name}" ] ; then + export STATE_SUBSCRIPTION=$(grep "^STATE_SUBSCRIPTION=" "${deployer_environment_file_name}" | awk -F'=' '{print $2}' | xargs) + az pipelines variable-group variable create --group-id "${VARIABLE_GROUP_ID}" --name Terraform_Remote_Storage_Subscription --value "${STATE_SUBSCRIPTION}" --output none --only-show-errors + fi + fi + + az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "DEPLOYER_RANDOM_ID_SEED.value" --output tsv) + if [ -n "${az_var}" ]; then + deployer_random_id="${az_var}" + else + deployer_random_id=$(grep "^deployer_random_id=" "${deployer_environment_file_name}" | awk -F'=' '{print $2}' | xargs) + az pipelines variable-group variable create --group-id "${VARIABLE_GROUP_ID}" --name DEPLOYER_RANDOM_ID_SEED --value "${deployer_random_id}" --output none --only-show-errors + fi + + az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Terraform_Remote_Storage_Account_Name.value" --output tsv) + if [ -n "${az_var}" ]; then + export REMOTE_STATE_SA="${az_var}" + else + if [ -f "${deployer_environment_file_name}" ] ; then + REMOTE_STATE_SA=$(grep "^REMOTE_STATE_SA=" "${deployer_environment_file_name}" | awk -F'=' '{print $2}' | xargs) + fi + fi + + echo "Terraform state subscription: $STATE_SUBSCRIPTION" + if [ -n "${REMOTE_STATE_RG}" ]; then + echo "Terraform state rg name: $REMOTE_STATE_RG" + fi + if [ -n "${REMOTE_STATE_SA}" ]; then + echo "Terraform storage account: $REMOTE_STATE_SA" + fi + + echo "Deployer Key Vault: ${key_vault}" + echo "Deployer TFvars: $(deployerconfig)" + + storage_account_parameter="" + if [ -n "${REMOTE_STATE_SA}" ]; then + storage_account_parameter=" --storageaccountname ${REMOTE_STATE_SA} " + else + sed -i 's/step=2/step=1/' "$deployer_environment_file_name" + sed -i 's/step=3/step=1/' "$deployer_environment_file_name" + fi + + keyvault_parameter="" + if [ -n "${key_vault}" ]; then + keyvault_parameter=" --vault ${key_vault} " + fi + + echo -e "$green--- Validations ---$reset" + + if [ -z "${TF_VAR_ansible_core_version}" ]; then + export TF_VAR_ansible_core_version=2.15 + fi + + if [ "$USE_WEBAPP" = "true" ]; then + echo "Deploy Web Application: true" + + if [ -z "${APP_REGISTRATION_APP_ID}" ]; then + echo "##vso[task.logissue type=error]Variable APP_REGISTRATION_APP_ID was not defined." + exit 2 + fi + + if [ -z "${WEB_APP_CLIENT_SECRET}" ]; then + echo "##vso[task.logissue type=error]Variable WEB_APP_CLIENT_SECRET was not defined." + exit 2 + fi + TF_VAR_app_registration_app_id=$(APP_REGISTRATION_APP_ID); + echo "App Registration ID: ${TF_VAR_app_registration_app_id}" + export TF_VAR_app_registration_app_id + TF_VAR_webapp_client_secret=$(WEB_APP_CLIENT_SECRET) + export TF_VAR_webapp_client_secret + export TF_VAR_use_webapp=true + else + echo "Deploy Web Application: false" + fi + + bootstrapped=0 + + if [ ! -f "$deployer_environment_file_name" ]; then + az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Terraform_Remote_Storage_Account_Name.value" --out tsv) + if [[ ${#az_var} -ne 0 ]]; then + echo "REMOTE_STATE_SA="${az_var} + echo "REMOTE_STATE_SA="${az_var} | tee -a "$deployer_environment_file_name" > /dev/null + echo "STATE_SUBSCRIPTION="$ARM_SUBSCRIPTION_ID | tee -a "$deployer_environment_file_name" > /dev/null + fi + + az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Terraform_Remote_Storage_Resource_Group_Name.value" --out tsv) + if [[ ${#az_var} -ne 0 ]]; then + echo "REMOTE_STATE_RG="${az_var} + echo "REMOTE_STATE_RG="${az_var} | tee -a "$deployer_environment_file_name" > /dev/null + echo "step=3" | tee -a "$deployer_environment_file_name" > /dev/null + + fi + + az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Deployer_State_FileName.value" --out tsv) + if [[ ${#az_var} -ne 0 ]]; then + echo "deployer_tfstate_key="${az_var} | tee -a "$deployer_environment_file_name" > /dev/null + fi + + az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Deployer_Key_Vault.value" --out tsv) + if [[ ${#az_var} -ne 0 ]]; then + echo "keyvault="${az_var} | tee -a "$deployer_environment_file_name" > /dev/null + bootstrapped=1 + fi + + fi + + echo -e "$green--- Update .sap_deployment_automation/config as SAP_AUTOMATION_REPO_PATH can change on devops agent ---$reset" + cd ${CONFIG_REPO_PATH} + mkdir -p .sap_deployment_automation + echo SAP_AUTOMATION_REPO_PATH=$SAP_AUTOMATION_REPO_PATH >.sap_deployment_automation/config + export SAP_AUTOMATION_REPO_PATH=$SAP_AUTOMATION_REPO_PATH + + echo -e "$green--- File Validations ---$reset" + if [ ! -f "${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig)" ]; then + echo -e "$boldred--- File "${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig)" was not found ---$reset" + echo "##vso[task.logissue type=error]File "${CONFIG_REPO_PATH}/${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig)" was not found." + exit 2 + fi + + if [ ! -f "${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig)" ]; then + echo -e "$boldred--- File ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig) was not found ---$reset" + echo "##vso[task.logissue type=error]File ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig) was not found." + exit 2 + fi + + # Check if running on deployer + if [[ ! -f /etc/profile.d/deploy_server.sh ]]; then + echo -e "$green--- Install dos2unix ---$reset" + sudo apt-get -qq install dos2unix + + sudo apt-get -qq install zip + + echo -e "$green --- Install terraform ---$reset" + + wget -q $(tf_url) + return_code=$? + if [ 0 != $return_code ]; then + echo "##vso[task.logissue type=error]Unable to download Terraform version $(tf_version)." + exit 2 + fi + unzip -qq terraform_$(tf_version)_linux_amd64.zip ; sudo mv terraform /bin/ + rm -f terraform_$(tf_version)_linux_amd64.zip + + az extension add --name storage-blob-preview >/dev/null + echo -e "$green--- az login ---$reset" + export ARM_CLIENT_ID=$CP_ARM_CLIENT_ID + export ARM_CLIENT_SECRET=$CP_ARM_CLIENT_SECRET + export ARM_TENANT_ID=$CP_ARM_TENANT_ID + export ARM_SUBSCRIPTION_ID=$CP_ARM_SUBSCRIPTION_ID + az login --service-principal --username "$ARM_CLIENT_ID" --password="$ARM_CLIENT_SECRET" --tenant "$ARM_TENANT_ID" --output none + return_code=$? + if [ 0 != $return_code ]; then + echo -e "$boldred--- Login failed ---$reset" + echo "##vso[task.logissue type=error]az login failed." + exit $return_code + fi + + az account set --subscription "$ARM_SUBSCRIPTION_ID" + + else + echo "Sourcing the deploy_server.sh" + . /etc/profile.d/deploy_server.sh ; /opt/bin/terraform/terraform --version + + if [ $USE_MSI != "true" ]; then + echo "Deployment credentials: Service Principal" + echo "Deployment credential ID (SPN): $CP_ARM_CLIENT_ID" + echo "Deployer subscription: $CP_ARM_SUBSCRIPTION_ID" + + export ARM_CLIENT_ID=$CP_ARM_CLIENT_ID + export ARM_CLIENT_SECRET=$CP_ARM_CLIENT_SECRET + export ARM_TENANT_ID=$CP_ARM_TENANT_ID + export ARM_SUBSCRIPTION_ID=$CP_ARM_SUBSCRIPTION_ID + unset ARM_USE_MSI + az login --service-principal --username "${ARM_CLIENT_ID}" --password="${ARM_CLIENT_SECRET}" --tenant "${ARM_TENANT_ID}" --output none + + return_code=$? + if [ 0 != $return_code ]; then + echo -e "$boldred--- Login failed ---$reset" + echo "##vso[task.logissue type=error]az login failed." + exit $return_code + fi + az account set --subscription $ARM_SUBSCRIPTION_ID + else + echo "Deployment credentials: Managed Identity" - git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" push --set-upstream origin $(Build.SourceBranchName) - fi + # export ARM_SUBSCRIPTION_ID=$ARM_SUBSCRIPTION_ID + export ARM_USE_MSI=true + export ARM_USE_AZUREAD=true + unset ARM_CLIENT_SECRET + az account set --subscription $ARM_SUBSCRIPTION_ID + fi + fi - if [ -f "${CONFIG_REPO_PATH}"/.sap_deployment_automation/"${ENVIRONMENT}""${LOCATION}".md ]; then - echo "##vso[task.uploadsummary]${CONFIG_REPO_PATH}/.sap_deployment_automation/"${ENVIRONMENT}${LOCATION}".md" - fi + echo -e "$green--- Configure parameters ---$reset" - echo -e "$green--- Adding variables to the variable group:" $(variable_group) "---$reset" - if [ 0 = $return_code ]; then - az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Terraform_Remote_Storage_Account_Name.value" --out tsv) - if [ -z ${az_var} ]; then - az pipelines variable-group variable create --group-id "${VARIABLE_GROUP_ID}" --name Terraform_Remote_Storage_Account_Name --value "${file_REMOTE_STATE_SA}" --output none --only-show-errors - else - az pipelines variable-group variable update --group-id "${VARIABLE_GROUP_ID}" --name Terraform_Remote_Storage_Account_Name --value "${file_REMOTE_STATE_SA}" --output none --only-show-errors - fi + echo -e "$green--- Convert config files to UX format ---$reset" + dos2unix -q "${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/$(deployerconfig)" + dos2unix -q "${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/$(libraryconfig)" - az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Terraform_Remote_Storage_Resource_Group_Name.value" --out tsv) - if [ -z ${az_var} ]; then - az pipelines variable-group variable create --group-id "${VARIABLE_GROUP_ID}" --name Terraform_Remote_Storage_Resource_Group_Name --value "${file_REMOTE_STATE_RG}" --output none --only-show-errors - else - az pipelines variable-group variable update --group-id "${VARIABLE_GROUP_ID}" --name Terraform_Remote_Storage_Resource_Group_Name --value "${file_REMOTE_STATE_RG}" --output none --only-show-errors - fi + echo -e "$green--- Configuring variables ---$reset" - az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Terraform_Remote_Storage_Subscription.value" --out tsv) - if [ -z ${az_var} ]; then - az pipelines variable-group variable create --group-id "${VARIABLE_GROUP_ID}" --name Terraform_Remote_Storage_Subscription --value "${ARM_SUBSCRIPTION_ID}" --output none --only-show-errors - else - az pipelines variable-group variable update --group-id "${VARIABLE_GROUP_ID}" --name Terraform_Remote_Storage_Subscription --value "${ARM_SUBSCRIPTION_ID}" --output none --only-show-errors - fi + deployer_environment_file_name=${CONFIG_REPO_PATH}/.sap_deployment_automation/${ENVIRONMENT}$LOCATION - az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Deployer_State_FileName.value" --out tsv) - if [ -z ${az_var} ]; then - az pipelines variable-group variable create --group-id "${VARIABLE_GROUP_ID}" --name Deployer_State_FileName --value "${file_deployer_tfstate_key}" --output none --only-show-errors - else - az pipelines variable-group variable update --group-id "${VARIABLE_GROUP_ID}" --name Deployer_State_FileName --value "${file_deployer_tfstate_key}" --output none --only-show-errors - fi + export key_vault="" + ip_added=0 - az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Deployer_Key_Vault.value" --out tsv) - if [ -z ${az_var} ]; then - az pipelines variable-group variable create --group-id "${VARIABLE_GROUP_ID}" --name Deployer_Key_Vault --value "${file_key_vault}" --output none --only-show-errors - else - az pipelines variable-group variable update --group-id "${VARIABLE_GROUP_ID}" --name Deployer_Key_Vault --value "${file_key_vault}" --output none --only-show-errors - fi + if [ -f "${deployer_environment_file_name}" ]; then + if [ 0 = $bootstrapped ]; then + key_vault=$(grep "^keyvault=" "${deployer_environment_file_name}" | awk -F'=' '{print $2}' | xargs) + export key_vault + if [ -n "${key_vault}" ]; then - az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "ControlPlaneEnvironment.value" --out tsv) - if [ -z ${az_var} ]; then - az pipelines variable-group variable create --group-id "${VARIABLE_GROUP_ID}" --name ControlPlaneEnvironment --value "${ENVIRONMENT}" --output none --only-show-errors - else - az pipelines variable-group variable update --group-id "${VARIABLE_GROUP_ID}" --name ControlPlaneEnvironment --value "${ENVIRONMENT}" --output none --only-show-errors - fi + key_vault_id=$(az resource list --name "${key_vault}" --resource-type Microsoft.KeyVault/vaults --query "[].id | [0]" -o tsv) + if [ -n "${key_vault_id}" ]; then - az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "ControlPlaneLocation.value" --out tsv) - if [ -z ${az_var} ]; then - az pipelines variable-group variable create --group-id "${VARIABLE_GROUP_ID}" --name ControlPlaneLocation --value "${LOCATION}" --output none --only-show-errors - else - az pipelines variable-group variable update --group-id "${VARIABLE_GROUP_ID}" --name ControlPlaneLocation --value "${LOCATION}" --output none --only-show-errors + if [ "azure pipelines" = "$(this_agent)" ]; then + this_ip=$(curl -s ipinfo.io/ip) >/dev/null 2>&1 + az keyvault network-rule add --name ${key_vault} --ip-address ${this_ip} --only-show-errors --output none + ip_added=1 fi - fi - exit $return_code - - - displayName: Deploy control plane - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - CP_ARM_SUBSCRIPTION_ID: $(CP_ARM_SUBSCRIPTION_ID) - CP_ARM_CLIENT_ID: $(CP_ARM_CLIENT_ID) - CP_ARM_CLIENT_SECRET: $(CP_ARM_CLIENT_SECRET) - CP_ARM_TENANT_ID: $(CP_ARM_TENANT_ID) - TF_VAR_spn_id: $(CP_ARM_OBJECT_ID) - TF_VAR_agent_pool: $(POOL) - TF_VAR_agent_ado_url: $(System.CollectionUri) - TF_VAR_tf_version: $(tf_version) - TF_VAR_agent_pat: $(PAT) - IS_PIPELINE_DEPLOYMENT: true - WEB_APP_CLIENT_SECRET: $(WEB_APP_CLIENT_SECRET) - APP_REGISTRATION_APP_ID: $(APP_REGISTRATION_APP_ID) - keyvault: $(Deployer_Key_Vault) - POOL: $(POOL) - SAP_AUTOMATION_REPO_PATH: ${{ parameters.sap_automation_repo_path }} - CONFIG_REPO_PATH: ${{ parameters.config_repo_path }}/$(Deployment_Configuration_Path) - TF_VAR_ansible_core_version: $(ansible_core_version) - TF_LOG: $(TF_LOG) - TF_IN_AUTOMATION: true - DEPLOYER_TFSTATE_KEY: "${{ parameters.deployer }}.terraform.tfstate" - LOGON_USING_SPN: $(Logon_Using_SPN) - USE_MSI: $(Use_MSI) - DEPLOYER_RANDOM_ID_SEED: $(DEPLOYER_RANDOM_ID_SEED) - AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) - - failOnStderr: false - - - stage: Web_App_Deployment - pool: $(this_agent) - variables: - - template: variables/01-deploy-control-plane-variables.yaml - parameters: - deployer: ${{ parameters.deployer }} - library: ${{ parameters.library }} - environment: ${{ parameters.environment }} - use_webapp_param: ${{ parameters.use_webapp_param }} - use_deployer: ${{ parameters.use_deployer }} - displayName: Deploy SAP configuration Web App - - dependsOn: - - Deploy_controlplane - - Prepare_Deployer - condition: | - and - ( - eq(${{ parameters.use_webapp_param }}, true), - eq(${{ parameters.deploy_webapp_software }}, true), - eq(dependencies.Deploy_controlplane.result, 'Succeeded'), - eq(dependencies.Prepare_Deployer.result, 'Succeeded') - ) - jobs: - - job: Deploy_web_app - displayName: Deploy SAP configuration Web App - workspace: - clean: all - steps: - - template: templates\download.yaml - - task: PostBuildCleanup@4 - - task: DotNetCoreCLI@2 - displayName: "Build the Configuration Web Application" - inputs: - command: "build" - projects: "$(System.DefaultWorkingDirectory)/sap-automation/Webapp/SDAF/*.csproj" - - task: DotNetCoreCLI@2 - displayName: "Publish the Configuration Web Application" - inputs: - command: publish - projects: "**/Webapp/**/*.csproj" - publishWebProjects: false - arguments: "--output $(Build.ArtifactStagingDirectory)/WebApp" - zipAfterPublish: true - modifyOutputPath: true - - - task: AzureWebApp@1 - displayName: "Deploy the Configuration Web Application" - inputs: - azureSubscription: ${{parameters.connection_name}} - appType: "webApp" - appName: $(WEBAPP_URL_BASE) - package: "$(Build.ArtifactStagingDirectory)/WebApp/*.zip" - deploymentMethod: "auto" - appSettings: '-CollectionUri $(System.CollectionUri) - -ProjectName "$(System.TeamProject)" - -RepositoryId $(Build.Repository.ID) - -SourceBranch "$(Build.SourceBranchName)" - -WORKLOADZONE_PIPELINE_ID $(WORKLOADZONE_PIPELINE_ID) - -SYSTEM_PIPELINE_ID $(SYSTEM_PIPELINE_ID) - -SAP_INSTALL_PIPELINE_ID $(SAP_INSTALL_PIPELINE_ID) - -SDAF_GENERAL_GROUP_ID $(SDAF_GENERAL_GROUP_ID) - -IS_PIPELINE_DEPLOYMENT true - -CONTROLPLANE_ENV $(ControlPlaneEnvironment) - -CONTROLPLANE_LOC $(ControlPlaneLocation)' - env: - ARM_SUBSCRIPTION_ID: $(CP_ARM_SUBSCRIPTION_ID) - SYSTEM_PIPELINE_ID: $(SYSTEM_PIPELINE_ID) - WORKLOADZONE_PIPELINE_ID: $(WORKLOADZONE_PIPELINE_ID) - SAP_INSTALL_PIPELINE_ID: $(SAP_INSTALL_PIPELINE_ID) - SDAF_GENERAL_GROUP_ID: $(SDAF_GENERAL_GROUP_ID) - WEBAPP_URL_BASE: $(WEBAPP_URL_BASE) - WEBAPP_RESOURCE_GROUP: $(WEBAPP_RESOURCE_GROUP) - WEBAPP_ID: $(WEBAPP_ID) - APP_REGISTRATION_APP_ID: $(APP_REGISTRATION_APP_ID) - APP_REGISTRATION_OBJECTID: $(APP_REGISTRATION_OBJECTID) - APP_TENANT_ID: $(APP_TENANT_ID) - AZURE_CONNECTION_NAME: ${{variables.connection_name}} - - - bash: | - #!/bin/bash - printf "Configure the Web Application authentication using the following script.\n" > "$(Build.Repository.LocalPath)/Web Application Configuration.md" - printf "\n\n" >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" - - printf "az ad app update --id %s --web-home-page-url https://%s.azurewebsites.net --web-redirect-uris https://%s.azurewebsites.net/ https://%s.azurewebsites.net/.auth/login/aad/callback\n\n" $(APP_REGISTRATION_APP_ID) $(WEBAPP_URL_BASE) $(WEBAPP_URL_BASE) $(WEBAPP_URL_BASE) >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" - - printf "\n" >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" - printf "az role assignment create --assignee %s --role reader --subscription %s --scope /subscriptions/%s\n" $(WEBAPP_IDENTITY) $ARM_SUBSCRIPTION_ID $ARM_SUBSCRIPTION_ID >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" - printf "Run the above command for all subscriptions you want to use in the Web Application\n" >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" - - printf "\n" >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" - printf "az role assignment create --assignee %s --role 'Storage Blob Data Contributor' --subscription %s --scope /subscriptions/%s/resourceGroups/%s\n" $(WEBAPP_IDENTITY) $ARM_SUBSCRIPTION_ID $ARM_SUBSCRIPTION_ID $(Terraform_Remote_Storage_Resource_Group_Name) >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" - printf "az role assignment create --assignee %s --role 'Storage Table Data Contributor' --subscription %s --scope /subscriptions/%s/resourceGroups/%s \n\n" $(WEBAPP_IDENTITY) $ARM_SUBSCRIPTION_ID $ARM_SUBSCRIPTION_ID $(Terraform_Remote_Storage_Resource_Group_Name) >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" - - printf "\n" >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" - - printf "az rest --method POST --uri \"https://graph.microsoft.com/beta/applications/%s/federatedIdentityCredentials\" --body \"{'name': 'ManagedIdentityFederation', 'issuer': 'https://login.microsoftonline.com/%s/v2.0', 'subject': '%s', 'audiences': [ 'api://AzureADTokenExchange' ]}\"" $(APP_REGISTRATION_OBJECTID) $(APP_TENANT_ID) $(MSI_ID) >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" - printf "\n" >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" - - printf "az webapp restart --ids %s\n\n" $(WEBAPP_ID) >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" - printf "\n" >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" - - printf "[Access the Web App](https://%s.azurewebsites.net)" $(WEBAPP_URL_BASE) >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" - - echo "##vso[task.uploadsummary]$(Build.Repository.LocalPath)/Web Application Configuration.md" - displayName: "Documentation" - env: - ARM_SUBSCRIPTION_ID: $(CP_ARM_SUBSCRIPTION_ID) - SYSTEM_PIPELINE_ID: $(SYSTEM_PIPELINE_ID) - APP_REGISTRATION_APP_ID: $(APP_REGISTRATION_APP_ID) - WEBAPP_URL_BASE: $(WEBAPP_URL_BASE) - WEBAPP_ID: $(WEBAPP_ID) - WEBAPP_IDENTITY: $(WEBAPP_IDENTITY) - + fi + fi + fi + + echo -e "$green--- Deploy the Control Plane ---$reset" + + if [ -n "$(POOL)" ]; then + echo "Deployer Agent Pool: $(POOL)" + fi + + if [ -f "${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/state.zip" ]; then + pass=$(echo $(System.CollectionId) | sed 's/-//g') + + echo "Unzipping the library state file" + unzip -o -qq -P "${pass}" "${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/state.zip" -d "${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)" + fi + + # ls -lart ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder) + + if [ -f "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/state.zip ]; then + pass=$(echo $(System.CollectionId) | sed 's/-//g') + + echo "Unzipping the deployer state file" + unzip -o -qq -P "${pass}" "${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/state.zip" -d "${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)" + fi + + # ls -lart "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder) + + export TF_LOG_PATH=${CONFIG_REPO_PATH}/.sap_deployment_automation/terraform.log + + sudo chmod +x $SAP_AUTOMATION_REPO_PATH/deploy/scripts/deploy_controlplane.sh + if [ $USE_MSI != "true" ]; then + echo "Deployment credentials: Service Principal" + echo "Deployment credential ID (SPN): $CP_ARM_CLIENT_ID" + echo "Deployer subscription: $CP_ARM_SUBSCRIPTION_ID" + + export TF_VAR_use_spn=true + + $SAP_AUTOMATION_REPO_PATH/deploy/scripts/deploy_controlplane.sh \ + --deployer_parameter_file "${deployer_configfile}" \ + --library_parameter_file "${library_configfile}" \ + --subscription $STATE_SUBSCRIPTION \ + --spn_secret "${ARM_CLIENT_SECRET}" \ + --tenant_id "${ARM_TENANT_ID}" \ + --auto-approve --ado \ + ${storage_account_parameter} ${keyvault_parameter} + else + echo "Deployment credentials: Managed Identity" + export TF_VAR_use_spn=false + + ${SAP_AUTOMATION_REPO_PATH}/deploy/scripts/deploy_controlplane.sh \ + --deployer_parameter_file "${deployer_configfile}" \ + --library_parameter_file "${library_configfile}" \ + --subscription "${STATE_SUBSCRIPTION}" --ado --msi \ + "${storage_account_parameter}" "${keyvault_parameter}" \ + --auto-approve + + fi + + return_code=$? + + if [ 0 != $return_code ]; then + echo "##vso[task.logissue type=error]Return code from deploy_controlplane $return_code." + if [ -f .sap_deployment_automation/"${ENVIRONMENT}${LOCATION}".err ]; then + error_message=$(cat .sap_deployment_automation/"${ENVIRONMENT}${LOCATION}".err) + echo "##vso[task.logissue type=error]Error message: $error_message." + fi + fi + + echo -e "$green--- Adding deployment automation configuration to devops repository ---$reset" + added=0 + cd "${CONFIG_REPO_PATH}" || exit + git fetch -q --all + git pull -q + + if [ -f "${deployer_environment_file_name}" ]; then + + file_deployer_tfstate_key=$(grep "^deployer_tfstate_key=" "${deployer_environment_file_name}" | awk -F'=' '{print $2}' | xargs) + echo "Deployer State: ${file_deployer_tfstate_key}" + + file_key_vault=$(grep "^keyvault=" "${deployer_environment_file_name}" | awk -F'=' '{print $2}' | xargs) + echo "Deployer Keyvault: ${file_key_vault}" + + file_REMOTE_STATE_SA=$(grep "^REMOTE_STATE_SA=" "${deployer_environment_file_name}" | awk -F'=' '{print $2}' | xargs) + echo "Terraform account: ${file_REMOTE_STATE_SA}" + + file_REMOTE_STATE_RG=$(grep "^REMOTE_STATE_RG=" "${deployer_environment_file_name}" | awk -F'=' '{print $2}' | xargs) + echo "Terraform rgname: ${file_REMOTE_STATE_SA}" + fi + + echo -e "$green--- Update repo ---$reset" + if [ -f .sap_deployment_automation/"${ENVIRONMENT}${LOCATION}" ]; then + git add .sap_deployment_automation/"${ENVIRONMENT}${LOCATION}" + added=1 + fi + + if [ -f .sap_deployment_automation/"${ENVIRONMENT}${LOCATION}".md ]; then + git add .sap_deployment_automation/"${ENVIRONMENT}${LOCATION}".md + added=1 + fi + + if [ -f "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/.terraform/terraform.tfstate ]; then + git add -f "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/.terraform/terraform.tfstate + added=1 + fi + # || true suppresses the exitcode of grep. To not trigger the strict exit on error + backend=$(grep "local" "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/.terraform/terraform.tfstate || true) + if [ -n "${backend}" ]; then + echo "Local Terraform state" + if [ -f "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/terraform.tfstate ]; then + sudo apt-get -qq install zip + echo "Compressing the deployer state file" + pass=$(echo $(System.CollectionId) | sed 's/-//g') + zip -q -j -P "${pass}" "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/state "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/terraform.tfstate + git add -f "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/state.zip + added=1 + fi + else + echo "Remote Terraform state" + if [ -f "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/terraform.tfstate ]; then + git rm -q --ignore-unmatch -f "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/terraform.tfstate + added=1 + fi + if [ -f "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/state.zip ]; then + git rm -q --ignore-unmatch -f "${CONFIG_REPO_PATH}"/DEPLOYER/$(deployerfolder)/state.zip + added=1 + fi + fi + + # || true suppresses the exitcode of grep. To not trigger the strict exit on error + backend=$(grep "local" "${CONFIG_REPO_PATH}"/LIBRARY/$(libraryfolder)/.terraform/terraform.tfstate || true) + if [ -n "${backend}" ]; then + echo "Local Terraform state" + if [ -f "${CONFIG_REPO_PATH}"/LIBRARY/$(libraryfolder)/terraform.tfstate ]; then + sudo apt-get -qq install zip + echo "Compressing the library state file" + pass=$(echo $(System.CollectionId) | sed 's/-//g') + zip -q -j -P "${pass}" "${CONFIG_REPO_PATH}"/LIBRARY/$(libraryfolder)/state ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/terraform.tfstate + git add -f "${CONFIG_REPO_PATH}"/LIBRARY/$(libraryfolder)/state.zip + added=1 + fi + else + echo "Remote Terraform state" + if [ -f ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/terraform.tfstate ]; then + git rm -q -f --ignore-unmatch "${CONFIG_REPO_PATH}"/LIBRARY/$(libraryfolder)/terraform.tfstate + added=1 + fi + if [ -f ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/state.zip ]; then + git rm -q --ignore-unmatch -f "${CONFIG_REPO_PATH}"/LIBRARY/$(libraryfolder)/state.zip + added=1 + fi + fi + + if [ -f ${CONFIG_REPO_PATH}/LIBRARY/$(libraryfolder)/.terraform/terraform.tfstate ]; then + git add -f "${CONFIG_REPO_PATH}"/LIBRARY/$(libraryfolder)/.terraform/terraform.tfstate + added=1 + fi + + if [ 1 = $added ]; then + git config --global user.email "$(Build.RequestedForEmail)" + git config --global user.name "$(Build.RequestedFor)" + git commit -m "Added updates from control plane deployment $(Build.DefinitionName) [skip ci]" + + git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" push --set-upstream origin $(Build.SourceBranchName) + fi + + if [ -f "${CONFIG_REPO_PATH}"/.sap_deployment_automation/"${ENVIRONMENT}""${LOCATION}".md ]; then + echo "##vso[task.uploadsummary]${CONFIG_REPO_PATH}/.sap_deployment_automation/"${ENVIRONMENT}${LOCATION}".md" + fi + + echo -e "$green--- Adding variables to the variable group:" $(variable_group) "---$reset" + if [ 0 = $return_code ]; then + az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Terraform_Remote_Storage_Account_Name.value" --out tsv) + if [ -z ${az_var} ]; then + az pipelines variable-group variable create --group-id "${VARIABLE_GROUP_ID}" --name Terraform_Remote_Storage_Account_Name --value "${file_REMOTE_STATE_SA}" --output none --only-show-errors + else + az pipelines variable-group variable update --group-id "${VARIABLE_GROUP_ID}" --name Terraform_Remote_Storage_Account_Name --value "${file_REMOTE_STATE_SA}" --output none --only-show-errors + fi + + az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Terraform_Remote_Storage_Resource_Group_Name.value" --out tsv) + if [ -z ${az_var} ]; then + az pipelines variable-group variable create --group-id "${VARIABLE_GROUP_ID}" --name Terraform_Remote_Storage_Resource_Group_Name --value "${file_REMOTE_STATE_RG}" --output none --only-show-errors + else + az pipelines variable-group variable update --group-id "${VARIABLE_GROUP_ID}" --name Terraform_Remote_Storage_Resource_Group_Name --value "${file_REMOTE_STATE_RG}" --output none --only-show-errors + fi + + az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Terraform_Remote_Storage_Subscription.value" --out tsv) + if [ -z ${az_var} ]; then + az pipelines variable-group variable create --group-id "${VARIABLE_GROUP_ID}" --name Terraform_Remote_Storage_Subscription --value "${ARM_SUBSCRIPTION_ID}" --output none --only-show-errors + else + az pipelines variable-group variable update --group-id "${VARIABLE_GROUP_ID}" --name Terraform_Remote_Storage_Subscription --value "${ARM_SUBSCRIPTION_ID}" --output none --only-show-errors + fi + + az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Deployer_State_FileName.value" --out tsv) + if [ -z ${az_var} ]; then + az pipelines variable-group variable create --group-id "${VARIABLE_GROUP_ID}" --name Deployer_State_FileName --value "${file_deployer_tfstate_key}" --output none --only-show-errors + else + az pipelines variable-group variable update --group-id "${VARIABLE_GROUP_ID}" --name Deployer_State_FileName --value "${file_deployer_tfstate_key}" --output none --only-show-errors + fi + + az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "Deployer_Key_Vault.value" --out tsv) + if [ -z ${az_var} ]; then + az pipelines variable-group variable create --group-id "${VARIABLE_GROUP_ID}" --name Deployer_Key_Vault --value "${file_key_vault}" --output none --only-show-errors + else + az pipelines variable-group variable update --group-id "${VARIABLE_GROUP_ID}" --name Deployer_Key_Vault --value "${file_key_vault}" --output none --only-show-errors + fi + + az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "ControlPlaneEnvironment.value" --out tsv) + if [ -z ${az_var} ]; then + az pipelines variable-group variable create --group-id "${VARIABLE_GROUP_ID}" --name ControlPlaneEnvironment --value "${ENVIRONMENT}" --output none --only-show-errors + else + az pipelines variable-group variable update --group-id "${VARIABLE_GROUP_ID}" --name ControlPlaneEnvironment --value "${ENVIRONMENT}" --output none --only-show-errors + fi + + az_var=$(az pipelines variable-group variable list --group-id "${VARIABLE_GROUP_ID}" --query "ControlPlaneLocation.value" --out tsv) + if [ -z ${az_var} ]; then + az pipelines variable-group variable create --group-id "${VARIABLE_GROUP_ID}" --name ControlPlaneLocation --value "${LOCATION}" --output none --only-show-errors + else + az pipelines variable-group variable update --group-id "${VARIABLE_GROUP_ID}" --name ControlPlaneLocation --value "${LOCATION}" --output none --only-show-errors + fi + + fi + exit $return_code + + displayName: Deploy control plane + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + CP_ARM_SUBSCRIPTION_ID: $(CP_ARM_SUBSCRIPTION_ID) + CP_ARM_CLIENT_ID: $(CP_ARM_CLIENT_ID) + CP_ARM_CLIENT_SECRET: $(CP_ARM_CLIENT_SECRET) + CP_ARM_TENANT_ID: $(CP_ARM_TENANT_ID) + TF_VAR_spn_id: $(CP_ARM_OBJECT_ID) + TF_VAR_agent_pool: $(POOL) + TF_VAR_agent_ado_url: $(System.CollectionUri) + TF_VAR_tf_version: $(tf_version) + TF_VAR_agent_pat: $(PAT) + IS_PIPELINE_DEPLOYMENT: true + WEB_APP_CLIENT_SECRET: $(WEB_APP_CLIENT_SECRET) + APP_REGISTRATION_APP_ID: $(APP_REGISTRATION_APP_ID) + keyvault: $(Deployer_Key_Vault) + POOL: $(POOL) + SAP_AUTOMATION_REPO_PATH: ${{ parameters.sap_automation_repo_path }} + CONFIG_REPO_PATH: ${{ parameters.config_repo_path }}/$(Deployment_Configuration_Path) + TF_VAR_ansible_core_version: $(ansible_core_version) + TF_LOG: $(TF_LOG) + TF_IN_AUTOMATION: true + DEPLOYER_TFSTATE_KEY: "${{ parameters.deployer }}.terraform.tfstate" + LOGON_USING_SPN: $(Logon_Using_SPN) + USE_MSI: $(Use_MSI) + DEPLOYER_RANDOM_ID_SEED: $(DEPLOYER_RANDOM_ID_SEED) + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) + + failOnStderr: false + +- stage: Web_App_Deployment + pool: $(this_agent) + variables: + - template: variables/01-deploy-control-plane-variables.yaml + parameters: + deployer: ${{ parameters.deployer }} + library: ${{ parameters.library }} + environment: ${{ parameters.environment }} + use_webapp_param: ${{ parameters.use_webapp_param }} + use_deployer: ${{ parameters.use_deployer }} + displayName: Deploy SAP configuration Web App + + dependsOn: + - Deploy_controlplane + - Prepare_Deployer + condition: | + and + ( + eq(${{ parameters.use_webapp_param }}, true), + eq(${{ parameters.deploy_webapp_software }}, true), + eq(dependencies.Deploy_controlplane.result, 'Succeeded'), + eq(dependencies.Prepare_Deployer.result, 'Succeeded') + ) + jobs: + - job: Deploy_web_app + displayName: Deploy SAP configuration Web App + workspace: + clean: all + steps: + - template: templates\download.yaml + - task: PostBuildCleanup@4 + - task: DotNetCoreCLI@2 + displayName: "Build the Configuration Web Application" + inputs: + command: "build" + projects: "$(System.DefaultWorkingDirectory)/sap-automation/Webapp/SDAF/*.csproj" + - task: DotNetCoreCLI@2 + displayName: "Publish the Configuration Web Application" + inputs: + command: publish + projects: "**/Webapp/**/*.csproj" + publishWebProjects: false + arguments: "--output $(Build.ArtifactStagingDirectory)/WebApp" + zipAfterPublish: true + modifyOutputPath: true + + - task: AzureWebApp@1 + displayName: "Deploy the Configuration Web Application" + inputs: + azureSubscription: ${{parameters.connection_name}} + appType: "webApp" + appName: $(WEBAPP_URL_BASE) + package: "$(Build.ArtifactStagingDirectory)/WebApp/*.zip" + deploymentMethod: "auto" + appSettings: '-CollectionUri $(System.CollectionUri) -ProjectName + "$(System.TeamProject)" -RepositoryId $(Build.Repository.ID) + -SourceBranch "$(Build.SourceBranchName)" -WORKLOADZONE_PIPELINE_ID + $(WORKLOADZONE_PIPELINE_ID) -SYSTEM_PIPELINE_ID $(SYSTEM_PIPELINE_ID) + -SAP_INSTALL_PIPELINE_ID $(SAP_INSTALL_PIPELINE_ID) + -SDAF_GENERAL_GROUP_ID $(SDAF_GENERAL_GROUP_ID) + -IS_PIPELINE_DEPLOYMENT true -CONTROLPLANE_ENV + $(ControlPlaneEnvironment) -CONTROLPLANE_LOC $(ControlPlaneLocation)' + env: + ARM_SUBSCRIPTION_ID: $(CP_ARM_SUBSCRIPTION_ID) + SYSTEM_PIPELINE_ID: $(SYSTEM_PIPELINE_ID) + WORKLOADZONE_PIPELINE_ID: $(WORKLOADZONE_PIPELINE_ID) + SAP_INSTALL_PIPELINE_ID: $(SAP_INSTALL_PIPELINE_ID) + SDAF_GENERAL_GROUP_ID: $(SDAF_GENERAL_GROUP_ID) + WEBAPP_URL_BASE: $(WEBAPP_URL_BASE) + WEBAPP_RESOURCE_GROUP: $(WEBAPP_RESOURCE_GROUP) + WEBAPP_ID: $(WEBAPP_ID) + APP_REGISTRATION_APP_ID: $(APP_REGISTRATION_APP_ID) + APP_REGISTRATION_OBJECTID: $(APP_REGISTRATION_OBJECTID) + APP_TENANT_ID: $(APP_TENANT_ID) + AZURE_CONNECTION_NAME: ${{variables.connection_name}} + + - bash: | + #!/bin/bash + printf "Configure the Web Application authentication using the following script.\n" > "$(Build.Repository.LocalPath)/Web Application Configuration.md" + printf "\n\n" >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" + + printf "az ad app update --id %s --web-home-page-url https://%s.azurewebsites.net --web-redirect-uris https://%s.azurewebsites.net/ https://%s.azurewebsites.net/.auth/login/aad/callback\n\n" $(APP_REGISTRATION_APP_ID) $(WEBAPP_URL_BASE) $(WEBAPP_URL_BASE) $(WEBAPP_URL_BASE) >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" + + printf "\n" >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" + printf "az role assignment create --assignee %s --role reader --subscription %s --scope /subscriptions/%s\n" $(WEBAPP_IDENTITY) $ARM_SUBSCRIPTION_ID $ARM_SUBSCRIPTION_ID >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" + printf "Run the above command for all subscriptions you want to use in the Web Application\n" >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" + + printf "\n" >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" + printf "az role assignment create --assignee %s --role 'Storage Blob Data Contributor' --subscription %s --scope /subscriptions/%s/resourceGroups/%s\n" $(WEBAPP_IDENTITY) $ARM_SUBSCRIPTION_ID $ARM_SUBSCRIPTION_ID $(Terraform_Remote_Storage_Resource_Group_Name) >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" + printf "az role assignment create --assignee %s --role 'Storage Table Data Contributor' --subscription %s --scope /subscriptions/%s/resourceGroups/%s \n\n" $(WEBAPP_IDENTITY) $ARM_SUBSCRIPTION_ID $ARM_SUBSCRIPTION_ID $(Terraform_Remote_Storage_Resource_Group_Name) >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" + + printf "\n" >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" + + printf "az rest --method POST --uri \"https://graph.microsoft.com/beta/applications/%s/federatedIdentityCredentials\" --body \"{'name': 'ManagedIdentityFederation', 'issuer': 'https://login.microsoftonline.com/%s/v2.0', 'subject': '%s', 'audiences': [ 'api://AzureADTokenExchange' ]}\"" $(APP_REGISTRATION_OBJECTID) $(APP_TENANT_ID) $(MSI_ID) >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" + printf "\n" >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" + + printf "az webapp restart --ids %s\n\n" $(WEBAPP_ID) >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" + printf "\n" >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" + + printf "[Access the Web App](https://%s.azurewebsites.net)" $(WEBAPP_URL_BASE) >> "$(Build.Repository.LocalPath)/Web Application Configuration.md" + + echo "##vso[task.uploadsummary]$(Build.Repository.LocalPath)/Web Application Configuration.md" + displayName: "Documentation" + env: + ARM_SUBSCRIPTION_ID: $(CP_ARM_SUBSCRIPTION_ID) + SYSTEM_PIPELINE_ID: $(SYSTEM_PIPELINE_ID) + APP_REGISTRATION_APP_ID: $(APP_REGISTRATION_APP_ID) + WEBAPP_URL_BASE: $(WEBAPP_URL_BASE) + WEBAPP_ID: $(WEBAPP_ID) + WEBAPP_IDENTITY: $(WEBAPP_IDENTITY) diff --git a/deploy/pipelines/02-sap-workload-zone.yaml b/deploy/pipelines/02-sap-workload-zone.yaml index 4c6eecb8bc..c5ce0df201 100644 --- a/deploy/pipelines/02-sap-workload-zone.yaml +++ b/deploy/pipelines/02-sap-workload-zone.yaml @@ -6,704 +6,705 @@ # +------------------------------------4--------------------------------------*/ parameters: - - name: workload_zone - displayName: "Workload zone configuration name, use the following syntax: ENV-LOCA-VNET-INFRASTRUCTURE" - type: string - default: DEV-WEEU-SAP01-INFRASTRUCTURE - - - name: workload_environment - displayName: Workload Environment (DEV, QA, PRD, ...) - type: string - default: DEV - - - name: deployer_environment - displayName: Deployer Environment name (MGMT, DEV, QA, PRD, ...) - type: string - default: MGMT - - - name: deployer_region - displayName: Deployer region name code (MGMT, DEV, QA, PRD, ...) - type: string - default: WEEU - values: - - AUCE - - AUC2 - - AUEA - - AUSE - - BRSO - - BRSE - - BRUS - - CACE - - CAEA - - CEIN - - CEUS - - CEUA - - EAAS - - EAUS - - EUSA - - EUS2 - - FRCE - - FRSO - - GENO - - GEWC - - JAEA - - JAWE - - JINC - - JINW - - KOCE - - KOSO - - NCUS - - NOEU - - NOEA - - NOWE - - SANO - - SAWE - - SCUS - - SCUG - - SOEA - - SOIN - - SECE - - SWNO - - SWWE - - UACE - - UANO - - UKSO - - UKWE - - WCUS - - WEEU - - WEIN - - WEUS - - WUS2 - - WUS3 - - - name: inherit_settings - displayName: Inherit Terraform state file information from control plane - type: boolean - default: true - - - name: sap_automation_repo_path - displayName: The local path on the agent where the sap_automation repo can be found - type: string - - - name: config_repo_path - displayName: The local path on the agent where the config repo can be found - type: string - - - name: test - type: boolean - default: false +- name: workload_zone + displayName: "Workload zone configuration name, use the following syntax: + ENV-LOCA-VNET-INFRASTRUCTURE" + type: string + default: DEV-WEEU-SAP01-INFRASTRUCTURE + +- name: workload_environment + displayName: Workload Environment (DEV, QA, PRD, ...) + type: string + default: DEV + +- name: deployer_environment + displayName: Deployer Environment name (MGMT, DEV, QA, PRD, ...) + type: string + default: MGMT + +- name: deployer_region + displayName: Deployer region name code (MGMT, DEV, QA, PRD, ...) + type: string + default: WEEU + values: + - AUCE + - AUC2 + - AUEA + - AUSE + - BRSO + - BRSE + - BRUS + - CACE + - CAEA + - CEIN + - CEUS + - CEUA + - EAAS + - EAUS + - EUSA + - EUS2 + - FRCE + - FRSO + - GENO + - GEWC + - JAEA + - JAWE + - JINC + - JINW + - KOCE + - KOSO + - NCUS + - NOEU + - NOEA + - NOWE + - SANO + - SAWE + - SCUS + - SCUG + - SOEA + - SOIN + - SECE + - SWNO + - SWWE + - UACE + - UANO + - UKSO + - UKWE + - WCUS + - WEEU + - WEIN + - WEUS + - WUS2 + - WUS3 + +- name: inherit_settings + displayName: Inherit Terraform state file information from control plane + type: boolean + default: true + +- name: sap_automation_repo_path + displayName: The local path on the agent where the sap_automation repo can be found + type: string + +- name: config_repo_path + displayName: The local path on the agent where the config repo can be found + type: string + +- name: test + type: boolean + default: false stages: - - stage: Deploy_SAP_workload_zone - condition: and(not(failed()), not(canceled())) +- stage: Deploy_SAP_workload_zone + condition: and(not(failed()), not(canceled())) + displayName: Deploy SAP workload zone + variables: + - template: variables/02-sap-workload-zone-variables.yaml + parameters: + workload_zone: ${{ parameters.workload_zone }} + workload_environment: ${{ parameters.workload_environment }} + deployer_environment: ${{ parameters.deployer_environment }} + deployer_region: ${{ parameters.deployer_region }} + inherit_settings: ${{ parameters.inherit_settings }} + jobs: + - job: Deploy_SAP_workload_zone displayName: Deploy SAP workload zone - variables: - - template: variables/02-sap-workload-zone-variables.yaml - parameters: - workload_zone: ${{ parameters.workload_zone }} - workload_environment: ${{ parameters.workload_environment }} - deployer_environment: ${{ parameters.deployer_environment }} - deployer_region: ${{ parameters.deployer_region }} - inherit_settings: ${{ parameters.inherit_settings }} - jobs: - - job: Deploy_SAP_workload_zone - displayName: Deploy SAP workload zone - workspace: - clean: all - steps: - - template: templates\download.yaml - - task: PostBuildCleanup@4 - - bash: | - #!/bin/bash - green="\e[1;32m" ; reset="\e[0m" ; boldred="\e[1;31m" ; cyan="\e[1;36m" - - echo "##vso[build.updatebuildnumber]Deploying the SAP Workload zone defined in $(workload_zone_folder)" - - # Check if running on deployer - if [ ! -f /etc/profile.d/deploy_server.sh ]; then - echo -e "$green --- Install dos2unix ---$reset" - sudo apt-get -qq install dos2unix - echo -e "$green --- Install terraform ---$reset" - - wget -q $(tf_url) - return_code=$? - if [ 0 != $return_code ]; then - echo "##vso[task.logissue type=error]Unable to download Terraform version $(tf_version)." - exit 2 - fi - unzip -qq terraform_$(tf_version)_linux_amd64.zip ; sudo mv terraform /bin/ - rm -f terraform_$(tf_version)_linux_amd64.zip - else - source /etc/profile.d/deploy_server.sh - fi - - if [ ! -f $CONFIG_REPO_PATH/LANDSCAPE/$(workload_zone_folder)/$(workload_zone_configuration_file) ]; then - echo -e "$boldred--- $(workload_zone_configuration_file) was not found ---$reset" - echo "##vso[task.logissue type=error]File $(workload_zone_configuration_file) was not found." - exit 2 - fi - - echo -e "$green--- Checkout $(Build.SourceBranchName) ---$reset" - - cd "${CONFIG_REPO_PATH}" || exit - mkdir -p .sap_deployment_automation - git checkout -q $(Build.SourceBranchName) - - echo -e "$green--- Validations ---$reset" - if [ $USE_MSI != "true" ]; then - - if [ -z $WL_ARM_SUBSCRIPTION_ID ]; then - echo "##vso[task.logissue type=error]Variable ARM_SUBSCRIPTION_ID was not defined in the $(variable_group) variable group." - exit 2 - fi - - if [ $WL_ARM_SUBSCRIPTION_ID == '$$(ARM_SUBSCRIPTION_ID)' ]; then - echo "##vso[task.logissue type=error]Variable ARM_SUBSCRIPTION_ID was not defined in the $(variable_group) variable group." - exit 2 - fi - - if [ -z $WL_ARM_CLIENT_ID ]; then - echo "##vso[task.logissue type=error]Variable ARM_CLIENT_ID was not defined in the $(variable_group) variable group." - exit 2 - fi - - if [ $WL_ARM_CLIENT_ID == '$$(ARM_CLIENT_ID)' ]; then - echo "##vso[task.logissue type=error]Variable ARM_CLIENT_ID was not defined in the $(variable_group) variable group." - exit 2 - fi - - if [ -z $WL_ARM_CLIENT_SECRET ]; then - echo "##vso[task.logissue type=error]Variable ARM_CLIENT_SECRET was not defined in the $(variable_group) variable group." - exit 2 - fi - - if [ $WL_ARM_CLIENT_SECRET == '$$(ARM_CLIENT_SECRET)' ]; then - echo "##vso[task.logissue type=error]Variable ARM_CLIENT_SECRET was not defined in the $(variable_group) variable group." - exit 2 - fi - - if [ -z $WL_ARM_TENANT_ID ]; then - echo "##vso[task.logissue type=error]Variable ARM_TENANT_ID was not defined in the $(variable_group) variable group." - exit 2 - fi - - if [ $WL_ARM_TENANT_ID == '$$(ARM_TENANT_ID)' ]; then - echo "##vso[task.logissue type=error]Variable ARM_TENANT_ID was not defined in the $(variable_group) variable group." - exit 2 - fi - - if [ -z $CP_ARM_SUBSCRIPTION_ID ]; then - echo "##vso[task.logissue type=error]Variable CP_ARM_SUBSCRIPTION_ID was not defined in the $(parent_variable_group) variable group." - exit 2 - fi - - if [ -z $CP_ARM_CLIENT_ID ]; then - echo "##vso[task.logissue type=error]Variable CP_ARM_CLIENT_ID was not defined in the $(parent_variable_group) variable group." - exit 2 - fi - - if [ -z $CP_ARM_CLIENT_SECRET ]; then - echo "##vso[task.logissue type=error]Variable CP_ARM_CLIENT_SECRET was not defined in the $(parent_variable_group) variable group." - exit 2 - fi - - if [ -z $CP_ARM_TENANT_ID ]; then - echo "##vso[task.logissue type=error]Variable CP_ARM_TENANT_ID was not defined in the $(parent_variable_group) variable group." - exit 2 - fi - fi - - dos2unix -q LANDSCAPE/$(workload_zone_folder)/$(workload_zone_configuration_file) - echo -e "$green--- Read deployment details ---$reset" - - ENVIRONMENT=$(grep "^environment" LANDSCAPE/$(workload_zone_folder)/$(workload_zone_configuration_file) | awk -F'=' '{print $2}' | xargs) - LOCATION=$(grep "^location" LANDSCAPE/$(workload_zone_folder)/$(workload_zone_configuration_file) | awk -F'=' '{print $2}' | xargs | tr 'A-Z' 'a-z') - NETWORK=$(grep "^network_logical_name" LANDSCAPE/$(workload_zone_folder)/$(workload_zone_configuration_file) | awk -F'=' '{print $2}' | xargs) - - ENVIRONMENT_IN_FILENAME=$(echo $(workload_zone_folder) | awk -F'-' '{print $1}' | xargs ) - LOCATION_CODE=$(echo $(workload_zone_folder) | awk -F'-' '{print $2}' | xargs ) - case "$LOCATION_CODE" in - "AUCE") LOCATION_IN_FILENAME="australiacentral" ;; - "AUC2") LOCATION_IN_FILENAME="australiacentral2" ;; - "AUEA") LOCATION_IN_FILENAME="australiaeast" ;; - "AUSE") LOCATION_IN_FILENAME="australiasoutheast" ;; - "BRSO") LOCATION_IN_FILENAME="brazilsouth" ;; - "BRSE") LOCATION_IN_FILENAME="brazilsoutheast" ;; - "BRUS") LOCATION_IN_FILENAME="brazilus" ;; - "CACE") LOCATION_IN_FILENAME="canadacentral" ;; - "CAEA") LOCATION_IN_FILENAME="canadaeast" ;; - "CEIN") LOCATION_IN_FILENAME="centralindia" ;; - "CEUS") LOCATION_IN_FILENAME="centralus" ;; - "CEUA") LOCATION_IN_FILENAME="centraluseuap" ;; - "EAAS") LOCATION_IN_FILENAME="eastasia" ;; - "EAUS") LOCATION_IN_FILENAME="eastus" ;; - "EUSA") LOCATION_IN_FILENAME="eastus2euap" ;; - "EUS2") LOCATION_IN_FILENAME="eastus2" ;; - "EUSG") LOCATION_IN_FILENAME="eastusstg" ;; - "FRCE") LOCATION_IN_FILENAME="francecentral" ;; - "FRSO") LOCATION_IN_FILENAME="francesouth" ;; - "GENO") LOCATION_IN_FILENAME="germanynorth" ;; - "GEWE") LOCATION_IN_FILENAME="germanywest" ;; - "GEWC") LOCATION_IN_FILENAME="germanywestcentral" ;; - "ISCE") LOCATION_IN_FILENAME="israelcentral" ;; - "ITNO") LOCATION_IN_FILENAME="italynorth" ;; - "JAEA") LOCATION_IN_FILENAME="japaneast" ;; - "JAWE") LOCATION_IN_FILENAME="japanwest" ;; - "JINC") LOCATION_IN_FILENAME="jioindiacentral" ;; - "JINW") LOCATION_IN_FILENAME="jioindiawest" ;; - "KOCE") LOCATION_IN_FILENAME="koreacentral" ;; - "KOSO") LOCATION_IN_FILENAME="koreasouth" ;; - "NCUS") LOCATION_IN_FILENAME="northcentralus" ;; - "NOEU") LOCATION_IN_FILENAME="northeurope" ;; - "NOEA") LOCATION_IN_FILENAME="norwayeast" ;; - "NOWE") LOCATION_IN_FILENAME="norwaywest" ;; - "PLCE") LOCATION_IN_FILENAME="polandcentral" ;; - "QACE") LOCATION_IN_FILENAME="qatarcentral" ;; - "SANO") LOCATION_IN_FILENAME="southafricanorth" ;; - "SAWE") LOCATION_IN_FILENAME="southafricawest" ;; - "SCUS") LOCATION_IN_FILENAME="southcentralus" ;; - "SCUG") LOCATION_IN_FILENAME="southcentralusstg" ;; - "SOEA") LOCATION_IN_FILENAME="southeastasia" ;; - "SOIN") LOCATION_IN_FILENAME="southindia" ;; - "SECE") LOCATION_IN_FILENAME="swedencentral" ;; - "SWNO") LOCATION_IN_FILENAME="switzerlandnorth" ;; - "SWWE") LOCATION_IN_FILENAME="switzerlandwest" ;; - "UACE") LOCATION_IN_FILENAME="uaecentral" ;; - "UANO") LOCATION_IN_FILENAME="uaenorth" ;; - "UKSO") LOCATION_IN_FILENAME="uksouth" ;; - "UKWE") LOCATION_IN_FILENAME="ukwest" ;; - "WCUS") LOCATION_IN_FILENAME="westcentralus" ;; - "WEEU") LOCATION_IN_FILENAME="westeurope" ;; - "WEIN") LOCATION_IN_FILENAME="westindia" ;; - "WEUS") LOCATION_IN_FILENAME="westus" ;; - "WUS2") LOCATION_IN_FILENAME="westus2" ;; - "WUS3") LOCATION_IN_FILENAME="westus3" ;; - *) LOCATION_IN_FILENAME="westeurope" ;; - esac - - NETWORK_IN_FILENAME=$(echo $(workload_zone_folder) | awk -F'-' '{print $3}' | xargs ) - - echo "Environment: $ENVIRONMENT" - echo "Location: $LOCATION" - echo "Network: $NETWORK" - - echo "Environment(filename): $ENVIRONMENT_IN_FILENAME" - echo "Location(filename): $LOCATION_IN_FILENAME" - echo "Network(filename): $NETWORK_IN_FILENAME" - - echo "Deployer Environment $(deployer_environment)" - echo "Deployer Region $(deployer_region)" - echo "Workload TFvars $(workload_zone_configuration_file)" - echo "" - - echo "Agent pool: $(this_agent)" - echo "Organization: $(System.CollectionUri)" - echo "Project: $(System.TeamProject)" - echo "" - echo "Azure CLI version:" - echo "-------------------------------------------------" - az --version - - if [ $ENVIRONMENT != $ENVIRONMENT_IN_FILENAME ]; then - echo "##vso[task.logissue type=error]The environment setting in $(workload_zone_configuration_file) '$ENVIRONMENT' does not match the $(workload_zone_configuration_file) file name '$ENVIRONMENT_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-INFRASTRUCTURE" - exit 2 - fi - - if [ $LOCATION != $LOCATION_IN_FILENAME ]; then - echo "##vso[task.logissue type=error]The location setting in $(workload_zone_configuration_file) '$LOCATION' does not match the $(workload_zone_configuration_file) file name '$LOCATION_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-INFRASTRUCTURE" - exit 2 - fi - - if [ $NETWORK != $NETWORK_IN_FILENAME ]; then - echo "##vso[task.logissue type=error]The network_logical_name setting in $(workload_zone_configuration_file) '$NETWORK' does not match the $(workload_zone_configuration_file) file name '$NETWORK_IN_FILENAME-. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-INFRASTRUCTURE" - exit 2 - fi - - echo -e "$green--- Configure devops CLI extension ---$reset" - az config set extension.use_dynamic_install=yes_without_prompt --output none - - az extension add --name azure-devops --output none --only-show-errors - - az devops configure --defaults organization=$(System.CollectionUri) project='$(System.TeamProject)' --output none - - export PARENT_VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(parent_variable_group)'].id | [0]") - - if [ -z ${PARENT_VARIABLE_GROUP_ID} ]; then - echo "##vso[task.logissue type=error]Variable group $(parent_variable_group) could not be found." - exit 2 - fi - - export VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(variable_group)'].id | [0]") - - if [ -z ${VARIABLE_GROUP_ID} ]; then - echo "##vso[task.logissue type=error]Variable group $(variable_group) could not be found." - exit 2 - fi - printf -v tempval '%s id:' $(variable_group) - printf -v val '%-20s' "${tempval}" - echo "$val $VARIABLE_GROUP_ID" - - printf -v tempval '%s id:' $(parent_variable_group) - printf -v val '%-20s' "${tempval}" - echo "$val $PARENT_VARIABLE_GROUP_ID" - - deployer_environment_file_name=$CONFIG_REPO_PATH/.sap_deployment_automation/$(deployer_environment)$(deployer_region) - echo "Deployer Environment File: $deployer_environment_file_name" - - workload_environment_file_name=$CONFIG_REPO_PATH/.sap_deployment_automation/${ENVIRONMENT}${LOCATION_CODE}${NETWORK} - echo "Workload Zone Environment File: $workload_environment_file_name" - - dos2unix -q ${deployer_environment_file_name} - dos2unix -q ${workload_environment_file_name} - - if [ ! -f ${deployer_environment_file_name} ]; then - echo -e "$boldred--- $(deployer_environment)$(deployer_region) was not found ---$reset" - echo "##vso[task.logissue type=error]Control plane configuration file $(deployer_environment)$(deployer_region) was not found." - exit 2 - fi - - echo -e "$green--- Read parameter values ---$reset" - - if [ "true" == $(inherit) ]; then - - az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Deployer_State_FileName.value" --out tsv) - if [ -z ${az_var} ]; then - deployer_tfstate_key=$(grep "^deployer_tfstate_key=" ${deployer_environment_file_name} | awk -F'=' '{print $2}' | xargs) - else - deployer_tfstate_key=${az_var} - fi - - az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Deployer_Key_Vault.value" --out tsv) - if [ -z ${az_var} ]; then - key_vault=$(grep "^keyvault=" ${deployer_environment_file_name} | awk -F'=' '{print $2}' | xargs) - else - key_vault=${az_var} - fi - - az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Account_Name.value" --out tsv) - if [ -z ${az_var} ]; then - REMOTE_STATE_SA=$(grep "^REMOTE_STATE_SA" ${deployer_environment_file_name} | awk -F'=' '{print $2}' | xargs) ; - else - REMOTE_STATE_SA=${az_var} - fi - - az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Subscription.value" --out tsv) - if [ -z ${az_var} ]; then - STATE_SUBSCRIPTION=$(grep "^STATE_SUBSCRIPTION" ${deployer_environment_file_name} | awk -F'=' '{print $2}' | xargs) - else - STATE_SUBSCRIPTION=${az_var} - - fi - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WL_ARM_SUBSCRIPTION_ID.value" --out tsv) - if [ -z ${az_var} ]; then - echo "##vso[task.logissue type=error]Variable WL_ARM_SUBSCRIPTION_ID was not defined." - exit 2 - fi - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Workload_Key_Vault.value" --out tsv) - if [ -z ${az_var} ]; then - if [ -f ${workload_environment_file_name} ]; then - export workload_key_vault=$(grep "^workloadkeyvault" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) - fi - else - export workload_key_vault=$(Workload_Key_Vault) - - fi - else - deployer_tfstate_key=$(grep "^deployer_tfstate_key=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) - - key_vault=$(grep -m1 "^workload_key_vault=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) ; - - REMOTE_STATE_SA=$(grep "^REMOTE_STATE_SA=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) - - STATE_SUBSCRIPTION=$(grep "^STATE_SUBSCRIPTION=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) - fi - - echo "Deployer statefile: $deployer_tfstate_key" - echo "Deployer Key vault: $key_vault" - echo "Workload Key vault: ${workload_key_vault}" - echo "Target subscription $WL_ARM_SUBSCRIPTION_ID" - - echo "Terraform state file subscription: $STATE_SUBSCRIPTION" - echo "Terraform state file storage account:$REMOTE_STATE_SA" - - secrets_set=1 - echo -e "$green---az login ---$reset" - - echo -e "$cyan---Sourcing the deploy_server.sh file$reset" - . /etc/profile.d/deploy_server.sh - - if [ $USE_MSI != "true" ]; then - - echo "Deployment credentials: Service Principal" - echo "Deployment credential ID (SPN): $WL_ARM_CLIENT_ID" - echo "Deployer subscription: $STATE_SUBSCRIPTION" - - export ARM_CLIENT_ID=$WL_ARM_CLIENT_ID - export ARM_CLIENT_SECRET=$WL_ARM_CLIENT_SECRET - export ARM_OBJECT_ID=$WL_ARM_OBJECT_ID - export ARM_TENANT_ID=$WL_ARM_TENANT_ID - export ARM_SUBSCRIPTION_ID=$WL_ARM_SUBSCRIPTION_ID - export ARM_USE_AZUREAD=true - unset ARM_USE_MSI - az login --service-principal --username $ARM_CLIENT_ID --password=$ARM_CLIENT_SECRET --tenant $ARM_TENANT_ID --output none - - return_code=$? - if [ 0 != $return_code ]; then - echo -e "$boldred--- Login failed ---$reset" - echo "##vso[task.logissue type=error]az login failed." - exit $return_code - fi - az account set --subscription $STATE_SUBSCRIPTION - echo -e "$green --- Set secrets ---$reset" - - $SAP_AUTOMATION_REPO_PATH/deploy/scripts/set_secrets.sh --workload --vault "${key_vault}" --environment "${ENVIRONMENT}" \ - --region "${LOCATION}" --subscription $ARM_SUBSCRIPTION_ID --spn_id $ARM_CLIENT_ID --spn_secret "${ARM_CLIENT_SECRET}" \ - --tenant_id $ARM_TENANT_ID --keyvault_subscription $STATE_SUBSCRIPTION - secrets_set=$? ; - echo "Set Secrets returned: $secrets_set" - - else - echo "Deployment credentials: Managed Identity" - # export ARM_SUBSCRIPTION_ID=$ARM_SUBSCRIPTION_ID - export ARM_USE_MSI=true - export ARM_USE_AZUREAD=true - unset ARM_CLIENT_SECRET - fi - - debug_variable='--output none' - debug_variable='' - - if [ $USE_MSI != "true" ]; then - - isUserAccessAdmin=$(az role assignment list --role "User Access Administrator" --subscription $STATE_SUBSCRIPTION --assignee $WL_ARM_OBJECT_ID --query "[].principalName | [0]" --output tsv) - - tfstate_resource_id=$(az resource list --name "${REMOTE_STATE_SA}" --subscription ${STATE_SUBSCRIPTION} --resource-type Microsoft.Storage/storageAccounts --query "[].id | [0]" -o tsv) - - if [ -n "${isUserAccessAdmin}" ]; then - - echo -e "$green--- Set permissions ---$reset" - perms=$(az role assignment list --subscription ${STATE_SUBSCRIPTION} --role "Reader" --assignee $WL_ARM_OBJECT_ID --query "[].principalName | [0]" --output tsv --only-show-errors) - if [ -z "$perms" ]; then - echo -e "$green --- Assign subscription permissions to $perms ---$reset" - az role assignment create --assignee $ARM_OBJECT_ID --role "Reader" --scope "/subscriptions/${STATE_SUBSCRIPTION}" --output none - fi - - perms=$(az role assignment list --subscription ${STATE_SUBSCRIPTION} --role "Storage Blob Data Contributor" --scope "${tfstate_resource_id}" --assignee $WL_ARM_OBJECT_ID --query "[].principalName | [0]" --only-show-errors) - if [ -z "$perms" ]; then - echo "Assigning Storage Account Contributor permissions for $ARM_OBJECT_ID to ${tfstate_resource_id}" - az role assignment create --assignee $ARM_OBJECT_ID --role "Storage Blob Data Contributor" --scope "${tfstate_resource_id}" --output none - fi - - resource_group_name=$(az resource show --id "${tfstate_resource_id}" --query resourceGroup -o tsv) - - if [ -n "${resource_group_name}" ]; then - for scope in $(az resource list --resource-group "${resource_group_name}" --subscription ${STATE_SUBSCRIPTION} --resource-type Microsoft.Network/privateDnsZones --query "[].id" --output tsv); do - perms=$(az role assignment list --subscription ${STATE_SUBSCRIPTION} --role "Private DNS Zone Contributor" --scope $scope --assignee $WL_ARM_OBJECT_ID --query "[].principalName | [0]" --output tsv --only-show-errors) - if [ -z "$perms" ]; then - echo "Assigning DNS Zone Contributor permissions for $WL_ARM_OBJECT_ID to ${scope}" - az role assignment create --assignee $ARM_OBJECT_ID --role "Private DNS Zone Contributor" --scope $scope --output none - fi - done - fi - - resource_group_name=$(az keyvault show --name "${key_vault}" --query resourceGroup --subscription ${STATE_SUBSCRIPTION} -o tsv) - - if [ -n "${resource_group_name}" ]; then - resource_group_id=$(az group show --name ${resource_group_name} --subscription ${STATE_SUBSCRIPTION} --query id -o tsv) - - vnet_resource_id=$(az resource list --resource-group "${resource_group_name}" --subscription ${STATE_SUBSCRIPTION} --resource-type Microsoft.Network/virtualNetworks -o tsv --query "[].id | [0]") - if [ -n "${vnet_resource_id}" ]; then - perms=$(az role assignment list --subscription ${STATE_SUBSCRIPTION} --role "Network Contributor" --scope $vnet_resource_id --query "[].principalName | [0]" --assignee $ARM_OBJECT_ID --output tsv --only-show-errors) - - if [ -z "$perms" ]; then - echo "Assigning Network Contributor rights for $ARM_OBJECT_ID to ${vnet_resource_id}" - az role assignment create --assignee $ARM_OBJECT_ID --role "Network Contributor" --scope $vnet_resource_id --output none - fi - fi - fi - else - echo "##vso[task.logissue type=warning]Service Principal $WL_ARM_CLIENT_ID does not have 'User Access Administrator' permissions. Please ensure that the service principal $WL_ARM_CLIENT_ID has permissions on the Terrafrom state storage account and if needed on the Private DNS zone and the source management network resource" - fi - fi - - echo -e "$green--- Deploy the workload zone ---$reset" - cd $CONFIG_REPO_PATH/LANDSCAPE/$(workload_zone_folder) - if [ -f /etc/profile.d/deploy_server.sh ]; then - if [ $USE_MSI != "true" ]; then - az logout --output none - export ARM_CLIENT_ID=$WL_ARM_CLIENT_ID - export ARM_CLIENT_SECRET=$WL_ARM_CLIENT_SECRET - export ARM_TENANT_ID=$WL_ARM_TENANT_ID - export ARM_SUBSCRIPTION_ID=$WL_ARM_SUBSCRIPTION_ID - unset ARM_USE_MSI - az login --service-principal --username $WL_ARM_CLIENT_ID --password=$WL_ARM_CLIENT_SECRET --tenant $WL_ARM_TENANT_ID --output none - return_code=$? - if [ 0 != $return_code ]; then - echo -e "$boldred--- Login failed ---$reset" - echo "##vso[task.logissue type=error]az login failed." - exit $return_code - fi - $SAP_AUTOMATION_REPO_PATH/deploy/scripts/install_workloadzone.sh --parameterfile $(workload_zone_configuration_file) \ - --deployer_environment $(deployer_environment) --subscription $ARM_SUBSCRIPTION_ID \ - --spn_id $WL_ARM_CLIENT_ID --spn_secret $WL_ARM_CLIENT_SECRET --tenant_id $WL_ARM_TENANT_ID \ - --deployer_tfstate_key "${deployer_tfstate_key}" --keyvault "${key_vault}" --storageaccountname "${REMOTE_STATE_SA}" \ - --state_subscription "${STATE_SUBSCRIPTION}" --auto-approve --ado - else - $SAP_AUTOMATION_REPO_PATH/deploy/scripts/install_workloadzone.sh --parameterfile $(workload_zone_configuration_file) \ - --deployer_environment $(deployer_environment) --subscription $ARM_SUBSCRIPTION_ID \ - --deployer_tfstate_key "${deployer_tfstate_key}" --keyvault "${key_vault}" --storageaccountname "${REMOTE_STATE_SA}" \ - --state_subscription "${STATE_SUBSCRIPTION}" --auto-approve --ado --msi - - fi - - fi - return_code=$? - - echo "Return code from deployment: ${return_code}" - - if [ -f ${workload_environment_file_name} ]; then - export workload_key_vault=$(cat ${workload_environment_file_name} | grep workloadkeyvault= | awk -F'=' '{print $2}' | xargs) - echo "Workload zone key vault: ${workload_key_vault}" - - export workload_prefix=$(cat ${workload_environment_file_name} | grep workload_zone_prefix= | awk -F'=' '{print $2}' | xargs) - echo "Workload zone prefix: ${workload_prefix}" - - export landscape_tfstate_key=$(cat ${workload_environment_file_name} | grep landscape_tfstate_key= | awk -F'=' '{print $2}' | xargs) - echo "Workload zone state file: ${landscape_tfstate_key}" - fi - - expiry_date=$(date -d "+365 days" +%Y-%m-%d) - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "FENCING_SPN_ID.value") - if [ -z ${az_var} ]; then - echo "##vso[task.logissue type=warning]Variable FENCING_SPN_ID is not set. Required for highly available deployments" - else - export fencing_id=$(az keyvault secret list --vault-name $workload_key_vault --subscription $STATE_SUBSCRIPTION --query [].name -o tsv | grep ${workload_prefix}-fencing-spn-id | xargs) - if [ -z "$fencing_id" ]; then - az keyvault secret set --name ${workload_prefix}-fencing-spn-id --vault-name $workload_key_vault --value $(FENCING_SPN_ID) --subscription $STATE_SUBSCRIPTION --expires "$(date -d '+1 year' -u +%Y-%m-%dT%H:%M:%SZ)" --output none - az keyvault secret set --name ${workload_prefix}-fencing-spn-pwd --vault-name $workload_key_vault --value=$FENCING_SPN_PWD --subscription $STATE_SUBSCRIPTION --expires "$(date -d '+1 year' -u +%Y-%m-%dT%H:%M:%SZ)" --output none - az keyvault secret set --name ${workload_prefix}-fencing-spn-tenant --vault-name $workload_key_vault --value $(FENCING_SPN_TENANT) --subscription $STATE_SUBSCRIPTION --expires "$(date -d '+1 year' -u +%Y-%m-%dT%H:%M:%SZ)" --output none - fi - fi - az logout --output none - echo -e "$green--- Add & update files in the DevOps Repository ---$reset" - cd $(Build.Repository.LocalPath) - git pull - - echo -e "$green--- Pull latest ---$reset" - cd $CONFIG_REPO_PATH - git pull - - added=0 - if [ -f ${workload_environment_file_name} ]; then - git add ${workload_environment_file_name} - added=1 - fi - if [ -f ${workload_environment_file_name}.md ]; then - git add ${workload_environment_file_name}.md - added=1 - fi - if [ -f $(Deployment_Configuration_Path)/LANDSCAPE/$(workload_zone_folder)/.terraform/terraform.tfstate ]; then - git add -f $(Deployment_Configuration_Path)/LANDSCAPE/$(workload_zone_folder)/.terraform/terraform.tfstate - added=1 - fi - if [ 1 == $added ]; then - git config --global user.email "$(Build.RequestedForEmail)" - git config --global user.name "$(Build.RequestedFor)" - git commit -m "Added updates from devops deployment $(Build.DefinitionName) [skip ci]" - git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" push --set-upstream origin $(Build.SourceBranchName) - fi - - if [ -f ${workload_environment_file_name}.md ]; then - echo "##vso[task.uploadsummary]${workload_environment_file_name}.md" - fi - echo -e "$green--- Adding variables to the variable group" $(variable_group) "---$reset" - if [ -n "${VARIABLE_GROUP_ID}" ]; then - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query Terraform_Remote_Storage_Account_Name.value --output table) - if [ -n "${az_var}" ]; then - az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name Terraform_Remote_Storage_Account_Name --value "${REMOTE_STATE_SA}" --output none --only-show-errors - else - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name Terraform_Remote_Storage_Account_Name --value "${REMOTE_STATE_SA}" --output none --only-show-errors - fi - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query Terraform_Remote_Storage_Subscription.value --output table) - if [ -n "${az_var}" ]; then - az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name Terraform_Remote_Storage_Subscription --value "${STATE_SUBSCRIPTION}" --output none --only-show-errors - else - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name Terraform_Remote_Storage_Subscription --value "${STATE_SUBSCRIPTION}" --output none --only-show-errors - fi - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query Deployer_State_FileName.value --output table) - if [ -n "${az_var}" ]; then - az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name Deployer_State_FileName --value "${deployer_tfstate_key}" --output none --only-show-errors - else - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name Deployer_State_FileName --value "${deployer_tfstate_key}" --output none --only-show-errors - fi - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query Deployer_Key_Vault.value --output table) - if [ -n "${az_var}" ]; then - az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name Deployer_Key_Vault --value ${key_vault} --output none --only-show-errors - else - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name Deployer_Key_Vault --value ${key_vault} --output none --only-show-errors - fi - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "${NETWORK}"Workload_Key_Vault.value --output table) - if [ -n "${az_var}" ]; then - az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name "${NETWORK}"Workload_Key_Vault --value $workload_key_vault --output none --only-show-errors - else - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name "${NETWORK}"Workload_Key_Vault --value $workload_key_vault --output none --only-show-errors - fi - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "${NETWORK}"Workload_Secret_Prefix.value --output table) - if [ -n "${az_var}" ]; then - az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name "${NETWORK}"Workload_Secret_Prefix --value "${workload_prefix}" --output none --only-show-errors - else - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name "${NETWORK}"Workload_Secret_Prefix --value "${workload_prefix}" --output none --only-show-errors - fi - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "${NETWORK}"Workload_Zone_State_FileName.value --output table) - if [ -n "${az_var}" ]; then - az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name "${NETWORK}"Workload_Zone_State_FileName --value "${landscape_tfstate_key}" --output none --only-show-errors - else - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name "${NETWORK}"Workload_Zone_State_FileName --value "${landscape_tfstate_key}" --output none --only-show-errors - fi - - fi - - if [ 0 != $return_code ]; then - echo "##vso[task.logissue type=error]Return code from install_workloadzone $return_code." - if [ -f ${workload_environment_file_name}.err ]; then - error_message=$(cat ${workload_environment_file_name}.err) - echo "##vso[task.logissue type=error]Error message: $error_message." - fi - - fi - - exit $return_code - - displayName: Deploy SAP Workload Zone - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - WL_ARM_SUBSCRIPTION_ID: $(ARM_SUBSCRIPTION_ID) - WL_ARM_TENANT_ID: $(ARM_TENANT_ID) - WL_ARM_CLIENT_ID: $(ARM_CLIENT_ID) - WL_ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET) - WL_ARM_OBJECT_ID: $(ARM_OBJECT_ID) - CP_ARM_SUBSCRIPTION_ID: $(CP_ARM_SUBSCRIPTION_ID) - CP_ARM_CLIENT_ID: $(CP_ARM_CLIENT_ID) - CP_ARM_CLIENT_SECRET: $(CP_ARM_CLIENT_SECRET) - CP_ARM_TENANT_ID: $(CP_ARM_TENANT_ID) - CP_ARM_OBJECT_ID: $(CP_ARM_OBJECT_ID) - FENCING_SPN_PWD: $(FENCING_SPN_PWD) - SAPBITS: $(INSTALLATION_MEDIA_ACCOUNT) - TEST_ONLY: ${{ parameters.test }} - AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) - TF_LOG: $(TF_LOG) - TF_IN_AUTOMATION: true - SAP_AUTOMATION_REPO_PATH: ${{ parameters.sap_automation_repo_path }} - CONFIG_REPO_PATH: ${{ parameters.config_repo_path }}/$(Deployment_Configuration_Path) - LOGON_USING_SPN: $(Logon_Using_SPN) - USE_MSI: $(Use_MSI) - failOnStderr: false + workspace: + clean: all + steps: + - template: templates\download.yaml + - task: PostBuildCleanup@4 + - bash: | + #!/bin/bash + green="\e[1;32m" ; reset="\e[0m" ; boldred="\e[1;31m" ; cyan="\e[1;36m" + + echo "##vso[build.updatebuildnumber]Deploying the SAP Workload zone defined in $(workload_zone_folder)" + + # Check if running on deployer + if [ ! -f /etc/profile.d/deploy_server.sh ]; then + echo -e "$green --- Install dos2unix ---$reset" + sudo apt-get -qq install dos2unix + echo -e "$green --- Install terraform ---$reset" + + wget -q $(tf_url) + return_code=$? + if [ 0 != $return_code ]; then + echo "##vso[task.logissue type=error]Unable to download Terraform version $(tf_version)." + exit 2 + fi + unzip -qq terraform_$(tf_version)_linux_amd64.zip ; sudo mv terraform /bin/ + rm -f terraform_$(tf_version)_linux_amd64.zip + else + source /etc/profile.d/deploy_server.sh + fi + + if [ ! -f $CONFIG_REPO_PATH/LANDSCAPE/$(workload_zone_folder)/$(workload_zone_configuration_file) ]; then + echo -e "$boldred--- $(workload_zone_configuration_file) was not found ---$reset" + echo "##vso[task.logissue type=error]File $(workload_zone_configuration_file) was not found." + exit 2 + fi + + echo -e "$green--- Checkout $(Build.SourceBranchName) ---$reset" + + cd "${CONFIG_REPO_PATH}" || exit + mkdir -p .sap_deployment_automation + git checkout -q $(Build.SourceBranchName) + + echo -e "$green--- Validations ---$reset" + if [ $USE_MSI != "true" ]; then + + if [ -z $WL_ARM_SUBSCRIPTION_ID ]; then + echo "##vso[task.logissue type=error]Variable ARM_SUBSCRIPTION_ID was not defined in the $(variable_group) variable group." + exit 2 + fi + + if [ $WL_ARM_SUBSCRIPTION_ID == '$$(ARM_SUBSCRIPTION_ID)' ]; then + echo "##vso[task.logissue type=error]Variable ARM_SUBSCRIPTION_ID was not defined in the $(variable_group) variable group." + exit 2 + fi + + if [ -z $WL_ARM_CLIENT_ID ]; then + echo "##vso[task.logissue type=error]Variable ARM_CLIENT_ID was not defined in the $(variable_group) variable group." + exit 2 + fi + + if [ $WL_ARM_CLIENT_ID == '$$(ARM_CLIENT_ID)' ]; then + echo "##vso[task.logissue type=error]Variable ARM_CLIENT_ID was not defined in the $(variable_group) variable group." + exit 2 + fi + + if [ -z $WL_ARM_CLIENT_SECRET ]; then + echo "##vso[task.logissue type=error]Variable ARM_CLIENT_SECRET was not defined in the $(variable_group) variable group." + exit 2 + fi + + if [ $WL_ARM_CLIENT_SECRET == '$$(ARM_CLIENT_SECRET)' ]; then + echo "##vso[task.logissue type=error]Variable ARM_CLIENT_SECRET was not defined in the $(variable_group) variable group." + exit 2 + fi + + if [ -z $WL_ARM_TENANT_ID ]; then + echo "##vso[task.logissue type=error]Variable ARM_TENANT_ID was not defined in the $(variable_group) variable group." + exit 2 + fi + + if [ $WL_ARM_TENANT_ID == '$$(ARM_TENANT_ID)' ]; then + echo "##vso[task.logissue type=error]Variable ARM_TENANT_ID was not defined in the $(variable_group) variable group." + exit 2 + fi + + if [ -z $CP_ARM_SUBSCRIPTION_ID ]; then + echo "##vso[task.logissue type=error]Variable CP_ARM_SUBSCRIPTION_ID was not defined in the $(parent_variable_group) variable group." + exit 2 + fi + + if [ -z $CP_ARM_CLIENT_ID ]; then + echo "##vso[task.logissue type=error]Variable CP_ARM_CLIENT_ID was not defined in the $(parent_variable_group) variable group." + exit 2 + fi + + if [ -z $CP_ARM_CLIENT_SECRET ]; then + echo "##vso[task.logissue type=error]Variable CP_ARM_CLIENT_SECRET was not defined in the $(parent_variable_group) variable group." + exit 2 + fi + + if [ -z $CP_ARM_TENANT_ID ]; then + echo "##vso[task.logissue type=error]Variable CP_ARM_TENANT_ID was not defined in the $(parent_variable_group) variable group." + exit 2 + fi + fi + + dos2unix -q LANDSCAPE/$(workload_zone_folder)/$(workload_zone_configuration_file) + echo -e "$green--- Read deployment details ---$reset" + + ENVIRONMENT=$(grep "^environment" LANDSCAPE/$(workload_zone_folder)/$(workload_zone_configuration_file) | awk -F'=' '{print $2}' | xargs) + LOCATION=$(grep "^location" LANDSCAPE/$(workload_zone_folder)/$(workload_zone_configuration_file) | awk -F'=' '{print $2}' | xargs | tr 'A-Z' 'a-z') + NETWORK=$(grep "^network_logical_name" LANDSCAPE/$(workload_zone_folder)/$(workload_zone_configuration_file) | awk -F'=' '{print $2}' | xargs) + + ENVIRONMENT_IN_FILENAME=$(echo $(workload_zone_folder) | awk -F'-' '{print $1}' | xargs ) + LOCATION_CODE=$(echo $(workload_zone_folder) | awk -F'-' '{print $2}' | xargs ) + case "$LOCATION_CODE" in + "AUCE") LOCATION_IN_FILENAME="australiacentral" ;; + "AUC2") LOCATION_IN_FILENAME="australiacentral2" ;; + "AUEA") LOCATION_IN_FILENAME="australiaeast" ;; + "AUSE") LOCATION_IN_FILENAME="australiasoutheast" ;; + "BRSO") LOCATION_IN_FILENAME="brazilsouth" ;; + "BRSE") LOCATION_IN_FILENAME="brazilsoutheast" ;; + "BRUS") LOCATION_IN_FILENAME="brazilus" ;; + "CACE") LOCATION_IN_FILENAME="canadacentral" ;; + "CAEA") LOCATION_IN_FILENAME="canadaeast" ;; + "CEIN") LOCATION_IN_FILENAME="centralindia" ;; + "CEUS") LOCATION_IN_FILENAME="centralus" ;; + "CEUA") LOCATION_IN_FILENAME="centraluseuap" ;; + "EAAS") LOCATION_IN_FILENAME="eastasia" ;; + "EAUS") LOCATION_IN_FILENAME="eastus" ;; + "EUSA") LOCATION_IN_FILENAME="eastus2euap" ;; + "EUS2") LOCATION_IN_FILENAME="eastus2" ;; + "EUSG") LOCATION_IN_FILENAME="eastusstg" ;; + "FRCE") LOCATION_IN_FILENAME="francecentral" ;; + "FRSO") LOCATION_IN_FILENAME="francesouth" ;; + "GENO") LOCATION_IN_FILENAME="germanynorth" ;; + "GEWE") LOCATION_IN_FILENAME="germanywest" ;; + "GEWC") LOCATION_IN_FILENAME="germanywestcentral" ;; + "ISCE") LOCATION_IN_FILENAME="israelcentral" ;; + "ITNO") LOCATION_IN_FILENAME="italynorth" ;; + "JAEA") LOCATION_IN_FILENAME="japaneast" ;; + "JAWE") LOCATION_IN_FILENAME="japanwest" ;; + "JINC") LOCATION_IN_FILENAME="jioindiacentral" ;; + "JINW") LOCATION_IN_FILENAME="jioindiawest" ;; + "KOCE") LOCATION_IN_FILENAME="koreacentral" ;; + "KOSO") LOCATION_IN_FILENAME="koreasouth" ;; + "NCUS") LOCATION_IN_FILENAME="northcentralus" ;; + "NOEU") LOCATION_IN_FILENAME="northeurope" ;; + "NOEA") LOCATION_IN_FILENAME="norwayeast" ;; + "NOWE") LOCATION_IN_FILENAME="norwaywest" ;; + "PLCE") LOCATION_IN_FILENAME="polandcentral" ;; + "QACE") LOCATION_IN_FILENAME="qatarcentral" ;; + "SANO") LOCATION_IN_FILENAME="southafricanorth" ;; + "SAWE") LOCATION_IN_FILENAME="southafricawest" ;; + "SCUS") LOCATION_IN_FILENAME="southcentralus" ;; + "SCUG") LOCATION_IN_FILENAME="southcentralusstg" ;; + "SOEA") LOCATION_IN_FILENAME="southeastasia" ;; + "SOIN") LOCATION_IN_FILENAME="southindia" ;; + "SECE") LOCATION_IN_FILENAME="swedencentral" ;; + "SWNO") LOCATION_IN_FILENAME="switzerlandnorth" ;; + "SWWE") LOCATION_IN_FILENAME="switzerlandwest" ;; + "UACE") LOCATION_IN_FILENAME="uaecentral" ;; + "UANO") LOCATION_IN_FILENAME="uaenorth" ;; + "UKSO") LOCATION_IN_FILENAME="uksouth" ;; + "UKWE") LOCATION_IN_FILENAME="ukwest" ;; + "WCUS") LOCATION_IN_FILENAME="westcentralus" ;; + "WEEU") LOCATION_IN_FILENAME="westeurope" ;; + "WEIN") LOCATION_IN_FILENAME="westindia" ;; + "WEUS") LOCATION_IN_FILENAME="westus" ;; + "WUS2") LOCATION_IN_FILENAME="westus2" ;; + "WUS3") LOCATION_IN_FILENAME="westus3" ;; + *) LOCATION_IN_FILENAME="westeurope" ;; + esac + + NETWORK_IN_FILENAME=$(echo $(workload_zone_folder) | awk -F'-' '{print $3}' | xargs ) + + echo "Environment: $ENVIRONMENT" + echo "Location: $LOCATION" + echo "Network: $NETWORK" + + echo "Environment(filename): $ENVIRONMENT_IN_FILENAME" + echo "Location(filename): $LOCATION_IN_FILENAME" + echo "Network(filename): $NETWORK_IN_FILENAME" + + echo "Deployer Environment $(deployer_environment)" + echo "Deployer Region $(deployer_region)" + echo "Workload TFvars $(workload_zone_configuration_file)" + echo "" + + echo "Agent pool: $(this_agent)" + echo "Organization: $(System.CollectionUri)" + echo "Project: $(System.TeamProject)" + echo "" + echo "Azure CLI version:" + echo "-------------------------------------------------" + az --version + + if [ $ENVIRONMENT != $ENVIRONMENT_IN_FILENAME ]; then + echo "##vso[task.logissue type=error]The environment setting in $(workload_zone_configuration_file) '$ENVIRONMENT' does not match the $(workload_zone_configuration_file) file name '$ENVIRONMENT_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-INFRASTRUCTURE" + exit 2 + fi + + if [ $LOCATION != $LOCATION_IN_FILENAME ]; then + echo "##vso[task.logissue type=error]The location setting in $(workload_zone_configuration_file) '$LOCATION' does not match the $(workload_zone_configuration_file) file name '$LOCATION_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-INFRASTRUCTURE" + exit 2 + fi + + if [ $NETWORK != $NETWORK_IN_FILENAME ]; then + echo "##vso[task.logissue type=error]The network_logical_name setting in $(workload_zone_configuration_file) '$NETWORK' does not match the $(workload_zone_configuration_file) file name '$NETWORK_IN_FILENAME-. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-INFRASTRUCTURE" + exit 2 + fi + + echo -e "$green--- Configure devops CLI extension ---$reset" + az config set extension.use_dynamic_install=yes_without_prompt --output none + + az extension add --name azure-devops --output none --only-show-errors + + az devops configure --defaults organization=$(System.CollectionUri) project='$(System.TeamProject)' --output none + + export PARENT_VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(parent_variable_group)'].id | [0]") + + if [ -z ${PARENT_VARIABLE_GROUP_ID} ]; then + echo "##vso[task.logissue type=error]Variable group $(parent_variable_group) could not be found." + exit 2 + fi + + export VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(variable_group)'].id | [0]") + + if [ -z ${VARIABLE_GROUP_ID} ]; then + echo "##vso[task.logissue type=error]Variable group $(variable_group) could not be found." + exit 2 + fi + printf -v tempval '%s id:' $(variable_group) + printf -v val '%-20s' "${tempval}" + echo "$val $VARIABLE_GROUP_ID" + + printf -v tempval '%s id:' $(parent_variable_group) + printf -v val '%-20s' "${tempval}" + echo "$val $PARENT_VARIABLE_GROUP_ID" + + deployer_environment_file_name=$CONFIG_REPO_PATH/.sap_deployment_automation/$(deployer_environment)$(deployer_region) + echo "Deployer Environment File: $deployer_environment_file_name" + + workload_environment_file_name=$CONFIG_REPO_PATH/.sap_deployment_automation/${ENVIRONMENT}${LOCATION_CODE}${NETWORK} + echo "Workload Zone Environment File: $workload_environment_file_name" + + dos2unix -q ${deployer_environment_file_name} + dos2unix -q ${workload_environment_file_name} + + if [ ! -f ${deployer_environment_file_name} ]; then + echo -e "$boldred--- $(deployer_environment)$(deployer_region) was not found ---$reset" + echo "##vso[task.logissue type=error]Control plane configuration file $(deployer_environment)$(deployer_region) was not found." + exit 2 + fi + + echo -e "$green--- Read parameter values ---$reset" + + if [ "true" == $(inherit) ]; then + + az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Deployer_State_FileName.value" --out tsv) + if [ -z ${az_var} ]; then + deployer_tfstate_key=$(grep "^deployer_tfstate_key=" ${deployer_environment_file_name} | awk -F'=' '{print $2}' | xargs) + else + deployer_tfstate_key=${az_var} + fi + + az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Deployer_Key_Vault.value" --out tsv) + if [ -z ${az_var} ]; then + key_vault=$(grep "^keyvault=" ${deployer_environment_file_name} | awk -F'=' '{print $2}' | xargs) + else + key_vault=${az_var} + fi + + az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Account_Name.value" --out tsv) + if [ -z ${az_var} ]; then + REMOTE_STATE_SA=$(grep "^REMOTE_STATE_SA" ${deployer_environment_file_name} | awk -F'=' '{print $2}' | xargs) ; + else + REMOTE_STATE_SA=${az_var} + fi + + az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Subscription.value" --out tsv) + if [ -z ${az_var} ]; then + STATE_SUBSCRIPTION=$(grep "^STATE_SUBSCRIPTION" ${deployer_environment_file_name} | awk -F'=' '{print $2}' | xargs) + else + STATE_SUBSCRIPTION=${az_var} + + fi + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WL_ARM_SUBSCRIPTION_ID.value" --out tsv) + if [ -z ${az_var} ]; then + echo "##vso[task.logissue type=error]Variable WL_ARM_SUBSCRIPTION_ID was not defined." + exit 2 + fi + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Workload_Key_Vault.value" --out tsv) + if [ -z ${az_var} ]; then + if [ -f ${workload_environment_file_name} ]; then + export workload_key_vault=$(grep "^workloadkeyvault" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) + fi + else + export workload_key_vault=$(Workload_Key_Vault) + + fi + else + deployer_tfstate_key=$(grep "^deployer_tfstate_key=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) + + key_vault=$(grep -m1 "^workload_key_vault=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) ; + + REMOTE_STATE_SA=$(grep "^REMOTE_STATE_SA=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) + + STATE_SUBSCRIPTION=$(grep "^STATE_SUBSCRIPTION=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) + fi + + echo "Deployer statefile: $deployer_tfstate_key" + echo "Deployer Key vault: $key_vault" + echo "Workload Key vault: ${workload_key_vault}" + echo "Target subscription $WL_ARM_SUBSCRIPTION_ID" + + echo "Terraform state file subscription: $STATE_SUBSCRIPTION" + echo "Terraform state file storage account:$REMOTE_STATE_SA" + + secrets_set=1 + echo -e "$green---az login ---$reset" + + echo -e "$cyan---Sourcing the deploy_server.sh file$reset" + . /etc/profile.d/deploy_server.sh + + if [ $USE_MSI != "true" ]; then + + echo "Deployment credentials: Service Principal" + echo "Deployment credential ID (SPN): $WL_ARM_CLIENT_ID" + echo "Deployer subscription: $STATE_SUBSCRIPTION" + + export ARM_CLIENT_ID=$WL_ARM_CLIENT_ID + export ARM_CLIENT_SECRET=$WL_ARM_CLIENT_SECRET + export ARM_OBJECT_ID=$WL_ARM_OBJECT_ID + export ARM_TENANT_ID=$WL_ARM_TENANT_ID + export ARM_SUBSCRIPTION_ID=$WL_ARM_SUBSCRIPTION_ID + export ARM_USE_AZUREAD=true + unset ARM_USE_MSI + az login --service-principal --username $ARM_CLIENT_ID --password=$ARM_CLIENT_SECRET --tenant $ARM_TENANT_ID --output none + + return_code=$? + if [ 0 != $return_code ]; then + echo -e "$boldred--- Login failed ---$reset" + echo "##vso[task.logissue type=error]az login failed." + exit $return_code + fi + az account set --subscription $STATE_SUBSCRIPTION + echo -e "$green --- Set secrets ---$reset" + + $SAP_AUTOMATION_REPO_PATH/deploy/scripts/set_secrets.sh --workload --vault "${key_vault}" --environment "${ENVIRONMENT}" \ + --region "${LOCATION}" --subscription $ARM_SUBSCRIPTION_ID --spn_id $ARM_CLIENT_ID --spn_secret "${ARM_CLIENT_SECRET}" \ + --tenant_id $ARM_TENANT_ID --keyvault_subscription $STATE_SUBSCRIPTION + secrets_set=$? ; + echo "Set Secrets returned: $secrets_set" + + else + echo "Deployment credentials: Managed Identity" + # export ARM_SUBSCRIPTION_ID=$ARM_SUBSCRIPTION_ID + export ARM_USE_MSI=true + export ARM_USE_AZUREAD=true + unset ARM_CLIENT_SECRET + fi + + debug_variable='--output none' + debug_variable='' + + if [ $USE_MSI != "true" ]; then + + isUserAccessAdmin=$(az role assignment list --role "User Access Administrator" --subscription $STATE_SUBSCRIPTION --assignee $WL_ARM_OBJECT_ID --query "[].principalName | [0]" --output tsv) + + tfstate_resource_id=$(az resource list --name "${REMOTE_STATE_SA}" --subscription ${STATE_SUBSCRIPTION} --resource-type Microsoft.Storage/storageAccounts --query "[].id | [0]" -o tsv) + + if [ -n "${isUserAccessAdmin}" ]; then + + echo -e "$green--- Set permissions ---$reset" + perms=$(az role assignment list --subscription ${STATE_SUBSCRIPTION} --role "Reader" --assignee $WL_ARM_OBJECT_ID --query "[].principalName | [0]" --output tsv --only-show-errors) + if [ -z "$perms" ]; then + echo -e "$green --- Assign subscription permissions to $perms ---$reset" + az role assignment create --assignee $ARM_OBJECT_ID --role "Reader" --scope "/subscriptions/${STATE_SUBSCRIPTION}" --output none + fi + + perms=$(az role assignment list --subscription ${STATE_SUBSCRIPTION} --role "Storage Blob Data Contributor" --scope "${tfstate_resource_id}" --assignee $WL_ARM_OBJECT_ID --query "[].principalName | [0]" --only-show-errors) + if [ -z "$perms" ]; then + echo "Assigning Storage Account Contributor permissions for $ARM_OBJECT_ID to ${tfstate_resource_id}" + az role assignment create --assignee $ARM_OBJECT_ID --role "Storage Blob Data Contributor" --scope "${tfstate_resource_id}" --output none + fi + + resource_group_name=$(az resource show --id "${tfstate_resource_id}" --query resourceGroup -o tsv) + + if [ -n "${resource_group_name}" ]; then + for scope in $(az resource list --resource-group "${resource_group_name}" --subscription ${STATE_SUBSCRIPTION} --resource-type Microsoft.Network/privateDnsZones --query "[].id" --output tsv); do + perms=$(az role assignment list --subscription ${STATE_SUBSCRIPTION} --role "Private DNS Zone Contributor" --scope $scope --assignee $WL_ARM_OBJECT_ID --query "[].principalName | [0]" --output tsv --only-show-errors) + if [ -z "$perms" ]; then + echo "Assigning DNS Zone Contributor permissions for $WL_ARM_OBJECT_ID to ${scope}" + az role assignment create --assignee $ARM_OBJECT_ID --role "Private DNS Zone Contributor" --scope $scope --output none + fi + done + fi + + resource_group_name=$(az keyvault show --name "${key_vault}" --query resourceGroup --subscription ${STATE_SUBSCRIPTION} -o tsv) + + if [ -n "${resource_group_name}" ]; then + resource_group_id=$(az group show --name ${resource_group_name} --subscription ${STATE_SUBSCRIPTION} --query id -o tsv) + + vnet_resource_id=$(az resource list --resource-group "${resource_group_name}" --subscription ${STATE_SUBSCRIPTION} --resource-type Microsoft.Network/virtualNetworks -o tsv --query "[].id | [0]") + if [ -n "${vnet_resource_id}" ]; then + perms=$(az role assignment list --subscription ${STATE_SUBSCRIPTION} --role "Network Contributor" --scope $vnet_resource_id --query "[].principalName | [0]" --assignee $ARM_OBJECT_ID --output tsv --only-show-errors) + + if [ -z "$perms" ]; then + echo "Assigning Network Contributor rights for $ARM_OBJECT_ID to ${vnet_resource_id}" + az role assignment create --assignee $ARM_OBJECT_ID --role "Network Contributor" --scope $vnet_resource_id --output none + fi + fi + fi + else + echo "##vso[task.logissue type=warning]Service Principal $WL_ARM_CLIENT_ID does not have 'User Access Administrator' permissions. Please ensure that the service principal $WL_ARM_CLIENT_ID has permissions on the Terrafrom state storage account and if needed on the Private DNS zone and the source management network resource" + fi + fi + + echo -e "$green--- Deploy the workload zone ---$reset" + cd $CONFIG_REPO_PATH/LANDSCAPE/$(workload_zone_folder) + if [ -f /etc/profile.d/deploy_server.sh ]; then + if [ $USE_MSI != "true" ]; then + az logout --output none + export ARM_CLIENT_ID=$WL_ARM_CLIENT_ID + export ARM_CLIENT_SECRET=$WL_ARM_CLIENT_SECRET + export ARM_TENANT_ID=$WL_ARM_TENANT_ID + export ARM_SUBSCRIPTION_ID=$WL_ARM_SUBSCRIPTION_ID + unset ARM_USE_MSI + az login --service-principal --username $WL_ARM_CLIENT_ID --password=$WL_ARM_CLIENT_SECRET --tenant $WL_ARM_TENANT_ID --output none + return_code=$? + if [ 0 != $return_code ]; then + echo -e "$boldred--- Login failed ---$reset" + echo "##vso[task.logissue type=error]az login failed." + exit $return_code + fi + $SAP_AUTOMATION_REPO_PATH/deploy/scripts/install_workloadzone.sh --parameterfile $(workload_zone_configuration_file) \ + --deployer_environment $(deployer_environment) --subscription $ARM_SUBSCRIPTION_ID \ + --spn_id $WL_ARM_CLIENT_ID --spn_secret $WL_ARM_CLIENT_SECRET --tenant_id $WL_ARM_TENANT_ID \ + --deployer_tfstate_key "${deployer_tfstate_key}" --keyvault "${key_vault}" --storageaccountname "${REMOTE_STATE_SA}" \ + --state_subscription "${STATE_SUBSCRIPTION}" --auto-approve --ado + else + $SAP_AUTOMATION_REPO_PATH/deploy/scripts/install_workloadzone.sh --parameterfile $(workload_zone_configuration_file) \ + --deployer_environment $(deployer_environment) --subscription $ARM_SUBSCRIPTION_ID \ + --deployer_tfstate_key "${deployer_tfstate_key}" --keyvault "${key_vault}" --storageaccountname "${REMOTE_STATE_SA}" \ + --state_subscription "${STATE_SUBSCRIPTION}" --auto-approve --ado --msi + + fi + + fi + return_code=$? + + echo "Return code from deployment: ${return_code}" + + if [ -f ${workload_environment_file_name} ]; then + export workload_key_vault=$(cat ${workload_environment_file_name} | grep workloadkeyvault= | awk -F'=' '{print $2}' | xargs) + echo "Workload zone key vault: ${workload_key_vault}" + + export workload_prefix=$(cat ${workload_environment_file_name} | grep workload_zone_prefix= | awk -F'=' '{print $2}' | xargs) + echo "Workload zone prefix: ${workload_prefix}" + + export landscape_tfstate_key=$(cat ${workload_environment_file_name} | grep landscape_tfstate_key= | awk -F'=' '{print $2}' | xargs) + echo "Workload zone state file: ${landscape_tfstate_key}" + fi + + expiry_date=$(date -d "+365 days" +%Y-%m-%d) + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "FENCING_SPN_ID.value") + if [ -z ${az_var} ]; then + echo "##vso[task.logissue type=warning]Variable FENCING_SPN_ID is not set. Required for highly available deployments" + else + export fencing_id=$(az keyvault secret list --vault-name $workload_key_vault --subscription $STATE_SUBSCRIPTION --query [].name -o tsv | grep ${workload_prefix}-fencing-spn-id | xargs) + if [ -z "$fencing_id" ]; then + az keyvault secret set --name ${workload_prefix}-fencing-spn-id --vault-name $workload_key_vault --value $(FENCING_SPN_ID) --subscription $STATE_SUBSCRIPTION --expires "$(date -d '+1 year' -u +%Y-%m-%dT%H:%M:%SZ)" --output none + az keyvault secret set --name ${workload_prefix}-fencing-spn-pwd --vault-name $workload_key_vault --value=$FENCING_SPN_PWD --subscription $STATE_SUBSCRIPTION --expires "$(date -d '+1 year' -u +%Y-%m-%dT%H:%M:%SZ)" --output none + az keyvault secret set --name ${workload_prefix}-fencing-spn-tenant --vault-name $workload_key_vault --value $(FENCING_SPN_TENANT) --subscription $STATE_SUBSCRIPTION --expires "$(date -d '+1 year' -u +%Y-%m-%dT%H:%M:%SZ)" --output none + fi + fi + az logout --output none + echo -e "$green--- Add & update files in the DevOps Repository ---$reset" + cd $(Build.Repository.LocalPath) + git pull + + echo -e "$green--- Pull latest ---$reset" + cd $CONFIG_REPO_PATH + git pull + + added=0 + if [ -f ${workload_environment_file_name} ]; then + git add ${workload_environment_file_name} + added=1 + fi + if [ -f ${workload_environment_file_name}.md ]; then + git add ${workload_environment_file_name}.md + added=1 + fi + if [ -f $(Deployment_Configuration_Path)/LANDSCAPE/$(workload_zone_folder)/.terraform/terraform.tfstate ]; then + git add -f $(Deployment_Configuration_Path)/LANDSCAPE/$(workload_zone_folder)/.terraform/terraform.tfstate + added=1 + fi + if [ 1 == $added ]; then + git config --global user.email "$(Build.RequestedForEmail)" + git config --global user.name "$(Build.RequestedFor)" + git commit -m "Added updates from devops deployment $(Build.DefinitionName) [skip ci]" + git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" push --set-upstream origin $(Build.SourceBranchName) + fi + + if [ -f ${workload_environment_file_name}.md ]; then + echo "##vso[task.uploadsummary]${workload_environment_file_name}.md" + fi + echo -e "$green--- Adding variables to the variable group" $(variable_group) "---$reset" + if [ -n "${VARIABLE_GROUP_ID}" ]; then + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query Terraform_Remote_Storage_Account_Name.value --output table) + if [ -n "${az_var}" ]; then + az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name Terraform_Remote_Storage_Account_Name --value "${REMOTE_STATE_SA}" --output none --only-show-errors + else + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name Terraform_Remote_Storage_Account_Name --value "${REMOTE_STATE_SA}" --output none --only-show-errors + fi + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query Terraform_Remote_Storage_Subscription.value --output table) + if [ -n "${az_var}" ]; then + az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name Terraform_Remote_Storage_Subscription --value "${STATE_SUBSCRIPTION}" --output none --only-show-errors + else + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name Terraform_Remote_Storage_Subscription --value "${STATE_SUBSCRIPTION}" --output none --only-show-errors + fi + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query Deployer_State_FileName.value --output table) + if [ -n "${az_var}" ]; then + az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name Deployer_State_FileName --value "${deployer_tfstate_key}" --output none --only-show-errors + else + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name Deployer_State_FileName --value "${deployer_tfstate_key}" --output none --only-show-errors + fi + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query Deployer_Key_Vault.value --output table) + if [ -n "${az_var}" ]; then + az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name Deployer_Key_Vault --value ${key_vault} --output none --only-show-errors + else + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name Deployer_Key_Vault --value ${key_vault} --output none --only-show-errors + fi + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "${NETWORK}"Workload_Key_Vault.value --output table) + if [ -n "${az_var}" ]; then + az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name "${NETWORK}"Workload_Key_Vault --value $workload_key_vault --output none --only-show-errors + else + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name "${NETWORK}"Workload_Key_Vault --value $workload_key_vault --output none --only-show-errors + fi + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "${NETWORK}"Workload_Secret_Prefix.value --output table) + if [ -n "${az_var}" ]; then + az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name "${NETWORK}"Workload_Secret_Prefix --value "${workload_prefix}" --output none --only-show-errors + else + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name "${NETWORK}"Workload_Secret_Prefix --value "${workload_prefix}" --output none --only-show-errors + fi + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "${NETWORK}"Workload_Zone_State_FileName.value --output table) + if [ -n "${az_var}" ]; then + az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name "${NETWORK}"Workload_Zone_State_FileName --value "${landscape_tfstate_key}" --output none --only-show-errors + else + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name "${NETWORK}"Workload_Zone_State_FileName --value "${landscape_tfstate_key}" --output none --only-show-errors + fi + + fi + + if [ 0 != $return_code ]; then + echo "##vso[task.logissue type=error]Return code from install_workloadzone $return_code." + if [ -f ${workload_environment_file_name}.err ]; then + error_message=$(cat ${workload_environment_file_name}.err) + echo "##vso[task.logissue type=error]Error message: $error_message." + fi + + fi + + exit $return_code + + displayName: Deploy SAP Workload Zone + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + WL_ARM_SUBSCRIPTION_ID: $(ARM_SUBSCRIPTION_ID) + WL_ARM_TENANT_ID: $(ARM_TENANT_ID) + WL_ARM_CLIENT_ID: $(ARM_CLIENT_ID) + WL_ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET) + WL_ARM_OBJECT_ID: $(ARM_OBJECT_ID) + CP_ARM_SUBSCRIPTION_ID: $(CP_ARM_SUBSCRIPTION_ID) + CP_ARM_CLIENT_ID: $(CP_ARM_CLIENT_ID) + CP_ARM_CLIENT_SECRET: $(CP_ARM_CLIENT_SECRET) + CP_ARM_TENANT_ID: $(CP_ARM_TENANT_ID) + CP_ARM_OBJECT_ID: $(CP_ARM_OBJECT_ID) + FENCING_SPN_PWD: $(FENCING_SPN_PWD) + SAPBITS: $(INSTALLATION_MEDIA_ACCOUNT) + TEST_ONLY: ${{ parameters.test }} + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) + TF_LOG: $(TF_LOG) + TF_IN_AUTOMATION: true + SAP_AUTOMATION_REPO_PATH: ${{ parameters.sap_automation_repo_path }} + CONFIG_REPO_PATH: ${{ parameters.config_repo_path }}/$(Deployment_Configuration_Path) + LOGON_USING_SPN: $(Logon_Using_SPN) + USE_MSI: $(Use_MSI) + failOnStderr: false diff --git a/deploy/pipelines/03-sap-system-deployment.yaml b/deploy/pipelines/03-sap-system-deployment.yaml index c265b05ae8..3cd2d18c78 100644 --- a/deploy/pipelines/03-sap-system-deployment.yaml +++ b/deploy/pipelines/03-sap-system-deployment.yaml @@ -5,460 +5,460 @@ # +------------------------------------4--------------------------------------*/ parameters: - - name: sap_system - displayName: "SAP System configuration name, use the following syntax: ENV-LOCA-VNET-SID" - type: string - default: DEV-WEEU-SAP01-X00 +- name: sap_system + displayName: "SAP System configuration name, use the following syntax: ENV-LOCA-VNET-SID" + type: string + default: DEV-WEEU-SAP01-X00 - - name: environment - displayName: Workload Environment (DEV, QA, PRD, ...) - type: string - default: DEV +- name: environment + displayName: Workload Environment (DEV, QA, PRD, ...) + type: string + default: DEV - - name: sap_automation_repo_path - displayName: The local path on the agent where the sap_automation repo can be found - type: string +- name: sap_automation_repo_path + displayName: The local path on the agent where the sap_automation repo can be found + type: string - - name: config_repo_path - displayName: The local path on the agent where the config repo can be found - type: string +- name: config_repo_path + displayName: The local path on the agent where the config repo can be found + type: string - - name: test - displayName: Test deployment without applying the changes - type: boolean +- name: test + displayName: Test deployment without applying the changes + type: boolean stages: - - stage: Deploy_SAP_infrastructure - condition: and(not(failed()), not(canceled())) - variables: - - template: variables/03-sap-system-deployment-variables.yaml - parameters: - sap_system: ${{ parameters.sap_system }} - environment: ${{ parameters.environment }} - test: ${{ parameters.test }} - displayName: Deploy SAP infrastructure - jobs: - - job: Deploy_SAP_infrastructure - displayName: Deploy SAP infrastructure - workspace: - clean: all - steps: - - template: templates\download.yaml - - task: PostBuildCleanup@4 - - script: | - #!/bin/bash - echo "##vso[build.updatebuildnumber]Deploying the SAP System defined in $(sap_system_folder)" - green="\e[1;32m" ; reset="\e[0m" ; boldred="\e[1;31m" - - echo -e "$green--- Validations ---$reset" - - # Check if running on deployer - if [[ ! -f /etc/profile.d/deploy_server.sh ]]; then - echo -e "$green --- Install dos2unix ---$reset" - sudo apt-get -qq install dos2unix - - echo -e "$green --- Install terraform ---$reset" - - wget -q $(tf_url) - return_code=$? - if [ 0 != $return_code ]; then - echo "##vso[task.logissue type=error]Unable to download Terraform version $(tf_version)." - exit 2 - fi - unzip -qq terraform_$(tf_version)_linux_amd64.zip ; sudo mv terraform /bin/ - rm -f terraform_$(tf_version)_linux_amd64.zip - else - source /etc/profile.d/deploy_server.sh - fi - - HOME_CONFIG=${CONFIG_REPO_PATH}/$(Deployment_Configuration_Path) - cd $HOME_CONFIG; mkdir -p .sap_deployment_automation - if [ ! -f $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) ]; then - echo -e "$boldred--- $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) was not found ---$reset" - echo "##vso[task.logissue type=error]File $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) was not found." - exit 2 - fi - - if [ -z $WL_ARM_SUBSCRIPTION_ID ]; then - echo "##vso[task.logissue type=error]Variable ARM_SUBSCRIPTION_ID was not defined." - exit 2 - fi - echo "Before "USE_MSI" check" - if [ $USE_MSI != "true" ]; then - if [ -z $WL_ARM_CLIENT_ID ]; then - echo "##vso[task.logissue type=error]Variable ARM_CLIENT_ID was not defined." - exit 2 - fi - - if [ -z $WL_ARM_CLIENT_SECRET ]; then - echo "##vso[task.logissue type=error]Variable ARM_CLIENT_SECRET was not defined." - exit 2 - fi - - if [ -z $WL_ARM_TENANT_ID ]; then - echo "##vso[task.logissue type=error]Variable ARM_TENANT_ID was not defined." - exit 2 - fi - fi - - echo -e "$green--- Checkout $(Build.SourceBranchName) ---$reset" - cd $CONFIG_REPO_PATH - git checkout -q $(Build.SourceBranchName) - - echo -e "$green--- Convert config file to UX format ---$reset" - dos2unix -q $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) - echo -e "$green--- Read parameters ---$reset" - - ENVIRONMENT=$(grep "^environment" $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) | awk -F'=' '{print $2}' | xargs) - LOCATION=$(grep "^location" $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) | awk -F'=' '{print $2}' | xargs | tr 'A-Z' 'a-z') - NETWORK=$(grep "^network_logical_name" $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) | awk -F'=' '{print $2}' | xargs) - SID=$(grep "^sid" $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) | awk -F'=' '{print $2}' | xargs) - - echo "Environment: $ENVIRONMENT" - echo "Location: $LOCATION" - echo "Network: $NETWORK" - echo "SID: $SID" - echo "System TFvars: $(sap_system_configuration)" - - ENVIRONMENT_IN_FILENAME=$(echo $(sap_system_folder) | awk -F'-' '{print $1}' | xargs) ; - LOCATION_CODE=$(echo $(sap_system_folder) | awk -F'-' '{print $2}' | xargs) ; - NETWORK_IN_FILENAME=$(echo $(sap_system_folder) | awk -F'-' '{print $3}' | xargs) ; - SID_IN_FILENAME=$(echo $(sap_system_folder) | awk -F'-' '{print $4}' | xargs) ; - case "$LOCATION_CODE" in - "AUCE") LOCATION_IN_FILENAME="australiacentral" ;; - "AUC2") LOCATION_IN_FILENAME="australiacentral2" ;; - "AUEA") LOCATION_IN_FILENAME="australiaeast" ;; - "AUSE") LOCATION_IN_FILENAME="australiasoutheast" ;; - "BRSO") LOCATION_IN_FILENAME="brazilsouth" ;; - "BRSE") LOCATION_IN_FILENAME="brazilsoutheast" ;; - "BRUS") LOCATION_IN_FILENAME="brazilus" ;; - "CACE") LOCATION_IN_FILENAME="canadacentral" ;; - "CAEA") LOCATION_IN_FILENAME="canadaeast" ;; - "CEIN") LOCATION_IN_FILENAME="centralindia" ;; - "CEUS") LOCATION_IN_FILENAME="centralus" ;; - "CEUA") LOCATION_IN_FILENAME="centraluseuap" ;; - "EAAS") LOCATION_IN_FILENAME="eastasia" ;; - "EAUS") LOCATION_IN_FILENAME="eastus" ;; - "EUSA") LOCATION_IN_FILENAME="eastus2euap" ;; - "EUS2") LOCATION_IN_FILENAME="eastus2" ;; - "EUSG") LOCATION_IN_FILENAME="eastusstg" ;; - "FRCE") LOCATION_IN_FILENAME="francecentral" ;; - "FRSO") LOCATION_IN_FILENAME="francesouth" ;; - "GENO") LOCATION_IN_FILENAME="germanynorth" ;; - "GEWE") LOCATION_IN_FILENAME="germanywest" ;; - "GEWC") LOCATION_IN_FILENAME="germanywestcentral" ;; - "ISCE") LOCATION_IN_FILENAME="israelcentral" ;; - "ITNO") LOCATION_IN_FILENAME="italynorth" ;; - "JAEA") LOCATION_IN_FILENAME="japaneast" ;; - "JAWE") LOCATION_IN_FILENAME="japanwest" ;; - "JINC") LOCATION_IN_FILENAME="jioindiacentral" ;; - "JINW") LOCATION_IN_FILENAME="jioindiawest" ;; - "KOCE") LOCATION_IN_FILENAME="koreacentral" ;; - "KOSO") LOCATION_IN_FILENAME="koreasouth" ;; - "NCUS") LOCATION_IN_FILENAME="northcentralus" ;; - "NOEU") LOCATION_IN_FILENAME="northeurope" ;; - "NOEA") LOCATION_IN_FILENAME="norwayeast" ;; - "NOWE") LOCATION_IN_FILENAME="norwaywest" ;; - "PLCE") LOCATION_IN_FILENAME="polandcentral" ;; - "QACE") LOCATION_IN_FILENAME="qatarcentral" ;; - "SANO") LOCATION_IN_FILENAME="southafricanorth" ;; - "SAWE") LOCATION_IN_FILENAME="southafricawest" ;; - "SCUS") LOCATION_IN_FILENAME="southcentralus" ;; - "SCUG") LOCATION_IN_FILENAME="southcentralusstg" ;; - "SOEA") LOCATION_IN_FILENAME="southeastasia" ;; - "SOIN") LOCATION_IN_FILENAME="southindia" ;; - "SECE") LOCATION_IN_FILENAME="swedencentral" ;; - "SWNO") LOCATION_IN_FILENAME="switzerlandnorth" ;; - "SWWE") LOCATION_IN_FILENAME="switzerlandwest" ;; - "UACE") LOCATION_IN_FILENAME="uaecentral" ;; - "UANO") LOCATION_IN_FILENAME="uaenorth" ;; - "UKSO") LOCATION_IN_FILENAME="uksouth" ;; - "UKWE") LOCATION_IN_FILENAME="ukwest" ;; - "WCUS") LOCATION_IN_FILENAME="westcentralus" ;; - "WEEU") LOCATION_IN_FILENAME="westeurope" ;; - "WEIN") LOCATION_IN_FILENAME="westindia" ;; - "WEUS") LOCATION_IN_FILENAME="westus" ;; - "WUS2") LOCATION_IN_FILENAME="westus2" ;; - "WUS3") LOCATION_IN_FILENAME="westus3" ;; - *) LOCATION_IN_FILENAME="westeurope" ;; - esac - - echo "Environment(filename): $ENVIRONMENT_IN_FILENAME" - echo "Location(filename): $LOCATION_IN_FILENAME" - echo "Network(filename): $NETWORK_IN_FILENAME" - echo "SID(filename): $SID_IN_FILENAME" - - echo "" - echo "Agent: $(this_agent)" - echo "Organization: $(System.CollectionUri)" - echo "Project: $(System.TeamProject)" - echo "" - echo "Azure CLI version:" - echo "-------------------------------------------------" - az --version - - - if [ $ENVIRONMENT != $ENVIRONMENT_IN_FILENAME ]; then - echo "##vso[task.logissue type=error]The environment setting in $(sap_system_configuration) '$ENVIRONMENT' does not match the $(sap_system_configuration) file name '$ENVIRONMENT_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-[SID]" - exit 2 - fi - - if [ $LOCATION != $LOCATION_IN_FILENAME ]; then - echo "##vso[task.logissue type=error]The location setting in $(sap_system_configuration) '$LOCATION' does not match the $(sap_system_configuration) file name '$LOCATION_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-[SID]" - exit 2 - fi - - if [ $NETWORK != $NETWORK_IN_FILENAME ]; then - echo "##vso[task.logissue type=error]The network_logical_name setting in $(sap_system_configuration) '$NETWORK' does not match the $(sap_system_configuration) file name '$NETWORK_IN_FILENAME-. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-[SID]" - exit 2 - fi - - if [ $SID != $SID_IN_FILENAME ]; then - echo "##vso[task.logissue type=error]The sid setting in $(sap_system_configuration) '$SID' does not match the $(sap_system_configuration) file name '$SID_IN_FILENAME-. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-[SID]" - exit 2 - fi - - echo -e "$green--- Set CONFIG_REPO_PATH variable and ---$reset" - - environment_file_name=$HOME_CONFIG/.sap_deployment_automation/${ENVIRONMENT}${LOCATION_CODE}${NETWORK} - if [ ! -f $environment_file_name ]; then - echo -e "$boldred--- $environment_file_name was not found ---$reset" - echo "##vso[task.logissue type=error]Please rerun the workload zone deployment. Workload zone configuration file $environment_file_name was not found." - exit 2 - fi - - if [ -z ${SID} ]; then - echo "##vso[task.logissue type=error]SID was not defined in the parameter file." - exit 2 - fi - echo -e "$green--- Configure devops CLI extension ---$reset" - - az config set extension.use_dynamic_install=yes_without_prompt --output none --only-show-errors - - az extension add --name azure-devops --output none --only-show-errors - - az devops configure --defaults organization=$(System.CollectionUri) project='$(System.TeamProject)' --output none --only-show-errors - - export VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(variable_group)'].id | [0]") - - if [ -z ${VARIABLE_GROUP_ID} ]; then - echo "##vso[task.logissue type=error]Variable group $(variable_group) could not be found." - exit 2 - fi - printf -v val '%-15s' "$(variable_group) id:" - echo "$val $VARIABLE_GROUP_ID" - echo -e "$green--- Login ---$reset" - - if [ -z $USE_MSI ]; then - USE_MSI="false" - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query USE_MSI.value --output table) - if [ -n "${az_var}" ]; then - az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name USE_MSI --value false --output none --only-show-errors - else - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name USE_MSI --value false --output none --only-show-errors - fi - fi - - echo -e "$cyan---Sourcing the deploy_server.sh file$reset" - . /etc/profile.d/deploy_server.sh - export ARM_SUBSCRIPTION_ID=$WL_ARM_SUBSCRIPTION_ID - if [ $USE_MSI != "true" ]; then - - echo "Deployment credentials: Service Principal" - echo "Deployment credential ID (SPN): $WL_ARM_CLIENT_ID" - echo "Deployer subscription: $STATE_SUBSCRIPTION" - - export ARM_CLIENT_ID=$WL_ARM_CLIENT_ID - export ARM_CLIENT_SECRET=$WL_ARM_CLIENT_SECRET - export ARM_OBJECT_ID=$WL_ARM_OBJECT_ID - export ARM_TENANT_ID=$WL_ARM_TENANT_ID - export ARM_SUBSCRIPTION_ID=$WL_ARM_SUBSCRIPTION_ID - export ARM_USE_AZUREAD=true - unset ARM_USE_MSI - az login --service-principal --username $ARM_CLIENT_ID --password=$ARM_CLIENT_SECRET --tenant $ARM_TENANT_ID --output none - - return_code=$? - if [ 0 != $return_code ]; then - echo -e "$boldred--- Login failed ---$reset" - echo "##vso[task.logissue type=error]az login failed." - exit $return_code - fi - az account set --subscription $STATE_SUBSCRIPTION - echo -e "$green --- Set secrets ---$reset" - - $SAP_AUTOMATION_REPO_PATH/deploy/scripts/set_secrets.sh --workload --vault "${key_vault}" --environment "${ENVIRONMENT}" \ - --region "${LOCATION}" --subscription $ARM_SUBSCRIPTION_ID --spn_id $ARM_CLIENT_ID --spn_secret "${ARM_CLIENT_SECRET}" \ - --tenant_id $ARM_TENANT_ID --keyvault_subscription $STATE_SUBSCRIPTION - secrets_set=$? ; - echo "Set Secrets returned: $secrets_set" - - else - echo "Deployment credentials: Managed Identity" - export ARM_USE_MSI=true - export ARM_USE_AZUREAD=true - unset ARM_CLIENT_SECRET - fi - - echo -e "$green--- Define variables ---$reset" - cd $HOME_CONFIG/SYSTEM/$(sap_system_folder) - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Subscription.value" --out tsv) - if [ -z ${az_var} ]; then - export STATE_SUBSCRIPTION=$(grep STATE_SUBSCRIPTION ${environment_file_name} | awk -F'=' '{print $2}' | xargs) - else - export STATE_SUBSCRIPTION=${az_var} - fi - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Account_Name.value" --out tsv) - if [ -z ${az_var} ]; then - export REMOTE_STATE_SA=$(grep REMOTE_STATE_SA ${environment_file_name} | awk -F'=' '{print $2}' | xargs) - else - export REMOTE_STATE_SA=${az_var} - fi - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Deployer_State_FileName.value" --out tsv) - if [ -z ${az_var} ]; then - export deployer_tfstate_key=$(grep deployer_tfstate_key ${environment_file_name} | awk -F'=' '{print $2}' | xargs) - else - export deployer_tfstate_key=${az_var} - fi - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "${NETWORK}"Workload_Zone_State_FileName.value | tr -d \") - if [ -z ${az_var} ]; then - export landscape_tfstate_key=$(grep landscape_tfstate_key= ${environment_file_name} | awk -F'=' '{print $2}' | xargs) - else - export landscape_tfstate_key=${az_var} - fi - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Deployer_Key_Vault.value" --out tsv) - if [ -z ${az_var} ]; then - export key_vault=$(grep keyvault= ${environment_file_name} | awk -F'=' '{print $2}' | xargs) - else - export key_vault=${az_var} - fi - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "${NETWORK}"Workload_Key_Vault.value | tr -d \") - if [ -z ${az_var} ]; then - export workload_key_vault=$(grep workloadkeyvault= ${environment_file_name} | awk -F'=' '{print $2}' | xargs) - else - export workload_key_vault=${az_var} - fi - - echo "Deployer state file: $deployer_tfstate_key" - echo "Deployer Key Vault: $key_vault" - echo "Workload Zone state file: $landscape_tfstate_key" - echo "Workload Zone Key Vault: $workload_key_vault" - - echo -e "$green--- Run the installer script that deploys the SAP System ---$reset" - - $SAP_AUTOMATION_REPO_PATH/deploy/scripts/installer.sh --parameterfile $(sap_system_configuration) --type sap_system \ - --state_subscription ${STATE_SUBSCRIPTION} --storageaccountname ${REMOTE_STATE_SA} \ - --deployer_tfstate_key ${deployer_tfstate_key} --landscape_tfstate_key ${landscape_tfstate_key} \ - --ado --auto-approve - - return_code=$? - if [ 0 != $return_code ]; then - echo "##vso[task.logissue type=error]Return code from installer $return_code." - if [ -f ${environment_file_name}.err ]; then - error_message=$(cat ${environment_file_name}.err) - echo "##vso[task.logissue type=error]Error message: $error_message." - fi - fi - # Pull changes if there are other deployment jobs - - cd $HOME_CONFIG/SYSTEM/$(sap_system_folder) - - echo -e "$green--- Pull the latest content from DevOps ---$reset" - git pull - echo -e "$green--- Add & update files in the DevOps Repository ---$reset" - - added=0 - - if [ -f $.terraform/terraform.tfstate ]; then - git add -f .terraform/terraform.tfstate - added=1 - fi - - if [ -f sap-parameters.yaml ]; then - git add sap-parameters.yaml - added=1 - fi - - if [ -f ${SID}_hosts.yaml ]; then - git add -f ${SID}_hosts.yaml - added=1 - fi - - if [ -f ${SID}.md ]; then - git add ${SID}.md - added=1 - fi - - if [ -f ${SID}_inventory.md ]; then - git add ${SID}_inventory.md - added=1 - fi - - if [ -f ${SID}_resource_names.json ]; then - git add ${SID}_resource_names.json - added=1 - fi - - if [ -f $(sap_system_configuration) ]; then - git add $(sap_system_configuration) - added=1 - fi - - if [ -f ${SID}_virtual_machines.json ]; then - git add ${SID}_virtual_machines.json - added=1 - fi - - if [ 1 == $added ]; then - git config --global user.email "$(Build.RequestedForEmail)" - git config --global user.name "$(Build.RequestedFor)" - git commit -m "Added updates from devops system deployment $(Build.DefinitionName) [skip ci]" - - git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" push --set-upstream origin $(Build.SourceBranchName) - fi - - if [ -f ${SID}.md ]; then - echo "##vso[task.uploadsummary]$HOME_CONFIG/SYSTEM/$(sap_system_folder)/${SID}.md" - fi - - # file_name=${SID}_inventory.md - # if [ -f ${SID}_inventory.md ]; then - # az devops configure --defaults organization=$(System.CollectionUri) project='$(System.TeamProject)' --output none - - # # ToDo: Fix this later - # # WIKI_NAME_FOUND=$(az devops wiki list --query "[?name=='SDAF'].name | [0]") - # # echo "${WIKI_NAME_FOUND}" - # # if [ -n "${WIKI_NAME_FOUND}" ]; then - # # eTag=$(az devops wiki page show --path "${file_name}" --wiki SDAF --query eTag ) - # # if [ -n "$eTag" ]; then - # # az devops wiki page update --path "${file_name}" --wiki SDAF --file-path ./"${file_name}" --only-show-errors --version $eTag --output none - # # else - # # az devops wiki page create --path "${file_name}" --wiki SDAF --file-path ./"${file_name}" --output none --only-show-errors - # # fi - # # fi - # fi - - exit $return_code - - displayName: Deploy_SAP_infrastructure - env: - CONFIG_REPO_PATH: ${{ parameters.config_repo_path }} - LOGON_USING_SPN: $(Logon_Using_SPN) - AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) - SAP_AUTOMATION_REPO_PATH: ${{ parameters.sap_automation_repo_path }} - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - TEST_ONLY: ${{ parameters.test }} - TF_IN_AUTOMATION: true - TF_LOG: $(TF_LOG) - USE_MSI: $(Use_MSI) - WL_ARM_CLIENT_ID: $(ARM_CLIENT_ID) - WL_ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET) - WL_ARM_SUBSCRIPTION_ID: $(ARM_SUBSCRIPTION_ID) - WL_ARM_TENANT_ID: $(ARM_TENANT_ID) - - failOnStderr: false +- stage: Deploy_SAP_infrastructure + condition: and(not(failed()), not(canceled())) + variables: + - template: variables/03-sap-system-deployment-variables.yaml + parameters: + sap_system: ${{ parameters.sap_system }} + environment: ${{ parameters.environment }} + test: ${{ parameters.test }} + displayName: Deploy SAP infrastructure + jobs: + - job: Deploy_SAP_infrastructure + displayName: Deploy SAP infrastructure + workspace: + clean: all + steps: + - template: templates\download.yaml + - task: PostBuildCleanup@4 + - script: | + #!/bin/bash + echo "##vso[build.updatebuildnumber]Deploying the SAP System defined in $(sap_system_folder)" + green="\e[1;32m" ; reset="\e[0m" ; boldred="\e[1;31m" + + echo -e "$green--- Validations ---$reset" + + # Check if running on deployer + if [[ ! -f /etc/profile.d/deploy_server.sh ]]; then + echo -e "$green --- Install dos2unix ---$reset" + sudo apt-get -qq install dos2unix + + echo -e "$green --- Install terraform ---$reset" + + wget -q $(tf_url) + return_code=$? + if [ 0 != $return_code ]; then + echo "##vso[task.logissue type=error]Unable to download Terraform version $(tf_version)." + exit 2 + fi + unzip -qq terraform_$(tf_version)_linux_amd64.zip ; sudo mv terraform /bin/ + rm -f terraform_$(tf_version)_linux_amd64.zip + else + source /etc/profile.d/deploy_server.sh + fi + + HOME_CONFIG=${CONFIG_REPO_PATH}/$(Deployment_Configuration_Path) + cd $HOME_CONFIG; mkdir -p .sap_deployment_automation + if [ ! -f $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) ]; then + echo -e "$boldred--- $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) was not found ---$reset" + echo "##vso[task.logissue type=error]File $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) was not found." + exit 2 + fi + + if [ -z $WL_ARM_SUBSCRIPTION_ID ]; then + echo "##vso[task.logissue type=error]Variable ARM_SUBSCRIPTION_ID was not defined." + exit 2 + fi + echo "Before "USE_MSI" check" + if [ $USE_MSI != "true" ]; then + if [ -z $WL_ARM_CLIENT_ID ]; then + echo "##vso[task.logissue type=error]Variable ARM_CLIENT_ID was not defined." + exit 2 + fi + + if [ -z $WL_ARM_CLIENT_SECRET ]; then + echo "##vso[task.logissue type=error]Variable ARM_CLIENT_SECRET was not defined." + exit 2 + fi + + if [ -z $WL_ARM_TENANT_ID ]; then + echo "##vso[task.logissue type=error]Variable ARM_TENANT_ID was not defined." + exit 2 + fi + fi + + echo -e "$green--- Checkout $(Build.SourceBranchName) ---$reset" + cd $CONFIG_REPO_PATH + git checkout -q $(Build.SourceBranchName) + + echo -e "$green--- Convert config file to UX format ---$reset" + dos2unix -q $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) + echo -e "$green--- Read parameters ---$reset" + + ENVIRONMENT=$(grep "^environment" $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) | awk -F'=' '{print $2}' | xargs) + LOCATION=$(grep "^location" $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) | awk -F'=' '{print $2}' | xargs | tr 'A-Z' 'a-z') + NETWORK=$(grep "^network_logical_name" $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) | awk -F'=' '{print $2}' | xargs) + SID=$(grep "^sid" $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) | awk -F'=' '{print $2}' | xargs) + + echo "Environment: $ENVIRONMENT" + echo "Location: $LOCATION" + echo "Network: $NETWORK" + echo "SID: $SID" + echo "System TFvars: $(sap_system_configuration)" + + ENVIRONMENT_IN_FILENAME=$(echo $(sap_system_folder) | awk -F'-' '{print $1}' | xargs) ; + LOCATION_CODE=$(echo $(sap_system_folder) | awk -F'-' '{print $2}' | xargs) ; + NETWORK_IN_FILENAME=$(echo $(sap_system_folder) | awk -F'-' '{print $3}' | xargs) ; + SID_IN_FILENAME=$(echo $(sap_system_folder) | awk -F'-' '{print $4}' | xargs) ; + case "$LOCATION_CODE" in + "AUCE") LOCATION_IN_FILENAME="australiacentral" ;; + "AUC2") LOCATION_IN_FILENAME="australiacentral2" ;; + "AUEA") LOCATION_IN_FILENAME="australiaeast" ;; + "AUSE") LOCATION_IN_FILENAME="australiasoutheast" ;; + "BRSO") LOCATION_IN_FILENAME="brazilsouth" ;; + "BRSE") LOCATION_IN_FILENAME="brazilsoutheast" ;; + "BRUS") LOCATION_IN_FILENAME="brazilus" ;; + "CACE") LOCATION_IN_FILENAME="canadacentral" ;; + "CAEA") LOCATION_IN_FILENAME="canadaeast" ;; + "CEIN") LOCATION_IN_FILENAME="centralindia" ;; + "CEUS") LOCATION_IN_FILENAME="centralus" ;; + "CEUA") LOCATION_IN_FILENAME="centraluseuap" ;; + "EAAS") LOCATION_IN_FILENAME="eastasia" ;; + "EAUS") LOCATION_IN_FILENAME="eastus" ;; + "EUSA") LOCATION_IN_FILENAME="eastus2euap" ;; + "EUS2") LOCATION_IN_FILENAME="eastus2" ;; + "EUSG") LOCATION_IN_FILENAME="eastusstg" ;; + "FRCE") LOCATION_IN_FILENAME="francecentral" ;; + "FRSO") LOCATION_IN_FILENAME="francesouth" ;; + "GENO") LOCATION_IN_FILENAME="germanynorth" ;; + "GEWE") LOCATION_IN_FILENAME="germanywest" ;; + "GEWC") LOCATION_IN_FILENAME="germanywestcentral" ;; + "ISCE") LOCATION_IN_FILENAME="israelcentral" ;; + "ITNO") LOCATION_IN_FILENAME="italynorth" ;; + "JAEA") LOCATION_IN_FILENAME="japaneast" ;; + "JAWE") LOCATION_IN_FILENAME="japanwest" ;; + "JINC") LOCATION_IN_FILENAME="jioindiacentral" ;; + "JINW") LOCATION_IN_FILENAME="jioindiawest" ;; + "KOCE") LOCATION_IN_FILENAME="koreacentral" ;; + "KOSO") LOCATION_IN_FILENAME="koreasouth" ;; + "NCUS") LOCATION_IN_FILENAME="northcentralus" ;; + "NOEU") LOCATION_IN_FILENAME="northeurope" ;; + "NOEA") LOCATION_IN_FILENAME="norwayeast" ;; + "NOWE") LOCATION_IN_FILENAME="norwaywest" ;; + "PLCE") LOCATION_IN_FILENAME="polandcentral" ;; + "QACE") LOCATION_IN_FILENAME="qatarcentral" ;; + "SANO") LOCATION_IN_FILENAME="southafricanorth" ;; + "SAWE") LOCATION_IN_FILENAME="southafricawest" ;; + "SCUS") LOCATION_IN_FILENAME="southcentralus" ;; + "SCUG") LOCATION_IN_FILENAME="southcentralusstg" ;; + "SOEA") LOCATION_IN_FILENAME="southeastasia" ;; + "SOIN") LOCATION_IN_FILENAME="southindia" ;; + "SECE") LOCATION_IN_FILENAME="swedencentral" ;; + "SWNO") LOCATION_IN_FILENAME="switzerlandnorth" ;; + "SWWE") LOCATION_IN_FILENAME="switzerlandwest" ;; + "UACE") LOCATION_IN_FILENAME="uaecentral" ;; + "UANO") LOCATION_IN_FILENAME="uaenorth" ;; + "UKSO") LOCATION_IN_FILENAME="uksouth" ;; + "UKWE") LOCATION_IN_FILENAME="ukwest" ;; + "WCUS") LOCATION_IN_FILENAME="westcentralus" ;; + "WEEU") LOCATION_IN_FILENAME="westeurope" ;; + "WEIN") LOCATION_IN_FILENAME="westindia" ;; + "WEUS") LOCATION_IN_FILENAME="westus" ;; + "WUS2") LOCATION_IN_FILENAME="westus2" ;; + "WUS3") LOCATION_IN_FILENAME="westus3" ;; + *) LOCATION_IN_FILENAME="westeurope" ;; + esac + + echo "Environment(filename): $ENVIRONMENT_IN_FILENAME" + echo "Location(filename): $LOCATION_IN_FILENAME" + echo "Network(filename): $NETWORK_IN_FILENAME" + echo "SID(filename): $SID_IN_FILENAME" + + echo "" + echo "Agent: $(this_agent)" + echo "Organization: $(System.CollectionUri)" + echo "Project: $(System.TeamProject)" + echo "" + echo "Azure CLI version:" + echo "-------------------------------------------------" + az --version + + + if [ $ENVIRONMENT != $ENVIRONMENT_IN_FILENAME ]; then + echo "##vso[task.logissue type=error]The environment setting in $(sap_system_configuration) '$ENVIRONMENT' does not match the $(sap_system_configuration) file name '$ENVIRONMENT_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-[SID]" + exit 2 + fi + + if [ $LOCATION != $LOCATION_IN_FILENAME ]; then + echo "##vso[task.logissue type=error]The location setting in $(sap_system_configuration) '$LOCATION' does not match the $(sap_system_configuration) file name '$LOCATION_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-[SID]" + exit 2 + fi + + if [ $NETWORK != $NETWORK_IN_FILENAME ]; then + echo "##vso[task.logissue type=error]The network_logical_name setting in $(sap_system_configuration) '$NETWORK' does not match the $(sap_system_configuration) file name '$NETWORK_IN_FILENAME-. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-[SID]" + exit 2 + fi + + if [ $SID != $SID_IN_FILENAME ]; then + echo "##vso[task.logissue type=error]The sid setting in $(sap_system_configuration) '$SID' does not match the $(sap_system_configuration) file name '$SID_IN_FILENAME-. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-[SID]" + exit 2 + fi + + echo -e "$green--- Set CONFIG_REPO_PATH variable and ---$reset" + + environment_file_name=$HOME_CONFIG/.sap_deployment_automation/${ENVIRONMENT}${LOCATION_CODE}${NETWORK} + if [ ! -f $environment_file_name ]; then + echo -e "$boldred--- $environment_file_name was not found ---$reset" + echo "##vso[task.logissue type=error]Please rerun the workload zone deployment. Workload zone configuration file $environment_file_name was not found." + exit 2 + fi + + if [ -z ${SID} ]; then + echo "##vso[task.logissue type=error]SID was not defined in the parameter file." + exit 2 + fi + echo -e "$green--- Configure devops CLI extension ---$reset" + + az config set extension.use_dynamic_install=yes_without_prompt --output none --only-show-errors + + az extension add --name azure-devops --output none --only-show-errors + + az devops configure --defaults organization=$(System.CollectionUri) project='$(System.TeamProject)' --output none --only-show-errors + + export VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(variable_group)'].id | [0]") + + if [ -z ${VARIABLE_GROUP_ID} ]; then + echo "##vso[task.logissue type=error]Variable group $(variable_group) could not be found." + exit 2 + fi + printf -v val '%-15s' "$(variable_group) id:" + echo "$val $VARIABLE_GROUP_ID" + echo -e "$green--- Login ---$reset" + + if [ -z $USE_MSI ]; then + USE_MSI="false" + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query USE_MSI.value --output table) + if [ -n "${az_var}" ]; then + az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name USE_MSI --value false --output none --only-show-errors + else + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name USE_MSI --value false --output none --only-show-errors + fi + fi + + echo -e "$cyan---Sourcing the deploy_server.sh file$reset" + . /etc/profile.d/deploy_server.sh + export ARM_SUBSCRIPTION_ID=$WL_ARM_SUBSCRIPTION_ID + if [ $USE_MSI != "true" ]; then + + echo "Deployment credentials: Service Principal" + echo "Deployment credential ID (SPN): $WL_ARM_CLIENT_ID" + echo "Deployer subscription: $STATE_SUBSCRIPTION" + + export ARM_CLIENT_ID=$WL_ARM_CLIENT_ID + export ARM_CLIENT_SECRET=$WL_ARM_CLIENT_SECRET + export ARM_OBJECT_ID=$WL_ARM_OBJECT_ID + export ARM_TENANT_ID=$WL_ARM_TENANT_ID + export ARM_SUBSCRIPTION_ID=$WL_ARM_SUBSCRIPTION_ID + export ARM_USE_AZUREAD=true + unset ARM_USE_MSI + az login --service-principal --username $ARM_CLIENT_ID --password=$ARM_CLIENT_SECRET --tenant $ARM_TENANT_ID --output none + + return_code=$? + if [ 0 != $return_code ]; then + echo -e "$boldred--- Login failed ---$reset" + echo "##vso[task.logissue type=error]az login failed." + exit $return_code + fi + az account set --subscription $STATE_SUBSCRIPTION + echo -e "$green --- Set secrets ---$reset" + + $SAP_AUTOMATION_REPO_PATH/deploy/scripts/set_secrets.sh --workload --vault "${key_vault}" --environment "${ENVIRONMENT}" \ + --region "${LOCATION}" --subscription $ARM_SUBSCRIPTION_ID --spn_id $ARM_CLIENT_ID --spn_secret "${ARM_CLIENT_SECRET}" \ + --tenant_id $ARM_TENANT_ID --keyvault_subscription $STATE_SUBSCRIPTION + secrets_set=$? ; + echo "Set Secrets returned: $secrets_set" + + else + echo "Deployment credentials: Managed Identity" + export ARM_USE_MSI=true + export ARM_USE_AZUREAD=true + unset ARM_CLIENT_SECRET + fi + + echo -e "$green--- Define variables ---$reset" + cd $HOME_CONFIG/SYSTEM/$(sap_system_folder) + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Subscription.value" --out tsv) + if [ -z ${az_var} ]; then + export STATE_SUBSCRIPTION=$(grep STATE_SUBSCRIPTION ${environment_file_name} | awk -F'=' '{print $2}' | xargs) + else + export STATE_SUBSCRIPTION=${az_var} + fi + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Account_Name.value" --out tsv) + if [ -z ${az_var} ]; then + export REMOTE_STATE_SA=$(grep REMOTE_STATE_SA ${environment_file_name} | awk -F'=' '{print $2}' | xargs) + else + export REMOTE_STATE_SA=${az_var} + fi + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Deployer_State_FileName.value" --out tsv) + if [ -z ${az_var} ]; then + export deployer_tfstate_key=$(grep deployer_tfstate_key ${environment_file_name} | awk -F'=' '{print $2}' | xargs) + else + export deployer_tfstate_key=${az_var} + fi + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "${NETWORK}"Workload_Zone_State_FileName.value | tr -d \") + if [ -z ${az_var} ]; then + export landscape_tfstate_key=$(grep landscape_tfstate_key= ${environment_file_name} | awk -F'=' '{print $2}' | xargs) + else + export landscape_tfstate_key=${az_var} + fi + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Deployer_Key_Vault.value" --out tsv) + if [ -z ${az_var} ]; then + export key_vault=$(grep keyvault= ${environment_file_name} | awk -F'=' '{print $2}' | xargs) + else + export key_vault=${az_var} + fi + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "${NETWORK}"Workload_Key_Vault.value | tr -d \") + if [ -z ${az_var} ]; then + export workload_key_vault=$(grep workloadkeyvault= ${environment_file_name} | awk -F'=' '{print $2}' | xargs) + else + export workload_key_vault=${az_var} + fi + + echo "Deployer state file: $deployer_tfstate_key" + echo "Deployer Key Vault: $key_vault" + echo "Workload Zone state file: $landscape_tfstate_key" + echo "Workload Zone Key Vault: $workload_key_vault" + + echo -e "$green--- Run the installer script that deploys the SAP System ---$reset" + + $SAP_AUTOMATION_REPO_PATH/deploy/scripts/installer.sh --parameterfile $(sap_system_configuration) --type sap_system \ + --state_subscription ${STATE_SUBSCRIPTION} --storageaccountname ${REMOTE_STATE_SA} \ + --deployer_tfstate_key ${deployer_tfstate_key} --landscape_tfstate_key ${landscape_tfstate_key} \ + --ado --auto-approve + + return_code=$? + if [ 0 != $return_code ]; then + echo "##vso[task.logissue type=error]Return code from installer $return_code." + if [ -f ${environment_file_name}.err ]; then + error_message=$(cat ${environment_file_name}.err) + echo "##vso[task.logissue type=error]Error message: $error_message." + fi + fi + # Pull changes if there are other deployment jobs + + cd $HOME_CONFIG/SYSTEM/$(sap_system_folder) + + echo -e "$green--- Pull the latest content from DevOps ---$reset" + git pull + echo -e "$green--- Add & update files in the DevOps Repository ---$reset" + + added=0 + + if [ -f $.terraform/terraform.tfstate ]; then + git add -f .terraform/terraform.tfstate + added=1 + fi + + if [ -f sap-parameters.yaml ]; then + git add sap-parameters.yaml + added=1 + fi + + if [ -f ${SID}_hosts.yaml ]; then + git add -f ${SID}_hosts.yaml + added=1 + fi + + if [ -f ${SID}.md ]; then + git add ${SID}.md + added=1 + fi + + if [ -f ${SID}_inventory.md ]; then + git add ${SID}_inventory.md + added=1 + fi + + if [ -f ${SID}_resource_names.json ]; then + git add ${SID}_resource_names.json + added=1 + fi + + if [ -f $(sap_system_configuration) ]; then + git add $(sap_system_configuration) + added=1 + fi + + if [ -f ${SID}_virtual_machines.json ]; then + git add ${SID}_virtual_machines.json + added=1 + fi + + if [ 1 == $added ]; then + git config --global user.email "$(Build.RequestedForEmail)" + git config --global user.name "$(Build.RequestedFor)" + git commit -m "Added updates from devops system deployment $(Build.DefinitionName) [skip ci]" + + git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" push --set-upstream origin $(Build.SourceBranchName) + fi + + if [ -f ${SID}.md ]; then + echo "##vso[task.uploadsummary]$HOME_CONFIG/SYSTEM/$(sap_system_folder)/${SID}.md" + fi + + # file_name=${SID}_inventory.md + # if [ -f ${SID}_inventory.md ]; then + # az devops configure --defaults organization=$(System.CollectionUri) project='$(System.TeamProject)' --output none + + # # ToDo: Fix this later + # # WIKI_NAME_FOUND=$(az devops wiki list --query "[?name=='SDAF'].name | [0]") + # # echo "${WIKI_NAME_FOUND}" + # # if [ -n "${WIKI_NAME_FOUND}" ]; then + # # eTag=$(az devops wiki page show --path "${file_name}" --wiki SDAF --query eTag ) + # # if [ -n "$eTag" ]; then + # # az devops wiki page update --path "${file_name}" --wiki SDAF --file-path ./"${file_name}" --only-show-errors --version $eTag --output none + # # else + # # az devops wiki page create --path "${file_name}" --wiki SDAF --file-path ./"${file_name}" --output none --only-show-errors + # # fi + # # fi + # fi + + exit $return_code + + displayName: Deploy_SAP_infrastructure + env: + CONFIG_REPO_PATH: ${{ parameters.config_repo_path }} + LOGON_USING_SPN: $(Logon_Using_SPN) + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) + SAP_AUTOMATION_REPO_PATH: ${{ parameters.sap_automation_repo_path }} + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + TEST_ONLY: ${{ parameters.test }} + TF_IN_AUTOMATION: true + TF_LOG: $(TF_LOG) + USE_MSI: $(Use_MSI) + WL_ARM_CLIENT_ID: $(ARM_CLIENT_ID) + WL_ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET) + WL_ARM_SUBSCRIPTION_ID: $(ARM_SUBSCRIPTION_ID) + WL_ARM_TENANT_ID: $(ARM_TENANT_ID) + + failOnStderr: false diff --git a/deploy/pipelines/10-remover-terraform.yaml b/deploy/pipelines/10-remover-terraform.yaml index 08828c6ca1..88af8e6930 100644 --- a/deploy/pipelines/10-remover-terraform.yaml +++ b/deploy/pipelines/10-remover-terraform.yaml @@ -7,902 +7,903 @@ # +------------------------------------4--------------------------------------*/ parameters: - - name: cleanup_sap - displayName: Remove the SAP system - type: boolean - default: true - - - name: sap_system - displayName: "SAP System configuration name, use this format: ENV-LOCA-VNET-SID" - type: string - default: DEV-WEEU-SAP01-X00 - - - name: cleanup_zone - displayName: Remove the SAP workload zone - type: boolean - default: true - - - name: workload_zone - displayName: "SAP workload zone configuration name, use this format: ENV-LOCA-VNET-INFRASTRUCTURE" - type: string - default: DEV-WEEU-SAP01-INFRASTRUCTURE - - - name: cleanup_region - displayName: Remove the control plane - type: boolean - default: true - - - name: deployer - displayName: "Deployer configuration name, use this format: ENV-LOCA-VNET-INFRASTRUCTURE" - type: string - default: MGMT-WEEU-DEP00-INFRASTRUCTURE - - - name: library - displayName: "Library configuration name, use this format: ENV-LOCA-SAP_LIBRARY" - type: string - default: MGMT-WEEU-SAP_LIBRARY - - - name: workload_environment - displayName: Environment (DEV, QUA, PRD) - type: string - default: DEV - - - name: deployer_environment - displayName: Environment (MGMT) - type: string - default: MMGMT - - - name: use_deployer - displayName: Run removal on self hosted agent - type: boolean - default: true - - - name: sap_automation_repo_path - displayName: The local path on the agent where the sap_automation repo can be found - type: string - - - name: config_repo_path - displayName: The local path on the agent where the config repo can be found - type: string +- name: cleanup_sap + displayName: Remove the SAP system + type: boolean + default: true + +- name: sap_system + displayName: "SAP System configuration name, use this format: ENV-LOCA-VNET-SID" + type: string + default: DEV-WEEU-SAP01-X00 + +- name: cleanup_zone + displayName: Remove the SAP workload zone + type: boolean + default: true + +- name: workload_zone + displayName: "SAP workload zone configuration name, use this format: + ENV-LOCA-VNET-INFRASTRUCTURE" + type: string + default: DEV-WEEU-SAP01-INFRASTRUCTURE + +- name: cleanup_region + displayName: Remove the control plane + type: boolean + default: true + +- name: deployer + displayName: "Deployer configuration name, use this format: ENV-LOCA-VNET-INFRASTRUCTURE" + type: string + default: MGMT-WEEU-DEP00-INFRASTRUCTURE + +- name: library + displayName: "Library configuration name, use this format: ENV-LOCA-SAP_LIBRARY" + type: string + default: MGMT-WEEU-SAP_LIBRARY + +- name: workload_environment + displayName: Environment (DEV, QUA, PRD) + type: string + default: DEV + +- name: deployer_environment + displayName: Environment (MGMT) + type: string + default: MMGMT + +- name: use_deployer + displayName: Run removal on self hosted agent + type: boolean + default: true + +- name: sap_automation_repo_path + displayName: The local path on the agent where the sap_automation repo can be found + type: string + +- name: config_repo_path + displayName: The local path on the agent where the config repo can be found + type: string stages: - - stage: Remove_SAP_systems +- stage: Remove_SAP_systems + displayName: "Removing the SAP System" + condition: and(not(failed()), not(canceled()), eq(${{ parameters.cleanup_sap }}, true)) + variables: + - template: variables/10-remover-terraform-variables.yaml + parameters: + deployer_environment: ${{ parameters.deployer_environment }} + workload_environment: ${{ parameters.workload_environment }} + workload_zone: ${{ parameters.workload_zone }} + sap_system: ${{ parameters.sap_system }} + jobs: + - job: Remove_SAP_systems displayName: "Removing the SAP System" - condition: and(not(failed()), not(canceled()), eq(${{ parameters.cleanup_sap }}, true)) variables: - - template: variables/10-remover-terraform-variables.yaml - parameters: - deployer_environment: ${{ parameters.deployer_environment }} - workload_environment: ${{ parameters.workload_environment }} - workload_zone: ${{ parameters.workload_zone }} - sap_system: ${{ parameters.sap_system }} - jobs: - - job: Remove_SAP_systems - displayName: "Removing the SAP System" - variables: - - group: SDAF-${{ parameters.workload_environment }} - workspace: - clean: all - steps: - - template: templates\download.yaml - - bash: | - #!/bin/bash - green="\e[1;32m" ; reset="\e[0m" ; boldred="\e[1;31m" ; cyan="\e[1;36m" - - echo -e "$green--- Checkout $(Build.SourceBranchName) ---$reset" - - echo "##vso[build.updatebuildnumber]Removing the SAP System defined in $(sap_system_folder)" - - echo -e "$green--- Validations ---$reset" - HOME_CONFIG=${CONFIG_REPO_PATH} - cd $HOME_CONFIG; mkdir -p .sap_deployment_automation - if [ ! -f SYSTEM/$(sap_system_folder)/$(sap_system_configuration) ]; then - echo -e "$boldred--- $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) was not found ---$reset" - echo "##vso[task.logissue type=error]File SYSTEM/$(sap_system_folder)/$(sap_system_configuration) was not found." - exit 2 - fi - - if [ $USE_MSI != "true" ]; then - - if [ -z $WL_ARM_SUBSCRIPTION_ID ]; then - echo "##vso[task.logissue type=error]Variable ARM_SUBSCRIPTION_ID was not defined in the $(variable_group) variable group." - exit 2 - fi - - if [ $WL_ARM_SUBSCRIPTION_ID == '$$(ARM_SUBSCRIPTION_ID)' ]; then - echo "##vso[task.logissue type=error]Variable ARM_SUBSCRIPTION_ID was not defined in the $(variable_group) variable group." - exit 2 - fi - - if [ -z $WL_ARM_CLIENT_ID ]; then - echo "##vso[task.logissue type=error]Variable ARM_CLIENT_ID was not defined in the $(variable_group) variable group." - exit 2 - fi - - if [ $WL_ARM_CLIENT_ID == '$$(ARM_CLIENT_ID)' ]; then - echo "##vso[task.logissue type=error]Variable ARM_CLIENT_ID was not defined in the $(variable_group) variable group." - exit 2 - fi - - if [ -z $WL_ARM_CLIENT_SECRET ]; then - echo "##vso[task.logissue type=error]Variable ARM_CLIENT_SECRET was not defined in the $(variable_group) variable group." - exit 2 - fi - - if [ $WL_ARM_CLIENT_SECRET == '$$(ARM_CLIENT_SECRET)' ]; then - echo "##vso[task.logissue type=error]Variable ARM_CLIENT_SECRET was not defined in the $(variable_group) variable group." - exit 2 - fi - - if [ -z $WL_ARM_TENANT_ID ]; then - echo "##vso[task.logissue type=error]Variable ARM_TENANT_ID was not defined in the $(variable_group) variable group." - exit 2 - fi - - if [ $WL_ARM_TENANT_ID == '$$(ARM_TENANT_ID)' ]; then - echo "##vso[task.logissue type=error]Variable ARM_TENANT_ID was not defined in the $(variable_group) variable group." - exit 2 - fi - - fi - - - # Check if running on deployer - if [[ ! -f /etc/profile.d/deploy_server.sh ]]; then - echo -e "$green--- Install dos2unix ---$reset" - sudo apt-get -qq install dos2unix - - echo -e "$green--- Install terraform ---$reset" - - wget -q $(tf_url) - return_code=$? - if [ 0 != $return_code ]; then - echo "##vso[task.logissue type=error]Unable to download Terraform version $(tf_version)." - exit 2 - fi - unzip -qq terraform_$(tf_version)_linux_amd64.zip ; sudo mv terraform /bin/ - rm -f terraform_$(tf_version)_linux_amd64.zip - else - if [ $USE_MSI != "true" ]; then - - export ARM_CLIENT_ID=$WL_ARM_CLIENT_ID - export ARM_CLIENT_SECRET=$WL_ARM_CLIENT_SECRET - export ARM_TENANT_ID=$WL_ARM_TENANT_ID - export ARM_SUBSCRIPTION_ID=$WL_ARM_SUBSCRIPTION_ID - unset ARM_USE_MSI - az login --service-principal --username $WL_ARM_CLIENT_ID --password=$WL_ARM_CLIENT_SECRET --tenant $WL_ARM_TENANT_ID --output none - return_code=$? - if [ 0 != $return_code ]; then - echo -e "$boldred--- Login failed ---$reset" - echo "##vso[task.logissue type=error]az login failed." - exit $return_code - fi - else - echo "Deployment credentials: Managed Identity" - - export ARM_USE_MSI=true - export ARM_SUBSCRIPTION_ID=$WL_ARM_SUBSCRIPTION_ID - unset ARM_TENANT_ID - az login --identity --allow-no-subscriptions --output none - fi - fi - echo -e "$green--- Configure devops CLI extension ---$reset" - - az config set extension.use_dynamic_install=yes_without_prompt --output none --only-show-errors - - az devops configure --defaults organization=$(System.CollectionUri) project='$(System.TeamProject)' --output none --only-show-errors - - export VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(variable_group)'].id | [0]") - - if [ -z ${VARIABLE_GROUP_ID} ]; then - echo "##vso[task.logissue type=error]Variable group $(variable_group) could not be found." - exit 2 - fi - export PARENT_VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(parent_variable_group)'].id | [0]"); - - if [ -z ${PARENT_VARIABLE_GROUP_ID} ]; then - echo "##vso[task.logissue type=error]Variable group $(parent_variable_group) could not be found." - exit 2 - fi - - echo -e "$green--- Convert config file to UX format ---$reset" - dos2unix -q $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) - echo -e "$green--- Read parameters ---$reset" - - ENVIRONMENT=$(grep "^environment" $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) | awk -F'=' '{print $2}' | xargs) - LOCATION=$(grep "^location" $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) | awk -F'=' '{print $2}' | xargs | tr 'A-Z' 'a-z') - NETWORK=$(grep "^network_logical_name" $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) | awk -F'=' '{print $2}' | xargs) - SID=$(grep "^sid" $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) | awk -F'=' '{print $2}' | xargs) - - ENVIRONMENT_IN_FILENAME=$(echo $(sap_system_folder) | awk -F'-' '{print $1}' | xargs) - LOCATION_CODE=$(echo $(sap_system_folder) | awk -F'-' '{print $2}' | xargs) - NETWORK_IN_FILENAME=$(echo $(sap_system_folder) | awk -F'-' '{print $3}' | xargs) - SID_IN_FILENAME=$(echo $(sap_system_folder) | awk -F'-' '{print $4}' | xargs) - case "$LOCATION_CODE" in - "AUCE") LOCATION_IN_FILENAME="australiacentral" ;; - "AUC2") LOCATION_IN_FILENAME="australiacentral2" ;; - "AUEA") LOCATION_IN_FILENAME="australiaeast" ;; - "AUSE") LOCATION_IN_FILENAME="australiasoutheast" ;; - "BRSO") LOCATION_IN_FILENAME="brazilsouth" ;; - "BRSE") LOCATION_IN_FILENAME="brazilsoutheast" ;; - "BRUS") LOCATION_IN_FILENAME="brazilus" ;; - "CACE") LOCATION_IN_FILENAME="canadacentral" ;; - "CAEA") LOCATION_IN_FILENAME="canadaeast" ;; - "CEIN") LOCATION_IN_FILENAME="centralindia" ;; - "CEUS") LOCATION_IN_FILENAME="centralus" ;; - "CEUA") LOCATION_IN_FILENAME="centraluseuap" ;; - "EAAS") LOCATION_IN_FILENAME="eastasia" ;; - "EAUS") LOCATION_IN_FILENAME="eastus" ;; - "EUSA") LOCATION_IN_FILENAME="eastus2euap" ;; - "EUS2") LOCATION_IN_FILENAME="eastus2" ;; - "EUSG") LOCATION_IN_FILENAME="eastusstg" ;; - "FRCE") LOCATION_IN_FILENAME="francecentral" ;; - "FRSO") LOCATION_IN_FILENAME="francesouth" ;; - "GENO") LOCATION_IN_FILENAME="germanynorth" ;; - "GEWE") LOCATION_IN_FILENAME="germanywest" ;; - "GEWC") LOCATION_IN_FILENAME="germanywestcentral" ;; - "ISCE") LOCATION_IN_FILENAME="israelcentral" ;; - "ITNO") LOCATION_IN_FILENAME="italynorth" ;; - "JAEA") LOCATION_IN_FILENAME="japaneast" ;; - "JAWE") LOCATION_IN_FILENAME="japanwest" ;; - "JINC") LOCATION_IN_FILENAME="jioindiacentral" ;; - "JINW") LOCATION_IN_FILENAME="jioindiawest" ;; - "KOCE") LOCATION_IN_FILENAME="koreacentral" ;; - "KOSO") LOCATION_IN_FILENAME="koreasouth" ;; - "NCUS") LOCATION_IN_FILENAME="northcentralus" ;; - "NOEU") LOCATION_IN_FILENAME="northeurope" ;; - "NOEA") LOCATION_IN_FILENAME="norwayeast" ;; - "NOWE") LOCATION_IN_FILENAME="norwaywest" ;; - "PLCE") LOCATION_IN_FILENAME="polandcentral" ;; - "QACE") LOCATION_IN_FILENAME="qatarcentral" ;; - "SANO") LOCATION_IN_FILENAME="southafricanorth" ;; - "SAWE") LOCATION_IN_FILENAME="southafricawest" ;; - "SCUS") LOCATION_IN_FILENAME="southcentralus" ;; - "SCUG") LOCATION_IN_FILENAME="southcentralusstg" ;; - "SOEA") LOCATION_IN_FILENAME="southeastasia" ;; - "SOIN") LOCATION_IN_FILENAME="southindia" ;; - "SECE") LOCATION_IN_FILENAME="swedencentral" ;; - "SWNO") LOCATION_IN_FILENAME="switzerlandnorth" ;; - "SWWE") LOCATION_IN_FILENAME="switzerlandwest" ;; - "UACE") LOCATION_IN_FILENAME="uaecentral" ;; - "UANO") LOCATION_IN_FILENAME="uaenorth" ;; - "UKSO") LOCATION_IN_FILENAME="uksouth" ;; - "UKWE") LOCATION_IN_FILENAME="ukwest" ;; - "WCUS") LOCATION_IN_FILENAME="westcentralus" ;; - "WEEU") LOCATION_IN_FILENAME="westeurope" ;; - "WEIN") LOCATION_IN_FILENAME="westindia" ;; - "WEUS") LOCATION_IN_FILENAME="westus" ;; - "WUS2") LOCATION_IN_FILENAME="westus2" ;; - "WUS3") LOCATION_IN_FILENAME="westus3" ;; - *) LOCATION_IN_FILENAME="westeurope" ;; - esac - - - workload_environment_file_name=$HOME/.sap_deployment_automation/$ENVIRONMENT$LOCATION_CODE$NETWORK; - echo "Workload Environment file: $workload_environment_file_name" - - echo "Environment: $ENVIRONMENT" - echo "Location: $LOCATION" - echo "Network: $NETWORK" - echo "SID: $SID" - echo "" - echo "Environment(filename): $ENVIRONMENT_IN_FILENAME" - echo "Location(filename): $LOCATION_IN_FILENAME" - echo "Network(filename): $NETWORK_IN_FILENAME" - echo "SID(filename): $SID_IN_FILENAME" - - printf -v tempval '%s id:' $(variable_group) - printf -v val '%-20s' "${tempval}" - echo "$val $VARIABLE_GROUP_ID" - - printf -v tempval '%s id:' $(parent_variable_group) - printf -v val '%-20s' "${tempval}" - echo "$val $PARENT_VARIABLE_GROUP_ID" - - echo "" - - if [ $ENVIRONMENT != $ENVIRONMENT_IN_FILENAME ]; then - echo "##vso[task.logissue type=error]The environment setting in $(sap_system_configuration) '$ENVIRONMENT' does not match the $(sap_system_configuration) file name '$ENVIRONMENT_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-[SID]" - exit 2 - fi - - if [ $LOCATION != $LOCATION_IN_FILENAME ]; then - echo "##vso[task.logissue type=error]The location setting in $(sap_system_configuration) '$LOCATION' does not match the $(sap_system_configuration) file name '$LOCATION_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-[SID]" - exit 2 - fi - - if [ $NETWORK != $NETWORK_IN_FILENAME ]; then - echo "##vso[task.logissue type=error]The network_logical_name setting in $(sap_system_configuration) '$NETWORK' does not match the $(sap_system_configuration) file name '$NETWORK_IN_FILENAME-. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-[SID]" - exit 2 - fi - - if [ $SID != $SID_IN_FILENAME ]; then - echo "##vso[task.logissue type=error]The sid setting in $(sap_system_configuration) '$SID' does not match the $(sap_system_configuration) file name '$SID_IN_FILENAME-. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-[SID]" - exit 2 - fi - - # Check if running on deployer - if [[ ! -f /etc/profile.d/deploy_server.sh ]]; then - - if [ $USE_MSI != "true" ]; then - echo "Deployment credentials: Service Principal" - echo "Deployment credentials ID (SPN): $WL_ARM_CLIENT_SECRET" - - export ARM_CLIENT_ID=$WL_ARM_CLIENT_ID - export ARM_CLIENT_SECRET=$WL_ARM_CLIENT_SECRET - export ARM_TENANT_ID=$WL_ARM_TENANT_ID - export ARM_SUBSCRIPTION_ID=$WL_ARM_SUBSCRIPTION_ID - unset ARM_USE_MSI - az login --service-principal --username $WL_ARM_CLIENT_ID --password=$WL_ARM_CLIENT_SECRET --tenant $WL_ARM_TENANT_ID --output none - return_code=$? - if [ 0 != $return_code ]; then - echo -e "$boldred--- Login failed ---$reset" - echo "##vso[task.logissue type=error]az login failed." - exit $return_code - fi - else - export ARM_USE_MSI=true - az login --identity --allow-no-subscriptions --output none - fi - else - echo -e "$green--- Running on deployer ---$reset" - - if [ $USE_MSI != "true" ]; then - echo "Deployment credentials: Service Principal" - echo "Deployment credentials ID (SPN): $WL_ARM_CLIENT_SECRET" - - export ARM_CLIENT_ID=$WL_ARM_CLIENT_ID - export ARM_CLIENT_SECRET=$WL_ARM_CLIENT_SECRET - export ARM_TENANT_ID=$WL_ARM_TENANT_ID - export ARM_SUBSCRIPTION_ID=$WL_ARM_SUBSCRIPTION_ID - unset ARM_USE_MSI - az login --service-principal --username $WL_ARM_CLIENT_ID --password=$WL_ARM_CLIENT_SECRET --tenant $WL_ARM_TENANT_ID --output none - return_code=$? - if [ 0 != $return_code ]; then - echo -e "$boldred--- Login failed ---$reset" - echo "##vso[task.logissue type=error]az login failed." - exit $return_code - fi - else - echo "Deployment credentials: Managed Identity" - export ARM_USE_MSI=true - export ARM_SUBSCRIPTION_ID=$WL_ARM_SUBSCRIPTION_ID - unset ARM_TENANT_ID - az login --identity --allow-no-subscriptions --output none - fi - fi - - echo -e "$green--- Set variables ---$reset" - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "${NETWORK}Workload_Key_Vault.value" --out tsv) - if [ -z ${az_var} ]; then - export workload_key_vault=$(grep -m1 "^workloadkeyvault=" "${workload_environment_file_name}" | awk -F'=' '{print $2}' | xargs) - else - export workload_key_vault="${az_var}" - fi - - if [ -n $(Deployer_Key_Vault) ]; then - export key_vault=$(Deployer_Key_Vault) - else - export key_vault=$(grep -m1 "^keyvault=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) - fi - - az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Subscription.value" --out tsv) - if [ -n "${az_var}" ]; then - STATE_SUBSCRIPTION="${az_var}" - else - STATE_SUBSCRIPTION=$(grep "^STATE_SUBSCRIPTION=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) - fi - - az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Account_Name.value" --out tsv) - if [ -n "${az_var}" ]; then - REMOTE_STATE_SA="${az_var}" - else - REMOTE_STATE_SA=$(grep "REMOTE_STATE_SA" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) - fi - - echo "Deployer Key Vault: ${key_vault}" - - echo "Workload Key Vault: ${workload_key_vault}" - echo "TF state subscription: $STATE_SUBSCRIPTION" - echo "TF state account: $REMOTE_STATE_SA" - echo "System configuration: $(sap_system_configuration)" - - az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Deployer_State_FileName.value" --out tsv) - if [ -n "${az_var}" ]; then - export deployer_tfstate_key="${az_var}" - else - export deployer_tfstate_key=$(grep "^deployer_tfstate_key=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) - fi - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query $NETWORK"Workload_Zone_State_FileName.value" --out tsv) - if [ -n "${az_var}" ]; then - export landscape_tfstate_key="${az_var}" - else - export landscape_tfstate_key=$(grep "^landscape_tfstate_key=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) - fi - - cd $CONFIG_REPO_PATH/SYSTEM/$(sap_system_folder) || exit - - echo "Deployer state file name: $deployer_tfstate_key" - echo "Workload zone state file name: $landscape_tfstate_key" - - echo -e "$green--- Run the remover script that destroys the SAP system ---$reset" - - ${SAP_AUTOMATION_REPO_PATH}/deploy/scripts/remover.sh \ - --parameterfile $(sap_system_configuration) \ - --type sap_system \ - --state_subscription "${STATE_SUBSCRIPTION}" \ - --storageaccountname "${REMOTE_STATE_SA}" \ - --auto-approve - - return_code=$? - echo -e "$green--- Pull latest from DevOps Repository ---$reset" - git checkout -q $(Build.SourceBranchName) - git pull - - #stop the pipeline after you have reset the whitelisting on your resources - echo "Return code from remover.sh: $return_code." - if [ 0 != $return_code ]; then - echo "##vso[task.logissue type=error]Return code from remover.sh $return_code." - exit $return_code - fi - - echo -e "$green--- Add & update files in the DevOps Repository ---$reset" - cd $(Build.Repository.LocalPath) - - changed=0 - # Pull changes - git checkout -q $(Build.SourceBranchName) - git pull origin $(Build.SourceBranchName) - - if [ 0 == $return_code ]; then - - if [ -d $(Deployment_Configuration_Path)/SYSTEM/$(sap_system_folder)/.terraform ]; then - git rm -q -r --ignore-unmatch -f $(Deployment_Configuration_Path)/SYSTEM/$(sap_system_folder)/.terraform - changed=1 - fi - - if [ -f $(sap_system_configuration) ]; then - git add $(sap_system_configuration) - added=1 - fi - - if [ -f $(Deployment_Configuration_Path)/SYSTEM/$(sap_system_folder)/sap-parameters.yaml ]; then - git rm --ignore-unmatch -q $(Deployment_Configuration_Path)/SYSTEM/$(sap_system_folder)/sap-parameters.yaml - changed=1 - fi - - if [ $(ls $(Deployment_Configuration_Path)/SYSTEM/$(sap_system_folder)/*_hosts.yaml | wc -l ) -gt 0 ] ; then - git rm --ignore-unmatch -q $(Deployment_Configuration_Path)/SYSTEM/$(sap_system_folder)/*_hosts.yaml - changed=1 - fi - - if [ $(ls $(Deployment_Configuration_Path)/SYSTEM/$(sap_system_folder)/*.md | wc -l ) -gt 0 ] ; then - git rm --ignore-unmatch -q $(Deployment_Configuration_Path)/SYSTEM/$(sap_system_folder)/*.md - changed=1 - fi - - if [ 1 == $changed ]; then - git config --global user.email "$(Build.RequestedForEmail)" - git config --global user.name "$(Build.RequestedFor)" - git commit -m "Infrastructure for ${sap_system_folder} removed. [skip ci]" - git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" push --set-upstream origin $(Build.SourceBranchName) - fi - fi - - exit $return_code - - displayName: "Remove SAP system" - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - WL_ARM_SUBSCRIPTION_ID: $(WL_ARM_SUBSCRIPTION_ID) - WL_ARM_CLIENT_ID: $(WL_ARM_CLIENT_ID) - WL_ARM_CLIENT_SECRET: $(WL_ARM_CLIENT_SECRET) - WL_ARM_TENANT_ID: $(WL_ARM_TENANT_ID) - AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) - SAP_AUTOMATION_REPO_PATH: ${{ parameters.sap_automation_repo_path }} - CONFIG_REPO_PATH: ${{ parameters.config_repo_path }}/$(Deployment_Configuration_Path) - LOGON_USING_SPN: $(Logon_Using_SPN) - USE_MSI: $(Use_MSI) - - failOnStderr: false - - - stage: Remove_SAP_workload_zone - displayName: "Removing the SAP workload zone" - condition: and(not(failed()), not(canceled()), eq(${{ parameters.cleanup_zone }}, true)) + - group: SDAF-${{ parameters.workload_environment }} + workspace: + clean: all + steps: + - template: templates\download.yaml + - bash: | + #!/bin/bash + green="\e[1;32m" ; reset="\e[0m" ; boldred="\e[1;31m" ; cyan="\e[1;36m" + + echo -e "$green--- Checkout $(Build.SourceBranchName) ---$reset" + + echo "##vso[build.updatebuildnumber]Removing the SAP System defined in $(sap_system_folder)" + + echo -e "$green--- Validations ---$reset" + HOME_CONFIG=${CONFIG_REPO_PATH} + cd $HOME_CONFIG; mkdir -p .sap_deployment_automation + if [ ! -f SYSTEM/$(sap_system_folder)/$(sap_system_configuration) ]; then + echo -e "$boldred--- $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) was not found ---$reset" + echo "##vso[task.logissue type=error]File SYSTEM/$(sap_system_folder)/$(sap_system_configuration) was not found." + exit 2 + fi + + if [ $USE_MSI != "true" ]; then + + if [ -z $WL_ARM_SUBSCRIPTION_ID ]; then + echo "##vso[task.logissue type=error]Variable ARM_SUBSCRIPTION_ID was not defined in the $(variable_group) variable group." + exit 2 + fi + + if [ $WL_ARM_SUBSCRIPTION_ID == '$$(ARM_SUBSCRIPTION_ID)' ]; then + echo "##vso[task.logissue type=error]Variable ARM_SUBSCRIPTION_ID was not defined in the $(variable_group) variable group." + exit 2 + fi + + if [ -z $WL_ARM_CLIENT_ID ]; then + echo "##vso[task.logissue type=error]Variable ARM_CLIENT_ID was not defined in the $(variable_group) variable group." + exit 2 + fi + + if [ $WL_ARM_CLIENT_ID == '$$(ARM_CLIENT_ID)' ]; then + echo "##vso[task.logissue type=error]Variable ARM_CLIENT_ID was not defined in the $(variable_group) variable group." + exit 2 + fi + + if [ -z $WL_ARM_CLIENT_SECRET ]; then + echo "##vso[task.logissue type=error]Variable ARM_CLIENT_SECRET was not defined in the $(variable_group) variable group." + exit 2 + fi + + if [ $WL_ARM_CLIENT_SECRET == '$$(ARM_CLIENT_SECRET)' ]; then + echo "##vso[task.logissue type=error]Variable ARM_CLIENT_SECRET was not defined in the $(variable_group) variable group." + exit 2 + fi + + if [ -z $WL_ARM_TENANT_ID ]; then + echo "##vso[task.logissue type=error]Variable ARM_TENANT_ID was not defined in the $(variable_group) variable group." + exit 2 + fi + + if [ $WL_ARM_TENANT_ID == '$$(ARM_TENANT_ID)' ]; then + echo "##vso[task.logissue type=error]Variable ARM_TENANT_ID was not defined in the $(variable_group) variable group." + exit 2 + fi + + fi + + + # Check if running on deployer + if [[ ! -f /etc/profile.d/deploy_server.sh ]]; then + echo -e "$green--- Install dos2unix ---$reset" + sudo apt-get -qq install dos2unix + + echo -e "$green--- Install terraform ---$reset" + + wget -q $(tf_url) + return_code=$? + if [ 0 != $return_code ]; then + echo "##vso[task.logissue type=error]Unable to download Terraform version $(tf_version)." + exit 2 + fi + unzip -qq terraform_$(tf_version)_linux_amd64.zip ; sudo mv terraform /bin/ + rm -f terraform_$(tf_version)_linux_amd64.zip + else + if [ $USE_MSI != "true" ]; then + + export ARM_CLIENT_ID=$WL_ARM_CLIENT_ID + export ARM_CLIENT_SECRET=$WL_ARM_CLIENT_SECRET + export ARM_TENANT_ID=$WL_ARM_TENANT_ID + export ARM_SUBSCRIPTION_ID=$WL_ARM_SUBSCRIPTION_ID + unset ARM_USE_MSI + az login --service-principal --username $WL_ARM_CLIENT_ID --password=$WL_ARM_CLIENT_SECRET --tenant $WL_ARM_TENANT_ID --output none + return_code=$? + if [ 0 != $return_code ]; then + echo -e "$boldred--- Login failed ---$reset" + echo "##vso[task.logissue type=error]az login failed." + exit $return_code + fi + else + echo "Deployment credentials: Managed Identity" + + export ARM_USE_MSI=true + export ARM_SUBSCRIPTION_ID=$WL_ARM_SUBSCRIPTION_ID + unset ARM_TENANT_ID + az login --identity --allow-no-subscriptions --output none + fi + fi + echo -e "$green--- Configure devops CLI extension ---$reset" + + az config set extension.use_dynamic_install=yes_without_prompt --output none --only-show-errors + + az devops configure --defaults organization=$(System.CollectionUri) project='$(System.TeamProject)' --output none --only-show-errors + + export VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(variable_group)'].id | [0]") + + if [ -z ${VARIABLE_GROUP_ID} ]; then + echo "##vso[task.logissue type=error]Variable group $(variable_group) could not be found." + exit 2 + fi + export PARENT_VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(parent_variable_group)'].id | [0]"); + + if [ -z ${PARENT_VARIABLE_GROUP_ID} ]; then + echo "##vso[task.logissue type=error]Variable group $(parent_variable_group) could not be found." + exit 2 + fi + + echo -e "$green--- Convert config file to UX format ---$reset" + dos2unix -q $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) + echo -e "$green--- Read parameters ---$reset" + + ENVIRONMENT=$(grep "^environment" $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) | awk -F'=' '{print $2}' | xargs) + LOCATION=$(grep "^location" $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) | awk -F'=' '{print $2}' | xargs | tr 'A-Z' 'a-z') + NETWORK=$(grep "^network_logical_name" $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) | awk -F'=' '{print $2}' | xargs) + SID=$(grep "^sid" $HOME_CONFIG/SYSTEM/$(sap_system_folder)/$(sap_system_configuration) | awk -F'=' '{print $2}' | xargs) + + ENVIRONMENT_IN_FILENAME=$(echo $(sap_system_folder) | awk -F'-' '{print $1}' | xargs) + LOCATION_CODE=$(echo $(sap_system_folder) | awk -F'-' '{print $2}' | xargs) + NETWORK_IN_FILENAME=$(echo $(sap_system_folder) | awk -F'-' '{print $3}' | xargs) + SID_IN_FILENAME=$(echo $(sap_system_folder) | awk -F'-' '{print $4}' | xargs) + case "$LOCATION_CODE" in + "AUCE") LOCATION_IN_FILENAME="australiacentral" ;; + "AUC2") LOCATION_IN_FILENAME="australiacentral2" ;; + "AUEA") LOCATION_IN_FILENAME="australiaeast" ;; + "AUSE") LOCATION_IN_FILENAME="australiasoutheast" ;; + "BRSO") LOCATION_IN_FILENAME="brazilsouth" ;; + "BRSE") LOCATION_IN_FILENAME="brazilsoutheast" ;; + "BRUS") LOCATION_IN_FILENAME="brazilus" ;; + "CACE") LOCATION_IN_FILENAME="canadacentral" ;; + "CAEA") LOCATION_IN_FILENAME="canadaeast" ;; + "CEIN") LOCATION_IN_FILENAME="centralindia" ;; + "CEUS") LOCATION_IN_FILENAME="centralus" ;; + "CEUA") LOCATION_IN_FILENAME="centraluseuap" ;; + "EAAS") LOCATION_IN_FILENAME="eastasia" ;; + "EAUS") LOCATION_IN_FILENAME="eastus" ;; + "EUSA") LOCATION_IN_FILENAME="eastus2euap" ;; + "EUS2") LOCATION_IN_FILENAME="eastus2" ;; + "EUSG") LOCATION_IN_FILENAME="eastusstg" ;; + "FRCE") LOCATION_IN_FILENAME="francecentral" ;; + "FRSO") LOCATION_IN_FILENAME="francesouth" ;; + "GENO") LOCATION_IN_FILENAME="germanynorth" ;; + "GEWE") LOCATION_IN_FILENAME="germanywest" ;; + "GEWC") LOCATION_IN_FILENAME="germanywestcentral" ;; + "ISCE") LOCATION_IN_FILENAME="israelcentral" ;; + "ITNO") LOCATION_IN_FILENAME="italynorth" ;; + "JAEA") LOCATION_IN_FILENAME="japaneast" ;; + "JAWE") LOCATION_IN_FILENAME="japanwest" ;; + "JINC") LOCATION_IN_FILENAME="jioindiacentral" ;; + "JINW") LOCATION_IN_FILENAME="jioindiawest" ;; + "KOCE") LOCATION_IN_FILENAME="koreacentral" ;; + "KOSO") LOCATION_IN_FILENAME="koreasouth" ;; + "NCUS") LOCATION_IN_FILENAME="northcentralus" ;; + "NOEU") LOCATION_IN_FILENAME="northeurope" ;; + "NOEA") LOCATION_IN_FILENAME="norwayeast" ;; + "NOWE") LOCATION_IN_FILENAME="norwaywest" ;; + "PLCE") LOCATION_IN_FILENAME="polandcentral" ;; + "QACE") LOCATION_IN_FILENAME="qatarcentral" ;; + "SANO") LOCATION_IN_FILENAME="southafricanorth" ;; + "SAWE") LOCATION_IN_FILENAME="southafricawest" ;; + "SCUS") LOCATION_IN_FILENAME="southcentralus" ;; + "SCUG") LOCATION_IN_FILENAME="southcentralusstg" ;; + "SOEA") LOCATION_IN_FILENAME="southeastasia" ;; + "SOIN") LOCATION_IN_FILENAME="southindia" ;; + "SECE") LOCATION_IN_FILENAME="swedencentral" ;; + "SWNO") LOCATION_IN_FILENAME="switzerlandnorth" ;; + "SWWE") LOCATION_IN_FILENAME="switzerlandwest" ;; + "UACE") LOCATION_IN_FILENAME="uaecentral" ;; + "UANO") LOCATION_IN_FILENAME="uaenorth" ;; + "UKSO") LOCATION_IN_FILENAME="uksouth" ;; + "UKWE") LOCATION_IN_FILENAME="ukwest" ;; + "WCUS") LOCATION_IN_FILENAME="westcentralus" ;; + "WEEU") LOCATION_IN_FILENAME="westeurope" ;; + "WEIN") LOCATION_IN_FILENAME="westindia" ;; + "WEUS") LOCATION_IN_FILENAME="westus" ;; + "WUS2") LOCATION_IN_FILENAME="westus2" ;; + "WUS3") LOCATION_IN_FILENAME="westus3" ;; + *) LOCATION_IN_FILENAME="westeurope" ;; + esac + + + workload_environment_file_name=$HOME/.sap_deployment_automation/$ENVIRONMENT$LOCATION_CODE$NETWORK; + echo "Workload Environment file: $workload_environment_file_name" + + echo "Environment: $ENVIRONMENT" + echo "Location: $LOCATION" + echo "Network: $NETWORK" + echo "SID: $SID" + echo "" + echo "Environment(filename): $ENVIRONMENT_IN_FILENAME" + echo "Location(filename): $LOCATION_IN_FILENAME" + echo "Network(filename): $NETWORK_IN_FILENAME" + echo "SID(filename): $SID_IN_FILENAME" + + printf -v tempval '%s id:' $(variable_group) + printf -v val '%-20s' "${tempval}" + echo "$val $VARIABLE_GROUP_ID" + + printf -v tempval '%s id:' $(parent_variable_group) + printf -v val '%-20s' "${tempval}" + echo "$val $PARENT_VARIABLE_GROUP_ID" + + echo "" + + if [ $ENVIRONMENT != $ENVIRONMENT_IN_FILENAME ]; then + echo "##vso[task.logissue type=error]The environment setting in $(sap_system_configuration) '$ENVIRONMENT' does not match the $(sap_system_configuration) file name '$ENVIRONMENT_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-[SID]" + exit 2 + fi + + if [ $LOCATION != $LOCATION_IN_FILENAME ]; then + echo "##vso[task.logissue type=error]The location setting in $(sap_system_configuration) '$LOCATION' does not match the $(sap_system_configuration) file name '$LOCATION_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-[SID]" + exit 2 + fi + + if [ $NETWORK != $NETWORK_IN_FILENAME ]; then + echo "##vso[task.logissue type=error]The network_logical_name setting in $(sap_system_configuration) '$NETWORK' does not match the $(sap_system_configuration) file name '$NETWORK_IN_FILENAME-. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-[SID]" + exit 2 + fi + + if [ $SID != $SID_IN_FILENAME ]; then + echo "##vso[task.logissue type=error]The sid setting in $(sap_system_configuration) '$SID' does not match the $(sap_system_configuration) file name '$SID_IN_FILENAME-. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-[SID]" + exit 2 + fi + + # Check if running on deployer + if [[ ! -f /etc/profile.d/deploy_server.sh ]]; then + + if [ $USE_MSI != "true" ]; then + echo "Deployment credentials: Service Principal" + echo "Deployment credentials ID (SPN): $WL_ARM_CLIENT_SECRET" + + export ARM_CLIENT_ID=$WL_ARM_CLIENT_ID + export ARM_CLIENT_SECRET=$WL_ARM_CLIENT_SECRET + export ARM_TENANT_ID=$WL_ARM_TENANT_ID + export ARM_SUBSCRIPTION_ID=$WL_ARM_SUBSCRIPTION_ID + unset ARM_USE_MSI + az login --service-principal --username $WL_ARM_CLIENT_ID --password=$WL_ARM_CLIENT_SECRET --tenant $WL_ARM_TENANT_ID --output none + return_code=$? + if [ 0 != $return_code ]; then + echo -e "$boldred--- Login failed ---$reset" + echo "##vso[task.logissue type=error]az login failed." + exit $return_code + fi + else + export ARM_USE_MSI=true + az login --identity --allow-no-subscriptions --output none + fi + else + echo -e "$green--- Running on deployer ---$reset" + + if [ $USE_MSI != "true" ]; then + echo "Deployment credentials: Service Principal" + echo "Deployment credentials ID (SPN): $WL_ARM_CLIENT_SECRET" + + export ARM_CLIENT_ID=$WL_ARM_CLIENT_ID + export ARM_CLIENT_SECRET=$WL_ARM_CLIENT_SECRET + export ARM_TENANT_ID=$WL_ARM_TENANT_ID + export ARM_SUBSCRIPTION_ID=$WL_ARM_SUBSCRIPTION_ID + unset ARM_USE_MSI + az login --service-principal --username $WL_ARM_CLIENT_ID --password=$WL_ARM_CLIENT_SECRET --tenant $WL_ARM_TENANT_ID --output none + return_code=$? + if [ 0 != $return_code ]; then + echo -e "$boldred--- Login failed ---$reset" + echo "##vso[task.logissue type=error]az login failed." + exit $return_code + fi + else + echo "Deployment credentials: Managed Identity" + export ARM_USE_MSI=true + export ARM_SUBSCRIPTION_ID=$WL_ARM_SUBSCRIPTION_ID + unset ARM_TENANT_ID + az login --identity --allow-no-subscriptions --output none + fi + fi + + echo -e "$green--- Set variables ---$reset" + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "${NETWORK}Workload_Key_Vault.value" --out tsv) + if [ -z ${az_var} ]; then + export workload_key_vault=$(grep -m1 "^workloadkeyvault=" "${workload_environment_file_name}" | awk -F'=' '{print $2}' | xargs) + else + export workload_key_vault="${az_var}" + fi + + if [ -n $(Deployer_Key_Vault) ]; then + export key_vault=$(Deployer_Key_Vault) + else + export key_vault=$(grep -m1 "^keyvault=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) + fi + + az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Subscription.value" --out tsv) + if [ -n "${az_var}" ]; then + STATE_SUBSCRIPTION="${az_var}" + else + STATE_SUBSCRIPTION=$(grep "^STATE_SUBSCRIPTION=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) + fi + + az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Account_Name.value" --out tsv) + if [ -n "${az_var}" ]; then + REMOTE_STATE_SA="${az_var}" + else + REMOTE_STATE_SA=$(grep "REMOTE_STATE_SA" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) + fi + + echo "Deployer Key Vault: ${key_vault}" + + echo "Workload Key Vault: ${workload_key_vault}" + echo "TF state subscription: $STATE_SUBSCRIPTION" + echo "TF state account: $REMOTE_STATE_SA" + echo "System configuration: $(sap_system_configuration)" + + az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Deployer_State_FileName.value" --out tsv) + if [ -n "${az_var}" ]; then + export deployer_tfstate_key="${az_var}" + else + export deployer_tfstate_key=$(grep "^deployer_tfstate_key=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) + fi + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query $NETWORK"Workload_Zone_State_FileName.value" --out tsv) + if [ -n "${az_var}" ]; then + export landscape_tfstate_key="${az_var}" + else + export landscape_tfstate_key=$(grep "^landscape_tfstate_key=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) + fi + + cd $CONFIG_REPO_PATH/SYSTEM/$(sap_system_folder) || exit + + echo "Deployer state file name: $deployer_tfstate_key" + echo "Workload zone state file name: $landscape_tfstate_key" + + echo -e "$green--- Run the remover script that destroys the SAP system ---$reset" + + ${SAP_AUTOMATION_REPO_PATH}/deploy/scripts/remover.sh \ + --parameterfile $(sap_system_configuration) \ + --type sap_system \ + --state_subscription "${STATE_SUBSCRIPTION}" \ + --storageaccountname "${REMOTE_STATE_SA}" \ + --auto-approve + + return_code=$? + echo -e "$green--- Pull latest from DevOps Repository ---$reset" + git checkout -q $(Build.SourceBranchName) + git pull + + #stop the pipeline after you have reset the whitelisting on your resources + echo "Return code from remover.sh: $return_code." + if [ 0 != $return_code ]; then + echo "##vso[task.logissue type=error]Return code from remover.sh $return_code." + exit $return_code + fi + + echo -e "$green--- Add & update files in the DevOps Repository ---$reset" + cd $(Build.Repository.LocalPath) + + changed=0 + # Pull changes + git checkout -q $(Build.SourceBranchName) + git pull origin $(Build.SourceBranchName) + + if [ 0 == $return_code ]; then + + if [ -d $(Deployment_Configuration_Path)/SYSTEM/$(sap_system_folder)/.terraform ]; then + git rm -q -r --ignore-unmatch -f $(Deployment_Configuration_Path)/SYSTEM/$(sap_system_folder)/.terraform + changed=1 + fi + + if [ -f $(sap_system_configuration) ]; then + git add $(sap_system_configuration) + added=1 + fi + + if [ -f $(Deployment_Configuration_Path)/SYSTEM/$(sap_system_folder)/sap-parameters.yaml ]; then + git rm --ignore-unmatch -q $(Deployment_Configuration_Path)/SYSTEM/$(sap_system_folder)/sap-parameters.yaml + changed=1 + fi + + if [ $(ls $(Deployment_Configuration_Path)/SYSTEM/$(sap_system_folder)/*_hosts.yaml | wc -l ) -gt 0 ] ; then + git rm --ignore-unmatch -q $(Deployment_Configuration_Path)/SYSTEM/$(sap_system_folder)/*_hosts.yaml + changed=1 + fi + + if [ $(ls $(Deployment_Configuration_Path)/SYSTEM/$(sap_system_folder)/*.md | wc -l ) -gt 0 ] ; then + git rm --ignore-unmatch -q $(Deployment_Configuration_Path)/SYSTEM/$(sap_system_folder)/*.md + changed=1 + fi + + if [ 1 == $changed ]; then + git config --global user.email "$(Build.RequestedForEmail)" + git config --global user.name "$(Build.RequestedFor)" + git commit -m "Infrastructure for ${sap_system_folder} removed. [skip ci]" + git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" push --set-upstream origin $(Build.SourceBranchName) + fi + fi + + exit $return_code + + displayName: "Remove SAP system" + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + WL_ARM_SUBSCRIPTION_ID: $(WL_ARM_SUBSCRIPTION_ID) + WL_ARM_CLIENT_ID: $(WL_ARM_CLIENT_ID) + WL_ARM_CLIENT_SECRET: $(WL_ARM_CLIENT_SECRET) + WL_ARM_TENANT_ID: $(WL_ARM_TENANT_ID) + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) + SAP_AUTOMATION_REPO_PATH: ${{ parameters.sap_automation_repo_path }} + CONFIG_REPO_PATH: ${{ parameters.config_repo_path }}/$(Deployment_Configuration_Path) + LOGON_USING_SPN: $(Logon_Using_SPN) + USE_MSI: $(Use_MSI) + + failOnStderr: false + +- stage: Remove_SAP_workload_zone + displayName: "Removing the SAP workload zone" + condition: and(not(failed()), not(canceled()), eq(${{ parameters.cleanup_zone }}, true)) + variables: + - template: variables/10-remover-terraform-variables.yaml + parameters: + deployer_environment: ${{ parameters.deployer_environment }} + workload_environment: ${{ parameters.workload_environment }} + workload_zone: ${{ parameters.workload_zone }} + sap_system: ${{ parameters.sap_system }} + + jobs: + - job: Remove_SAP_workload_zone + displayName: Remove the SAP Workload Zone variables: - - template: variables/10-remover-terraform-variables.yaml - parameters: - deployer_environment: ${{ parameters.deployer_environment }} - workload_environment: ${{ parameters.workload_environment }} - workload_zone: ${{ parameters.workload_zone }} - sap_system: ${{ parameters.sap_system }} - - jobs: - - job: Remove_SAP_workload_zone - displayName: Remove the SAP Workload Zone - variables: - - group: SDAF-${{ parameters.workload_environment }} - workspace: - clean: all - steps: - - template: templates\download.yaml - - bash: | - #!/bin/bash - green="\e[1;32m" ; reset="\e[0m" ; boldred="\e[1;31m" ; cyan="\e[1;36m" - - echo "##vso[build.updatebuildnumber]Removing the SAP Workload zone defined in $(workload_zone_folder)" - - echo -e "$green--- Validations ---$reset" - HOME_CONFIG=${CONFIG_REPO_PATH} - cd $HOME_CONFIG; mkdir -p .sap_deployment_automation - - if [ ! -f LANDSCAPE/$(workload_zone_folder)/$(workload_zone_configuration_file) ]; then - echo -e "$boldred--- $(workload_zone_configuration_file) was not found ---$reset" - echo "##vso[task.logissue type=error]File $(workload_zone_configuration_file) was not found." - exit 2 - fi - - if [ -z $WL_ARM_SUBSCRIPTION_ID ]; then - echo "##vso[task.logissue type=error]Variable ARM_SUBSCRIPTION_ID was not defined." - exit 2 - fi - - if [ -z $WL_ARM_CLIENT_ID ]; then - echo "##vso[task.logissue type=error]Variable ARM_CLIENT_ID was not defined." - exit 2 - fi - - if [ -z $WL_ARM_CLIENT_SECRET ]; then - echo "##vso[task.logissue type=error]Variable ARM_CLIENT_SECRET was not defined." - exit 2 - fi - - if [ -z $WL_ARM_TENANT_ID ]; then - echo "##vso[task.logissue type=error]Variable ARM_TENANT_ID was not defined." - exit 2 - fi - - # Check if running on deployer - if [[ ! -f /etc/profile.d/deploy_server.sh ]]; then - echo -e "$green--- Install dos2unix ---$reset" - sudo apt-get -qq install dos2unix - - echo -e "$green--- Install terraform ---$reset" - - wget -q $(tf_url) - return_code=$? - if [ 0 != $return_code ]; then - echo "##vso[task.logissue type=error]Unable to download Terraform version $(tf_version)." - exit 2 - fi - unzip -qq terraform_$(tf_version)_linux_amd64.zip ; sudo mv terraform /bin/ - rm -f terraform_$(tf_version)_linux_amd64.zip - else - echo "sourcing /etc/profile.d/deploy_server.sh" - source /etc/profile.d/deploy_server.sh - fi - - echo -e "$green--- Configure devops CLI extension ---$reset" - - az config set extension.use_dynamic_install=yes_without_prompt --output none - - az devops configure --defaults organization=$(System.CollectionUri) project='$(System.TeamProject)' --output none - - export VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(variable_group)'].id | [0]") - if [ -z ${VARIABLE_GROUP_ID} ]; then - echo "##vso[task.logissue type=error]Variable group $(variable_group) could not be found." - exit 2 - fi - export PARENT_VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(parent_variable_group)'].id | [0]"); echo PARENT_VARIABLE_GROUP_ID $PARENT_VARIABLE_GROUP_ID - if [ -z ${PARENT_VARIABLE_GROUP_ID} ]; then - echo "##vso[task.logissue type=error]Variable group $(parent_variable_group) could not be found." - exit 2 - fi - - echo -e "$green--- Convert config file to UX format ---$reset" - dos2unix -q LANDSCAPE/$(workload_zone_folder)/$(workload_zone_configuration_file) - echo -e "$green--- Read details ---$reset" - - ENVIRONMENT=$(grep "^environment" LANDSCAPE/$(workload_zone_folder)/$(workload_zone_configuration_file) | awk -F'=' '{print $2}' | xargs) - LOCATION=$(grep "^location" LANDSCAPE/$(workload_zone_folder)/$(workload_zone_configuration_file) | awk -F'=' '{print $2}' | xargs | tr 'A-Z' 'a-z') - NETWORK=$(grep "^network_logical_name" LANDSCAPE/$(workload_zone_folder)/$(workload_zone_configuration_file) | awk -F'=' '{print $2}' | xargs) - - workload_environment_file_name=$HOME/.sap_deployment_automation/$ENVIRONMENT$LOCATION_CODE$NETWORK; - - ENVIRONMENT_IN_FILENAME=$(echo $(workload_zone_folder) | awk -F'-' '{print $1}' | xargs ) - LOCATION_CODE=$(echo $(workload_zone_folder) | awk -F'-' '{print $2}' | xargs ) - case "$LOCATION_CODE" in - "AUCE") LOCATION_IN_FILENAME="australiacentral" ;; - "AUC2") LOCATION_IN_FILENAME="australiacentral2" ;; - "AUEA") LOCATION_IN_FILENAME="australiaeast" ;; - "AUSE") LOCATION_IN_FILENAME="australiasoutheast" ;; - "BRSO") LOCATION_IN_FILENAME="brazilsouth" ;; - "BRSE") LOCATION_IN_FILENAME="brazilsoutheast" ;; - "BRUS") LOCATION_IN_FILENAME="brazilus" ;; - "CACE") LOCATION_IN_FILENAME="canadacentral" ;; - "CAEA") LOCATION_IN_FILENAME="canadaeast" ;; - "CEIN") LOCATION_IN_FILENAME="centralindia" ;; - "CEUS") LOCATION_IN_FILENAME="centralus" ;; - "CEUA") LOCATION_IN_FILENAME="centraluseuap" ;; - "EAAS") LOCATION_IN_FILENAME="eastasia" ;; - "EAUS") LOCATION_IN_FILENAME="eastus" ;; - "EUSA") LOCATION_IN_FILENAME="eastus2euap" ;; - "EUS2") LOCATION_IN_FILENAME="eastus2" ;; - "EUSG") LOCATION_IN_FILENAME="eastusstg" ;; - "FRCE") LOCATION_IN_FILENAME="francecentral" ;; - "FRSO") LOCATION_IN_FILENAME="francesouth" ;; - "GENO") LOCATION_IN_FILENAME="germanynorth" ;; - "GEWE") LOCATION_IN_FILENAME="germanywest" ;; - "GEWC") LOCATION_IN_FILENAME="germanywestcentral" ;; - "ISCE") LOCATION_IN_FILENAME="israelcentral" ;; - "ITNO") LOCATION_IN_FILENAME="italynorth" ;; - "JAEA") LOCATION_IN_FILENAME="japaneast" ;; - "JAWE") LOCATION_IN_FILENAME="japanwest" ;; - "JINC") LOCATION_IN_FILENAME="jioindiacentral" ;; - "JINW") LOCATION_IN_FILENAME="jioindiawest" ;; - "KOCE") LOCATION_IN_FILENAME="koreacentral" ;; - "KOSO") LOCATION_IN_FILENAME="koreasouth" ;; - "NCUS") LOCATION_IN_FILENAME="northcentralus" ;; - "NOEU") LOCATION_IN_FILENAME="northeurope" ;; - "NOEA") LOCATION_IN_FILENAME="norwayeast" ;; - "NOWE") LOCATION_IN_FILENAME="norwaywest" ;; - "PLCE") LOCATION_IN_FILENAME="polandcentral" ;; - "QACE") LOCATION_IN_FILENAME="qatarcentral" ;; - "SANO") LOCATION_IN_FILENAME="southafricanorth" ;; - "SAWE") LOCATION_IN_FILENAME="southafricawest" ;; - "SCUS") LOCATION_IN_FILENAME="southcentralus" ;; - "SCUG") LOCATION_IN_FILENAME="southcentralusstg" ;; - "SOEA") LOCATION_IN_FILENAME="southeastasia" ;; - "SOIN") LOCATION_IN_FILENAME="southindia" ;; - "SECE") LOCATION_IN_FILENAME="swedencentral" ;; - "SWNO") LOCATION_IN_FILENAME="switzerlandnorth" ;; - "SWWE") LOCATION_IN_FILENAME="switzerlandwest" ;; - "UACE") LOCATION_IN_FILENAME="uaecentral" ;; - "UANO") LOCATION_IN_FILENAME="uaenorth" ;; - "UKSO") LOCATION_IN_FILENAME="uksouth" ;; - "UKWE") LOCATION_IN_FILENAME="ukwest" ;; - "WCUS") LOCATION_IN_FILENAME="westcentralus" ;; - "WEEU") LOCATION_IN_FILENAME="westeurope" ;; - "WEIN") LOCATION_IN_FILENAME="westindia" ;; - "WEUS") LOCATION_IN_FILENAME="westus" ;; - "WUS2") LOCATION_IN_FILENAME="westus2" ;; - "WUS3") LOCATION_IN_FILENAME="westus3" ;; - *) LOCATION_IN_FILENAME="westeurope" ;; - esac - - NETWORK_IN_FILENAME=$(echo $(workload_zone_folder) | awk -F'-' '{print $3}' | xargs ) - workload_environment_file_name=$HOME/.sap_deployment_automation/$ENVIRONMENT$LOCATION_CODE$NETWORK; - echo "Workload Environment file: $workload_environment_file_name" - echo "Environment: ${ENVIRONMENT}" - echo "Location: ${LOCATION}" - echo "Network: ${NETWORK}" - echo "" - - workload_environment_file_name=$HOME/.sap_deployment_automation/$ENVIRONMENT$LOCATION_CODE$NETWORK; - echo "Environment file: $workload_environment_file_name" - echo "Environment(filename): $ENVIRONMENT_IN_FILENAME" - echo "Location(filename): $LOCATION_IN_FILENAME" - echo "Network(filename): $NETWORK_IN_FILENAME" - echo "" - - printf -v tempval '%s id:' $(variable_group) - printf -v val '%-20s' "${tempval}" - echo "$val $VARIABLE_GROUP_ID" - - printf -v tempval '%s id:' $(parent_variable_group) - printf -v val '%-20s' "${tempval}" - echo "$val $PARENT_VARIABLE_GROUP_ID" - - if [ $ENVIRONMENT != $ENVIRONMENT_IN_FILENAME ]; then - echo "##vso[task.logissue type=error]The environment setting in $(workload_zone_configuration_file) '$ENVIRONMENT' does not match the $(workload_zone_configuration_file) file name '$ENVIRONMENT_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-INFRASTRUCTURE" - exit 2 - fi - - if [ $LOCATION != $LOCATION_IN_FILENAME ]; then - echo "##vso[task.logissue type=error]The location setting in $(workload_zone_configuration_file) '$LOCATION' does not match the $(workload_zone_configuration_file) file name '$LOCATION_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-INFRASTRUCTURE" - exit 2 - fi - - if [ $NETWORK != $NETWORK_IN_FILENAME ]; then - echo "##vso[task.logissue type=error]The network_logical_name setting in $(workload_zone_configuration_file) '$NETWORK' does not match the $(workload_zone_configuration_file) file name '$NETWORK_IN_FILENAME-. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-INFRASTRUCTURE" - exit 2 - fi - - if [ -z $(Deployer_Key_Vault) ]; then - if [ ! -f ${workload_environment_file_name} ]; then - echo -e "$boldred--- $workload_environment_file_name was not found ---$reset" - echo "##vso[task.logissue type=error]Workload Zone configuration file ${workload_environment_file_name} was not found." - exit 2 - fi - fi - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "${NETWORK}Workload_Key_Vault.value" --out tsv) - if [ -z ${az_var} ]; then - export workload_key_vault=$(grep -m1 "^workloadkeyvault=" "${workload_environment_file_name}" | awk -F'=' '{print $2}' | xargs) - else - export workload_key_vault="${az_var}" - fi - - if [ -n $(Deployer_Key_Vault) ]; then - export key_vault=$(Deployer_Key_Vault) - else - export key_vault=$(grep -m1 "^keyvault=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) - fi - - az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Subscription.value" --out tsv) - if [ -n "${az_var}" ]; then - STATE_SUBSCRIPTION="${az_var}" - else - STATE_SUBSCRIPTION=$(grep "^STATE_SUBSCRIPTION=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) - fi - - az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Deployer_State_FileName.value" --out tsv) - if [ -n "${az_var}" ]; then - export deployer_tfstate_key="${az_var}" - else - export deployer_tfstate_key=$(grep "^deployer_tfstate_key=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) - fi - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query $NETWORK"Workload_Zone_State_FileName.value" --out tsv) - if [ -n "${az_var}" ]; then - export landscape_tfstate_key="${az_var}" - else - export landscape_tfstate_key=$(grep "^landscape_tfstate_key=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) - fi - - az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Account_Name.value" --out tsv) - if [ -n "${az_var}" ]; then - export REMOTE_STATE_SA="${az_var}" - else - export REMOTE_STATE_SA=$(grep "^REMOTE_STATE_SA=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) - fi - - az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Resource_Group_Name.value" --out tsv) - if [ -n "${az_var}" ]; then - export REMOTE_STATE_RG="${az_var}" - else - export REMOTE_STATE_RG=$(grep "^REMOTE_STATE_RG=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) - fi - - echo "Workload Key Vault: ${workload_key_vault}" - echo "Deployer Key Vault: ${key_vault}" - echo "Terraform state subscription: $STATE_SUBSCRIPTION" - echo "Terraform state account: $REMOTE_STATE_SA" - echo "Terraform state resource group: $REMOTE_STATE_RG" - - echo "System configuration: $(workload_zone_configuration_file)" - - echo "Deployer state file name: $deployer_tfstate_key" - echo "Workload zone state file name: $landscape_tfstate_key" - # Check if running on deployer - if [[ ! -f /etc/profile.d/deploy_server.sh ]]; then - - az login --service-principal --username $WL_ARM_CLIENT_ID --password=$WL_ARM_CLIENT_SECRET --tenant $WL_ARM_TENANT_ID --output none - return_code=$? - if [ 0 != $return_code ]; then - echo -e "$boldred--- Login failed ---$reset" - echo "##vso[task.logissue type=error]az login failed." - exit $return_code - fi - else - echo -e "$green--- Running on deployer ---$reset" - - if [ "${USE_MSI}" != "true" ]; then - - echo -e "$cyan--- Remove using Service Principals ---$reset" - export ARM_CLIENT_ID=$WL_ARM_CLIENT_ID - export ARM_CLIENT_SECRET=$WL_ARM_CLIENT_SECRET - export ARM_TENANT_ID=$WL_ARM_TENANT_ID - export ARM_SUBSCRIPTION_ID=$WL_ARM_SUBSCRIPTION_ID - unset ARM_USE_MSI - - echo "Deployment credentials: Service Principal" - echo "Deployment credentials ID (SPN): $WL_ARM_CLIENT_SECRET" - - az login --service-principal --username "${WL_ARM_CLIENT_ID}" --password="${WL_ARM_CLIENT_SECRET}" --tenant "${WL_ARM_TENANT_ID}" --output none - return_code=$? - if [ 0 != $return_code ]; then - echo -e "$boldred--- Login failed ---$reset" - echo "##vso[task.logissue type=error]az login failed." - exit $return_code - fi - else - echo "Deployment credentials: Managed Identity" - export ARM_USE_MSI=true - export ARM_SUBSCRIPTION_ID=$WL_ARM_SUBSCRIPTION_ID - unset ARM_TENANT_ID - az login --identity --allow-no-subscriptions --output none - fi - fi - - echo -e "$green --- Run the remover script that destroys the SAP workload zone (landscape) ---$reset" - cd "$CONFIG_REPO_PATH/LANDSCAPE/$(workload_zone_folder)" || exit - cd "$CONFIG_REPO_PATH/LANDSCAPE/$(workload_zone_folder)" || exit - - $SAP_AUTOMATION_REPO_PATH/deploy/scripts/remover.sh \ - --parameterfile $(workload_zone_configuration_file) \ - --type sap_landscape \ - --state_subscription ${STATE_SUBSCRIPTION} \ - --storageaccountname "${REMOTE_STATE_SA}" \ - --auto-approve - - return_code=$? - - #stop the pipeline after you have reset the whitelisting on your resources - echo "Return code from remover.sh: $return_code." - if [ 0 != $return_code ]; then - echo "##vso[task.logissue type=error]Return code from remover.sh $return_code." - exit $return_code - fi - - echo -e "$green--- Add & update files in the DevOps Repository ---$reset" - cd $(Build.Repository.LocalPath) - changed=0 - git checkout -q $(Build.SourceBranchName) - git pull - - if [ 0 == $return_code ]; then - - if [ -f "${workload_environment_file_name}" ]; then - git rm -q -f ${workload_environment_file_name} - echo "Removed ${workload_environment_file_name}" - - changed=1 - fi - - if [ -f "${workload_environment_file_name}.md" ]; then - git rm -q --ignore-unmatch -f ${workload_environment_file_name}.md - changed=1 - fi - - if [ -d $(Deployment_Configuration_Path)/LANDSCAPE/$(workload_zone_folder)/.terraform ]; then - git rm -r --ignore-unmatch -f $(Deployment_Configuration_Path)/LANDSCAPE/$(workload_zone_folder)/.terraform - changed=1 - fi - - if [ 1 == $changed ] ; then - git config --global user.email "$(Build.RequestedForEmail)" - git config --global user.name "$(Build.RequestedFor)" - git commit -m "Workload zone ${workload_zone_folder} removal.[skip ci]" - git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" push --set-upstream origin $(Build.SourceBranchName) - fi - - echo -e "$green--- Deleting variables ---$reset" - if [ -n "${VARIABLE_GROUP_ID}" ]; then - echo "Deleting variables" - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query ${NETWORK}"Workload_Key_Vault.value") - if [ -n "${az_var}" ]; then - az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name $NETWORK"Workload_Key_Vault" --yes --only-show-errors - fi - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query $NETWORK"Workload_Zone_State_FileName.value") - if [ -n "${az_var}" ]; then - az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name $NETWORK"Workload_Zone_State_FileName" --yes --only-show-errors - fi - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "${NETWORK}"Workload_Secret_Prefix.value --output table) - if [ -n "${az_var}" ]; then - az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name $NETWORK"Workload_Secret_Prefix" --yes --only-show-errors - fi - - fi - fi - - exit $return_code - displayName: Remove SAP workload_zone - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - WL_ARM_SUBSCRIPTION_ID: $(WL_ARM_SUBSCRIPTION_ID) - WL_ARM_CLIENT_ID: $(WL_ARM_CLIENT_ID) - WL_ARM_CLIENT_SECRET: $(WL_ARM_CLIENT_SECRET) - WL_ARM_TENANT_ID: $(WL_ARM_TENANT_ID) - AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) - SAP_AUTOMATION_REPO_PATH: ${{ parameters.sap_automation_repo_path }} - CONFIG_REPO_PATH: ${{ parameters.config_repo_path }}/$(Deployment_Configuration_Path) - LOGON_USING_SPN: $(Logon_Using_SPN) - USE_MSI: $(Use_MSI) - - failOnStderr: false + - group: SDAF-${{ parameters.workload_environment }} + workspace: + clean: all + steps: + - template: templates\download.yaml + - bash: | + #!/bin/bash + green="\e[1;32m" ; reset="\e[0m" ; boldred="\e[1;31m" ; cyan="\e[1;36m" + + echo "##vso[build.updatebuildnumber]Removing the SAP Workload zone defined in $(workload_zone_folder)" + + echo -e "$green--- Validations ---$reset" + HOME_CONFIG=${CONFIG_REPO_PATH} + cd $HOME_CONFIG; mkdir -p .sap_deployment_automation + + if [ ! -f LANDSCAPE/$(workload_zone_folder)/$(workload_zone_configuration_file) ]; then + echo -e "$boldred--- $(workload_zone_configuration_file) was not found ---$reset" + echo "##vso[task.logissue type=error]File $(workload_zone_configuration_file) was not found." + exit 2 + fi + + if [ -z $WL_ARM_SUBSCRIPTION_ID ]; then + echo "##vso[task.logissue type=error]Variable ARM_SUBSCRIPTION_ID was not defined." + exit 2 + fi + + if [ -z $WL_ARM_CLIENT_ID ]; then + echo "##vso[task.logissue type=error]Variable ARM_CLIENT_ID was not defined." + exit 2 + fi + + if [ -z $WL_ARM_CLIENT_SECRET ]; then + echo "##vso[task.logissue type=error]Variable ARM_CLIENT_SECRET was not defined." + exit 2 + fi + + if [ -z $WL_ARM_TENANT_ID ]; then + echo "##vso[task.logissue type=error]Variable ARM_TENANT_ID was not defined." + exit 2 + fi + + # Check if running on deployer + if [[ ! -f /etc/profile.d/deploy_server.sh ]]; then + echo -e "$green--- Install dos2unix ---$reset" + sudo apt-get -qq install dos2unix + + echo -e "$green--- Install terraform ---$reset" + + wget -q $(tf_url) + return_code=$? + if [ 0 != $return_code ]; then + echo "##vso[task.logissue type=error]Unable to download Terraform version $(tf_version)." + exit 2 + fi + unzip -qq terraform_$(tf_version)_linux_amd64.zip ; sudo mv terraform /bin/ + rm -f terraform_$(tf_version)_linux_amd64.zip + else + echo "sourcing /etc/profile.d/deploy_server.sh" + source /etc/profile.d/deploy_server.sh + fi + + echo -e "$green--- Configure devops CLI extension ---$reset" + + az config set extension.use_dynamic_install=yes_without_prompt --output none + + az devops configure --defaults organization=$(System.CollectionUri) project='$(System.TeamProject)' --output none + + export VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(variable_group)'].id | [0]") + if [ -z ${VARIABLE_GROUP_ID} ]; then + echo "##vso[task.logissue type=error]Variable group $(variable_group) could not be found." + exit 2 + fi + export PARENT_VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(parent_variable_group)'].id | [0]"); echo PARENT_VARIABLE_GROUP_ID $PARENT_VARIABLE_GROUP_ID + if [ -z ${PARENT_VARIABLE_GROUP_ID} ]; then + echo "##vso[task.logissue type=error]Variable group $(parent_variable_group) could not be found." + exit 2 + fi + + echo -e "$green--- Convert config file to UX format ---$reset" + dos2unix -q LANDSCAPE/$(workload_zone_folder)/$(workload_zone_configuration_file) + echo -e "$green--- Read details ---$reset" + + ENVIRONMENT=$(grep "^environment" LANDSCAPE/$(workload_zone_folder)/$(workload_zone_configuration_file) | awk -F'=' '{print $2}' | xargs) + LOCATION=$(grep "^location" LANDSCAPE/$(workload_zone_folder)/$(workload_zone_configuration_file) | awk -F'=' '{print $2}' | xargs | tr 'A-Z' 'a-z') + NETWORK=$(grep "^network_logical_name" LANDSCAPE/$(workload_zone_folder)/$(workload_zone_configuration_file) | awk -F'=' '{print $2}' | xargs) + + workload_environment_file_name=$HOME/.sap_deployment_automation/$ENVIRONMENT$LOCATION_CODE$NETWORK; + + ENVIRONMENT_IN_FILENAME=$(echo $(workload_zone_folder) | awk -F'-' '{print $1}' | xargs ) + LOCATION_CODE=$(echo $(workload_zone_folder) | awk -F'-' '{print $2}' | xargs ) + case "$LOCATION_CODE" in + "AUCE") LOCATION_IN_FILENAME="australiacentral" ;; + "AUC2") LOCATION_IN_FILENAME="australiacentral2" ;; + "AUEA") LOCATION_IN_FILENAME="australiaeast" ;; + "AUSE") LOCATION_IN_FILENAME="australiasoutheast" ;; + "BRSO") LOCATION_IN_FILENAME="brazilsouth" ;; + "BRSE") LOCATION_IN_FILENAME="brazilsoutheast" ;; + "BRUS") LOCATION_IN_FILENAME="brazilus" ;; + "CACE") LOCATION_IN_FILENAME="canadacentral" ;; + "CAEA") LOCATION_IN_FILENAME="canadaeast" ;; + "CEIN") LOCATION_IN_FILENAME="centralindia" ;; + "CEUS") LOCATION_IN_FILENAME="centralus" ;; + "CEUA") LOCATION_IN_FILENAME="centraluseuap" ;; + "EAAS") LOCATION_IN_FILENAME="eastasia" ;; + "EAUS") LOCATION_IN_FILENAME="eastus" ;; + "EUSA") LOCATION_IN_FILENAME="eastus2euap" ;; + "EUS2") LOCATION_IN_FILENAME="eastus2" ;; + "EUSG") LOCATION_IN_FILENAME="eastusstg" ;; + "FRCE") LOCATION_IN_FILENAME="francecentral" ;; + "FRSO") LOCATION_IN_FILENAME="francesouth" ;; + "GENO") LOCATION_IN_FILENAME="germanynorth" ;; + "GEWE") LOCATION_IN_FILENAME="germanywest" ;; + "GEWC") LOCATION_IN_FILENAME="germanywestcentral" ;; + "ISCE") LOCATION_IN_FILENAME="israelcentral" ;; + "ITNO") LOCATION_IN_FILENAME="italynorth" ;; + "JAEA") LOCATION_IN_FILENAME="japaneast" ;; + "JAWE") LOCATION_IN_FILENAME="japanwest" ;; + "JINC") LOCATION_IN_FILENAME="jioindiacentral" ;; + "JINW") LOCATION_IN_FILENAME="jioindiawest" ;; + "KOCE") LOCATION_IN_FILENAME="koreacentral" ;; + "KOSO") LOCATION_IN_FILENAME="koreasouth" ;; + "NCUS") LOCATION_IN_FILENAME="northcentralus" ;; + "NOEU") LOCATION_IN_FILENAME="northeurope" ;; + "NOEA") LOCATION_IN_FILENAME="norwayeast" ;; + "NOWE") LOCATION_IN_FILENAME="norwaywest" ;; + "PLCE") LOCATION_IN_FILENAME="polandcentral" ;; + "QACE") LOCATION_IN_FILENAME="qatarcentral" ;; + "SANO") LOCATION_IN_FILENAME="southafricanorth" ;; + "SAWE") LOCATION_IN_FILENAME="southafricawest" ;; + "SCUS") LOCATION_IN_FILENAME="southcentralus" ;; + "SCUG") LOCATION_IN_FILENAME="southcentralusstg" ;; + "SOEA") LOCATION_IN_FILENAME="southeastasia" ;; + "SOIN") LOCATION_IN_FILENAME="southindia" ;; + "SECE") LOCATION_IN_FILENAME="swedencentral" ;; + "SWNO") LOCATION_IN_FILENAME="switzerlandnorth" ;; + "SWWE") LOCATION_IN_FILENAME="switzerlandwest" ;; + "UACE") LOCATION_IN_FILENAME="uaecentral" ;; + "UANO") LOCATION_IN_FILENAME="uaenorth" ;; + "UKSO") LOCATION_IN_FILENAME="uksouth" ;; + "UKWE") LOCATION_IN_FILENAME="ukwest" ;; + "WCUS") LOCATION_IN_FILENAME="westcentralus" ;; + "WEEU") LOCATION_IN_FILENAME="westeurope" ;; + "WEIN") LOCATION_IN_FILENAME="westindia" ;; + "WEUS") LOCATION_IN_FILENAME="westus" ;; + "WUS2") LOCATION_IN_FILENAME="westus2" ;; + "WUS3") LOCATION_IN_FILENAME="westus3" ;; + *) LOCATION_IN_FILENAME="westeurope" ;; + esac + + NETWORK_IN_FILENAME=$(echo $(workload_zone_folder) | awk -F'-' '{print $3}' | xargs ) + workload_environment_file_name=$HOME/.sap_deployment_automation/$ENVIRONMENT$LOCATION_CODE$NETWORK; + echo "Workload Environment file: $workload_environment_file_name" + echo "Environment: ${ENVIRONMENT}" + echo "Location: ${LOCATION}" + echo "Network: ${NETWORK}" + echo "" + + workload_environment_file_name=$HOME/.sap_deployment_automation/$ENVIRONMENT$LOCATION_CODE$NETWORK; + echo "Environment file: $workload_environment_file_name" + echo "Environment(filename): $ENVIRONMENT_IN_FILENAME" + echo "Location(filename): $LOCATION_IN_FILENAME" + echo "Network(filename): $NETWORK_IN_FILENAME" + echo "" + + printf -v tempval '%s id:' $(variable_group) + printf -v val '%-20s' "${tempval}" + echo "$val $VARIABLE_GROUP_ID" + + printf -v tempval '%s id:' $(parent_variable_group) + printf -v val '%-20s' "${tempval}" + echo "$val $PARENT_VARIABLE_GROUP_ID" + + if [ $ENVIRONMENT != $ENVIRONMENT_IN_FILENAME ]; then + echo "##vso[task.logissue type=error]The environment setting in $(workload_zone_configuration_file) '$ENVIRONMENT' does not match the $(workload_zone_configuration_file) file name '$ENVIRONMENT_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-INFRASTRUCTURE" + exit 2 + fi + + if [ $LOCATION != $LOCATION_IN_FILENAME ]; then + echo "##vso[task.logissue type=error]The location setting in $(workload_zone_configuration_file) '$LOCATION' does not match the $(workload_zone_configuration_file) file name '$LOCATION_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-INFRASTRUCTURE" + exit 2 + fi + + if [ $NETWORK != $NETWORK_IN_FILENAME ]; then + echo "##vso[task.logissue type=error]The network_logical_name setting in $(workload_zone_configuration_file) '$NETWORK' does not match the $(workload_zone_configuration_file) file name '$NETWORK_IN_FILENAME-. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-INFRASTRUCTURE" + exit 2 + fi + + if [ -z $(Deployer_Key_Vault) ]; then + if [ ! -f ${workload_environment_file_name} ]; then + echo -e "$boldred--- $workload_environment_file_name was not found ---$reset" + echo "##vso[task.logissue type=error]Workload Zone configuration file ${workload_environment_file_name} was not found." + exit 2 + fi + fi + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "${NETWORK}Workload_Key_Vault.value" --out tsv) + if [ -z ${az_var} ]; then + export workload_key_vault=$(grep -m1 "^workloadkeyvault=" "${workload_environment_file_name}" | awk -F'=' '{print $2}' | xargs) + else + export workload_key_vault="${az_var}" + fi + + if [ -n $(Deployer_Key_Vault) ]; then + export key_vault=$(Deployer_Key_Vault) + else + export key_vault=$(grep -m1 "^keyvault=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) + fi + + az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Subscription.value" --out tsv) + if [ -n "${az_var}" ]; then + STATE_SUBSCRIPTION="${az_var}" + else + STATE_SUBSCRIPTION=$(grep "^STATE_SUBSCRIPTION=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) + fi + + az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Deployer_State_FileName.value" --out tsv) + if [ -n "${az_var}" ]; then + export deployer_tfstate_key="${az_var}" + else + export deployer_tfstate_key=$(grep "^deployer_tfstate_key=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) + fi + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query $NETWORK"Workload_Zone_State_FileName.value" --out tsv) + if [ -n "${az_var}" ]; then + export landscape_tfstate_key="${az_var}" + else + export landscape_tfstate_key=$(grep "^landscape_tfstate_key=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) + fi + + az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Account_Name.value" --out tsv) + if [ -n "${az_var}" ]; then + export REMOTE_STATE_SA="${az_var}" + else + export REMOTE_STATE_SA=$(grep "^REMOTE_STATE_SA=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) + fi + + az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Resource_Group_Name.value" --out tsv) + if [ -n "${az_var}" ]; then + export REMOTE_STATE_RG="${az_var}" + else + export REMOTE_STATE_RG=$(grep "^REMOTE_STATE_RG=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) + fi + + echo "Workload Key Vault: ${workload_key_vault}" + echo "Deployer Key Vault: ${key_vault}" + echo "Terraform state subscription: $STATE_SUBSCRIPTION" + echo "Terraform state account: $REMOTE_STATE_SA" + echo "Terraform state resource group: $REMOTE_STATE_RG" + + echo "System configuration: $(workload_zone_configuration_file)" + + echo "Deployer state file name: $deployer_tfstate_key" + echo "Workload zone state file name: $landscape_tfstate_key" + # Check if running on deployer + if [[ ! -f /etc/profile.d/deploy_server.sh ]]; then + + az login --service-principal --username $WL_ARM_CLIENT_ID --password=$WL_ARM_CLIENT_SECRET --tenant $WL_ARM_TENANT_ID --output none + return_code=$? + if [ 0 != $return_code ]; then + echo -e "$boldred--- Login failed ---$reset" + echo "##vso[task.logissue type=error]az login failed." + exit $return_code + fi + else + echo -e "$green--- Running on deployer ---$reset" + + if [ "${USE_MSI}" != "true" ]; then + + echo -e "$cyan--- Remove using Service Principals ---$reset" + export ARM_CLIENT_ID=$WL_ARM_CLIENT_ID + export ARM_CLIENT_SECRET=$WL_ARM_CLIENT_SECRET + export ARM_TENANT_ID=$WL_ARM_TENANT_ID + export ARM_SUBSCRIPTION_ID=$WL_ARM_SUBSCRIPTION_ID + unset ARM_USE_MSI + + echo "Deployment credentials: Service Principal" + echo "Deployment credentials ID (SPN): $WL_ARM_CLIENT_SECRET" + + az login --service-principal --username "${WL_ARM_CLIENT_ID}" --password="${WL_ARM_CLIENT_SECRET}" --tenant "${WL_ARM_TENANT_ID}" --output none + return_code=$? + if [ 0 != $return_code ]; then + echo -e "$boldred--- Login failed ---$reset" + echo "##vso[task.logissue type=error]az login failed." + exit $return_code + fi + else + echo "Deployment credentials: Managed Identity" + export ARM_USE_MSI=true + export ARM_SUBSCRIPTION_ID=$WL_ARM_SUBSCRIPTION_ID + unset ARM_TENANT_ID + az login --identity --allow-no-subscriptions --output none + fi + fi + + echo -e "$green --- Run the remover script that destroys the SAP workload zone (landscape) ---$reset" + cd "$CONFIG_REPO_PATH/LANDSCAPE/$(workload_zone_folder)" || exit + cd "$CONFIG_REPO_PATH/LANDSCAPE/$(workload_zone_folder)" || exit + + $SAP_AUTOMATION_REPO_PATH/deploy/scripts/remover.sh \ + --parameterfile $(workload_zone_configuration_file) \ + --type sap_landscape \ + --state_subscription ${STATE_SUBSCRIPTION} \ + --storageaccountname "${REMOTE_STATE_SA}" \ + --auto-approve + + return_code=$? + + #stop the pipeline after you have reset the whitelisting on your resources + echo "Return code from remover.sh: $return_code." + if [ 0 != $return_code ]; then + echo "##vso[task.logissue type=error]Return code from remover.sh $return_code." + exit $return_code + fi + + echo -e "$green--- Add & update files in the DevOps Repository ---$reset" + cd $(Build.Repository.LocalPath) + changed=0 + git checkout -q $(Build.SourceBranchName) + git pull + + if [ 0 == $return_code ]; then + + if [ -f "${workload_environment_file_name}" ]; then + git rm -q -f ${workload_environment_file_name} + echo "Removed ${workload_environment_file_name}" + + changed=1 + fi + + if [ -f "${workload_environment_file_name}.md" ]; then + git rm -q --ignore-unmatch -f ${workload_environment_file_name}.md + changed=1 + fi + + if [ -d $(Deployment_Configuration_Path)/LANDSCAPE/$(workload_zone_folder)/.terraform ]; then + git rm -r --ignore-unmatch -f $(Deployment_Configuration_Path)/LANDSCAPE/$(workload_zone_folder)/.terraform + changed=1 + fi + + if [ 1 == $changed ] ; then + git config --global user.email "$(Build.RequestedForEmail)" + git config --global user.name "$(Build.RequestedFor)" + git commit -m "Workload zone ${workload_zone_folder} removal.[skip ci]" + git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" push --set-upstream origin $(Build.SourceBranchName) + fi + + echo -e "$green--- Deleting variables ---$reset" + if [ -n "${VARIABLE_GROUP_ID}" ]; then + echo "Deleting variables" + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query ${NETWORK}"Workload_Key_Vault.value") + if [ -n "${az_var}" ]; then + az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name $NETWORK"Workload_Key_Vault" --yes --only-show-errors + fi + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query $NETWORK"Workload_Zone_State_FileName.value") + if [ -n "${az_var}" ]; then + az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name $NETWORK"Workload_Zone_State_FileName" --yes --only-show-errors + fi + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "${NETWORK}"Workload_Secret_Prefix.value --output table) + if [ -n "${az_var}" ]; then + az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name $NETWORK"Workload_Secret_Prefix" --yes --only-show-errors + fi + + fi + fi + + exit $return_code + displayName: Remove SAP workload_zone + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + WL_ARM_SUBSCRIPTION_ID: $(WL_ARM_SUBSCRIPTION_ID) + WL_ARM_CLIENT_ID: $(WL_ARM_CLIENT_ID) + WL_ARM_CLIENT_SECRET: $(WL_ARM_CLIENT_SECRET) + WL_ARM_TENANT_ID: $(WL_ARM_TENANT_ID) + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) + SAP_AUTOMATION_REPO_PATH: ${{ parameters.sap_automation_repo_path }} + CONFIG_REPO_PATH: ${{ parameters.config_repo_path }}/$(Deployment_Configuration_Path) + LOGON_USING_SPN: $(Logon_Using_SPN) + USE_MSI: $(Use_MSI) + + failOnStderr: false diff --git a/deploy/pipelines/12-remove-control-plane.yaml b/deploy/pipelines/12-remove-control-plane.yaml index 8e5e5458ba..33443b1dd6 100644 --- a/deploy/pipelines/12-remove-control-plane.yaml +++ b/deploy/pipelines/12-remove-control-plane.yaml @@ -6,783 +6,783 @@ # +------------------------------------4--------------------------------------*/ parameters: - - name: deployer - displayName: "Deployer configuration name, use this format: ENV-LOCA-VNET-INFRASTRUCTURE" - type: string - default: MGMT-WEEU-DEP01-INFRASTRUCTURE - - - name: library - displayName: "Library configuration name, use this format: ENV-LOCA-SAP_LIBRARY" - type: string - default: MGMT-WEEU-SAP_LIBRARY - - - name: deployer_environment - displayName: Deployer Environment name (MGMT, DEV, QA, PRD, ...) - type: string - default: MGMT - - - name: use_deployer - displayName: Run removal on self hosted agent - type: boolean - default: false - - - name: sap_automation_repo_path - displayName: The local path on the agent where the sap_automation repo can be found - type: string - - - name: config_repo_path - displayName: The local path on the agent where the config repo can be found - type: string - - - name: connection_name - displayName: Service Connection Name - type: string +- name: deployer + displayName: "Deployer configuration name, use this format: ENV-LOCA-VNET-INFRASTRUCTURE" + type: string + default: MGMT-WEEU-DEP01-INFRASTRUCTURE + +- name: library + displayName: "Library configuration name, use this format: ENV-LOCA-SAP_LIBRARY" + type: string + default: MGMT-WEEU-SAP_LIBRARY + +- name: deployer_environment + displayName: Deployer Environment name (MGMT, DEV, QA, PRD, ...) + type: string + default: MGMT + +- name: use_deployer + displayName: Run removal on self hosted agent + type: boolean + default: false + +- name: sap_automation_repo_path + displayName: The local path on the agent where the sap_automation repo can be found + type: string + +- name: config_repo_path + displayName: The local path on the agent where the config repo can be found + type: string + +- name: connection_name + displayName: Service Connection Name + type: string stages: - - stage: Remove_control_plane_remote - displayName: "Control plane removal (on agent)" +- stage: Remove_control_plane_remote + displayName: "Control plane removal (on agent)" + variables: + - template: variables/12-remove-control-plane-variables.yaml + parameters: + deployer: ${{ parameters.deployer }} + deployer_environment: ${{ parameters.deployer_environment }} + library: ${{ parameters.library }} + use_deployer: ${{ parameters.use_deployer }} + pool: + name: $(POOL) + jobs: + - job: Remove_control_plane_remote + displayName: "Start control plane removal" variables: - - template: variables/12-remove-control-plane-variables.yaml - parameters: - deployer: ${{ parameters.deployer }} - deployer_environment: ${{ parameters.deployer_environment }} - library: ${{ parameters.library }} - use_deployer: ${{ parameters.use_deployer }} - pool: - name: $(POOL) - jobs: - - job: Remove_control_plane_remote - displayName: "Start control plane removal" - variables: - - group: SDAF-${{ parameters.deployer_environment }} - workspace: - clean: all - steps: - - template: templates\download.yaml - - task: PostBuildCleanup@4 - - bash: | - #!/bin/bash - # Treat unset variables as an error when substituting. - set -u - - echo "##vso[build.updatebuildnumber]Removing the control plane defined in $(deployer_folder) $(library_folder)" - green="\e[1;32m" ; reset="\e[0m" ; boldred="\e[1;31m" ; cyan="\e[1;36m" - - # echo -e "$green--- Checkout $(Build.SourceBranchName) ---$reset" - # git fetch -q --all - # git checkout -q $(Build.SourceBranchName) - - echo -e "$green--- Update .sap_deployment_automation/config as DEPLOYMENT_REPO_PATH can change on devops agent ---$reset" - DEPLOYMENT_REPO_PATH=$(Build.Repository.LocalPath) - export HOME=$(Build.Repository.LocalPath)/$(Deployment_Configuration_Path) - cd $HOME; mkdir -p .sap_deployment_automation - echo DEPLOYMENT_REPO_PATH=$DEPLOYMENT_REPO_PATH > .sap_deployment_automation/config - - echo -e "$green--- Configure devops CLI extension ---$reset" - az config set extension.use_dynamic_install=yes_without_prompt --only-show-errors - az config set extension.dynamic_install_allow_preview=true --only-show-errors - - az devops configure --defaults organization=$(System.CollectionUri) project='$(System.TeamProject)' --output none - - export VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(parent_variable_group)'].id | [0]") - - if [ -z ${VARIABLE_GROUP_ID} ]; then - echo "##vso[task.logissue type=error]Variable group $(parent_variable_group) could not be found." - exit 2 - fi - - if [ -z $ARM_SUBSCRIPTION_ID ]; then - echo "##vso[task.logissue type=error]Variable ARM_SUBSCRIPTION_ID was not defined." - exit 2 - fi - - if [ $USE_MSI != "true" ]; then - if [ -z $ARM_CLIENT_ID ]; then - echo "##vso[task.logissue type=error]Variable ARM_CLIENT_ID was not defined." - exit 2 - fi - - if [ -z $ARM_CLIENT_SECRET ]; then - echo "##vso[task.logissue type=error]Variable ARM_CLIENT_SECRET was not defined." - exit 2 - fi - - if [ -z $ARM_TENANT_ID ]; then - echo "##vso[task.logissue type=error]Variable ARM_TENANT_ID was not defined." - exit 2 - fi - fi - - if [[ ! -f /etc/profile.d/deploy_server.sh ]]; then - echo -e "$green --- Install dos2unix ---$reset" - sudo apt-get -qq install dos2unix - - echo -e "$green --- Install terraform ---$reset" - - wget -q $(tf_url) - return_code=$? - if [ 0 != $return_code ]; then - echo "##vso[task.logissue type=error]Unable to download Terraform version $(tf_version)." - exit 2 - fi - unzip -qq terraform_$(tf_version)_linux_amd64.zip ; sudo mv terraform /bin/ - rm -f terraform_$(tf_version)_linux_amd64.zip - fi - if [ $USE_MSI != "true" ]; then - echo -e "$cyan--- Remove using Service Principals ---$reset" - unset ARM_USE_MSI - az login --service-principal --username $ARM_CLIENT_ID --password=$ARM_CLIENT_SECRET --tenant $ARM_TENANT_ID --output none - return_code=$? - if [ 0 != $return_code ]; then - echo -e "$boldred--- Login failed ---$reset" - echo "##vso[task.logissue type=error]az login failed." - exit $return_code - fi - else - echo -e "$cyan--- Remove using Managed Identity ---$reset" - source /etc/profile.d/deploy_server.sh - export ARM_SUBSCRIPTION_ID=$ARM_SUBSCRIPTION_ID - export ARM_USE_MSI=true - unset ARM_CLIENT_ID - unset ARM_TENANT_ID - fi - - echo -e "$green--- Convert config files to UX format ---$reset" - dos2unix -q $CONFIG_REPO_PATH/DEPLOYER/$(deployer_folder)/$(deployer_configuration_file) - dos2unix -q $CONFIG_REPO_PATH/LIBRARY/$(library_folder)/$(library_configuration_file) - - echo -e "$green--- Environment information ---$reset" - - ENVIRONMENT=$(grep "^environment" $CONFIG_REPO_PATH/DEPLOYER/$(deployer_folder)/$(deployer_configuration_file) | awk -F'=' '{print $2}' | xargs) - LOCATION=$(grep "^location" $CONFIG_REPO_PATH/DEPLOYER/$(deployer_folder)/$(deployer_configuration_file) | awk -F'=' '{print $2}' | xargs | tr 'A-Z' 'a-z') - - ENVIRONMENT_IN_FILENAME=$(echo $(deployer_folder) | awk -F'-' '{print $1}' | xargs ) - LOCATION_CODE=$(echo $(deployer_folder) | awk -F'-' '{print $2}' | xargs ) - case "$LOCATION_CODE" in - "AUCE") LOCATION_IN_FILENAME="australiacentral" ;; - "AUC2") LOCATION_IN_FILENAME="australiacentral2" ;; - "AUEA") LOCATION_IN_FILENAME="australiaeast" ;; - "AUSE") LOCATION_IN_FILENAME="australiasoutheast" ;; - "BRSO") LOCATION_IN_FILENAME="brazilsouth" ;; - "BRSE") LOCATION_IN_FILENAME="brazilsoutheast" ;; - "BRUS") LOCATION_IN_FILENAME="brazilus" ;; - "CACE") LOCATION_IN_FILENAME="canadacentral" ;; - "CAEA") LOCATION_IN_FILENAME="canadaeast" ;; - "CEIN") LOCATION_IN_FILENAME="centralindia" ;; - "CEUS") LOCATION_IN_FILENAME="centralus" ;; - "CEUA") LOCATION_IN_FILENAME="centraluseuap" ;; - "EAAS") LOCATION_IN_FILENAME="eastasia" ;; - "EAUS") LOCATION_IN_FILENAME="eastus" ;; - "EUSA") LOCATION_IN_FILENAME="eastus2euap" ;; - "EUS2") LOCATION_IN_FILENAME="eastus2" ;; - "EUSG") LOCATION_IN_FILENAME="eastusstg" ;; - "FRCE") LOCATION_IN_FILENAME="francecentral" ;; - "FRSO") LOCATION_IN_FILENAME="francesouth" ;; - "GENO") LOCATION_IN_FILENAME="germanynorth" ;; - "GEWE") LOCATION_IN_FILENAME="germanywest" ;; - "GEWC") LOCATION_IN_FILENAME="germanywestcentral" ;; - "ISCE") LOCATION_IN_FILENAME="israelcentral" ;; - "ITNO") LOCATION_IN_FILENAME="italynorth" ;; - "JAEA") LOCATION_IN_FILENAME="japaneast" ;; - "JAWE") LOCATION_IN_FILENAME="japanwest" ;; - "JINC") LOCATION_IN_FILENAME="jioindiacentral" ;; - "JINW") LOCATION_IN_FILENAME="jioindiawest" ;; - "KOCE") LOCATION_IN_FILENAME="koreacentral" ;; - "KOSO") LOCATION_IN_FILENAME="koreasouth" ;; - "NCUS") LOCATION_IN_FILENAME="northcentralus" ;; - "NOEU") LOCATION_IN_FILENAME="northeurope" ;; - "NOEA") LOCATION_IN_FILENAME="norwayeast" ;; - "NOWE") LOCATION_IN_FILENAME="norwaywest" ;; - "PLCE") LOCATION_IN_FILENAME="polandcentral" ;; - "QACE") LOCATION_IN_FILENAME="qatarcentral" ;; - "SANO") LOCATION_IN_FILENAME="southafricanorth" ;; - "SAWE") LOCATION_IN_FILENAME="southafricawest" ;; - "SCUS") LOCATION_IN_FILENAME="southcentralus" ;; - "SCUG") LOCATION_IN_FILENAME="southcentralusstg" ;; - "SOEA") LOCATION_IN_FILENAME="southeastasia" ;; - "SOIN") LOCATION_IN_FILENAME="southindia" ;; - "SECE") LOCATION_IN_FILENAME="swedencentral" ;; - "SWNO") LOCATION_IN_FILENAME="switzerlandnorth" ;; - "SWWE") LOCATION_IN_FILENAME="switzerlandwest" ;; - "UACE") LOCATION_IN_FILENAME="uaecentral" ;; - "UANO") LOCATION_IN_FILENAME="uaenorth" ;; - "UKSO") LOCATION_IN_FILENAME="uksouth" ;; - "UKWE") LOCATION_IN_FILENAME="ukwest" ;; - "WCUS") LOCATION_IN_FILENAME="westcentralus" ;; - "WEEU") LOCATION_IN_FILENAME="westeurope" ;; - "WEIN") LOCATION_IN_FILENAME="westindia" ;; - "WEUS") LOCATION_IN_FILENAME="westus" ;; - "WUS2") LOCATION_IN_FILENAME="westus2" ;; - "WUS3") LOCATION_IN_FILENAME="westus3" ;; - *) LOCATION_IN_FILENAME="westeurope" ;; - esac - - echo "Environment: ${ENVIRONMENT}" - echo "Location: ${LOCATION}" - echo "Environment(filename): $ENVIRONMENT_IN_FILENAME" - echo "Location(filename): $LOCATION_IN_FILENAME" - echo "" - - - if [ $ENVIRONMENT != $ENVIRONMENT_IN_FILENAME ]; then - echo "##vso[task.logissue type=error]The environment setting in $(workload_zone_configuration_file) '$ENVIRONMENT' does not match the $(workload_zone_configuration_file) file name '$ENVIRONMENT_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-INFRASTRUCTURE" - exit 2 - fi - - if [ $LOCATION != $LOCATION_IN_FILENAME ]; then - echo "##vso[task.logissue type=error]The location setting in $(workload_zone_configuration_file) '$LOCATION' does not match the $(workload_zone_configuration_file) file name '$LOCATION_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-INFRASTRUCTURE" - exit 2 + - group: SDAF-${{ parameters.deployer_environment }} + workspace: + clean: all + steps: + - template: templates\download.yaml + - task: PostBuildCleanup@4 + - bash: | + #!/bin/bash + # Treat unset variables as an error when substituting. + set -u + + echo "##vso[build.updatebuildnumber]Removing the control plane defined in $(deployer_folder) $(library_folder)" + green="\e[1;32m" ; reset="\e[0m" ; boldred="\e[1;31m" ; cyan="\e[1;36m" + + # echo -e "$green--- Checkout $(Build.SourceBranchName) ---$reset" + # git fetch -q --all + # git checkout -q $(Build.SourceBranchName) + + echo -e "$green--- Update .sap_deployment_automation/config as DEPLOYMENT_REPO_PATH can change on devops agent ---$reset" + DEPLOYMENT_REPO_PATH=$(Build.Repository.LocalPath) + export HOME=$(Build.Repository.LocalPath)/$(Deployment_Configuration_Path) + cd $HOME; mkdir -p .sap_deployment_automation + echo DEPLOYMENT_REPO_PATH=$DEPLOYMENT_REPO_PATH > .sap_deployment_automation/config + + echo -e "$green--- Configure devops CLI extension ---$reset" + az config set extension.use_dynamic_install=yes_without_prompt --only-show-errors + az config set extension.dynamic_install_allow_preview=true --only-show-errors + + az devops configure --defaults organization=$(System.CollectionUri) project='$(System.TeamProject)' --output none + + export VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(parent_variable_group)'].id | [0]") + + if [ -z ${VARIABLE_GROUP_ID} ]; then + echo "##vso[task.logissue type=error]Variable group $(parent_variable_group) could not be found." + exit 2 + fi + + if [ -z $ARM_SUBSCRIPTION_ID ]; then + echo "##vso[task.logissue type=error]Variable ARM_SUBSCRIPTION_ID was not defined." + exit 2 + fi + + if [ $USE_MSI != "true" ]; then + if [ -z $ARM_CLIENT_ID ]; then + echo "##vso[task.logissue type=error]Variable ARM_CLIENT_ID was not defined." + exit 2 + fi + + if [ -z $ARM_CLIENT_SECRET ]; then + echo "##vso[task.logissue type=error]Variable ARM_CLIENT_SECRET was not defined." + exit 2 + fi + + if [ -z $ARM_TENANT_ID ]; then + echo "##vso[task.logissue type=error]Variable ARM_TENANT_ID was not defined." + exit 2 + fi + fi + + if [[ ! -f /etc/profile.d/deploy_server.sh ]]; then + echo -e "$green --- Install dos2unix ---$reset" + sudo apt-get -qq install dos2unix + + echo -e "$green --- Install terraform ---$reset" + + wget -q $(tf_url) + return_code=$? + if [ 0 != $return_code ]; then + echo "##vso[task.logissue type=error]Unable to download Terraform version $(tf_version)." + exit 2 + fi + unzip -qq terraform_$(tf_version)_linux_amd64.zip ; sudo mv terraform /bin/ + rm -f terraform_$(tf_version)_linux_amd64.zip + fi + if [ $USE_MSI != "true" ]; then + echo -e "$cyan--- Remove using Service Principals ---$reset" + unset ARM_USE_MSI + az login --service-principal --username $ARM_CLIENT_ID --password=$ARM_CLIENT_SECRET --tenant $ARM_TENANT_ID --output none + return_code=$? + if [ 0 != $return_code ]; then + echo -e "$boldred--- Login failed ---$reset" + echo "##vso[task.logissue type=error]az login failed." + exit $return_code + fi + else + echo -e "$cyan--- Remove using Managed Identity ---$reset" + source /etc/profile.d/deploy_server.sh + export ARM_SUBSCRIPTION_ID=$ARM_SUBSCRIPTION_ID + export ARM_USE_MSI=true + unset ARM_CLIENT_ID + unset ARM_TENANT_ID + fi + + echo -e "$green--- Convert config files to UX format ---$reset" + dos2unix -q $CONFIG_REPO_PATH/DEPLOYER/$(deployer_folder)/$(deployer_configuration_file) + dos2unix -q $CONFIG_REPO_PATH/LIBRARY/$(library_folder)/$(library_configuration_file) + + echo -e "$green--- Environment information ---$reset" + + ENVIRONMENT=$(grep "^environment" $CONFIG_REPO_PATH/DEPLOYER/$(deployer_folder)/$(deployer_configuration_file) | awk -F'=' '{print $2}' | xargs) + LOCATION=$(grep "^location" $CONFIG_REPO_PATH/DEPLOYER/$(deployer_folder)/$(deployer_configuration_file) | awk -F'=' '{print $2}' | xargs | tr 'A-Z' 'a-z') + + ENVIRONMENT_IN_FILENAME=$(echo $(deployer_folder) | awk -F'-' '{print $1}' | xargs ) + LOCATION_CODE=$(echo $(deployer_folder) | awk -F'-' '{print $2}' | xargs ) + case "$LOCATION_CODE" in + "AUCE") LOCATION_IN_FILENAME="australiacentral" ;; + "AUC2") LOCATION_IN_FILENAME="australiacentral2" ;; + "AUEA") LOCATION_IN_FILENAME="australiaeast" ;; + "AUSE") LOCATION_IN_FILENAME="australiasoutheast" ;; + "BRSO") LOCATION_IN_FILENAME="brazilsouth" ;; + "BRSE") LOCATION_IN_FILENAME="brazilsoutheast" ;; + "BRUS") LOCATION_IN_FILENAME="brazilus" ;; + "CACE") LOCATION_IN_FILENAME="canadacentral" ;; + "CAEA") LOCATION_IN_FILENAME="canadaeast" ;; + "CEIN") LOCATION_IN_FILENAME="centralindia" ;; + "CEUS") LOCATION_IN_FILENAME="centralus" ;; + "CEUA") LOCATION_IN_FILENAME="centraluseuap" ;; + "EAAS") LOCATION_IN_FILENAME="eastasia" ;; + "EAUS") LOCATION_IN_FILENAME="eastus" ;; + "EUSA") LOCATION_IN_FILENAME="eastus2euap" ;; + "EUS2") LOCATION_IN_FILENAME="eastus2" ;; + "EUSG") LOCATION_IN_FILENAME="eastusstg" ;; + "FRCE") LOCATION_IN_FILENAME="francecentral" ;; + "FRSO") LOCATION_IN_FILENAME="francesouth" ;; + "GENO") LOCATION_IN_FILENAME="germanynorth" ;; + "GEWE") LOCATION_IN_FILENAME="germanywest" ;; + "GEWC") LOCATION_IN_FILENAME="germanywestcentral" ;; + "ISCE") LOCATION_IN_FILENAME="israelcentral" ;; + "ITNO") LOCATION_IN_FILENAME="italynorth" ;; + "JAEA") LOCATION_IN_FILENAME="japaneast" ;; + "JAWE") LOCATION_IN_FILENAME="japanwest" ;; + "JINC") LOCATION_IN_FILENAME="jioindiacentral" ;; + "JINW") LOCATION_IN_FILENAME="jioindiawest" ;; + "KOCE") LOCATION_IN_FILENAME="koreacentral" ;; + "KOSO") LOCATION_IN_FILENAME="koreasouth" ;; + "NCUS") LOCATION_IN_FILENAME="northcentralus" ;; + "NOEU") LOCATION_IN_FILENAME="northeurope" ;; + "NOEA") LOCATION_IN_FILENAME="norwayeast" ;; + "NOWE") LOCATION_IN_FILENAME="norwaywest" ;; + "PLCE") LOCATION_IN_FILENAME="polandcentral" ;; + "QACE") LOCATION_IN_FILENAME="qatarcentral" ;; + "SANO") LOCATION_IN_FILENAME="southafricanorth" ;; + "SAWE") LOCATION_IN_FILENAME="southafricawest" ;; + "SCUS") LOCATION_IN_FILENAME="southcentralus" ;; + "SCUG") LOCATION_IN_FILENAME="southcentralusstg" ;; + "SOEA") LOCATION_IN_FILENAME="southeastasia" ;; + "SOIN") LOCATION_IN_FILENAME="southindia" ;; + "SECE") LOCATION_IN_FILENAME="swedencentral" ;; + "SWNO") LOCATION_IN_FILENAME="switzerlandnorth" ;; + "SWWE") LOCATION_IN_FILENAME="switzerlandwest" ;; + "UACE") LOCATION_IN_FILENAME="uaecentral" ;; + "UANO") LOCATION_IN_FILENAME="uaenorth" ;; + "UKSO") LOCATION_IN_FILENAME="uksouth" ;; + "UKWE") LOCATION_IN_FILENAME="ukwest" ;; + "WCUS") LOCATION_IN_FILENAME="westcentralus" ;; + "WEEU") LOCATION_IN_FILENAME="westeurope" ;; + "WEIN") LOCATION_IN_FILENAME="westindia" ;; + "WEUS") LOCATION_IN_FILENAME="westus" ;; + "WUS2") LOCATION_IN_FILENAME="westus2" ;; + "WUS3") LOCATION_IN_FILENAME="westus3" ;; + *) LOCATION_IN_FILENAME="westeurope" ;; + esac + + echo "Environment: ${ENVIRONMENT}" + echo "Location: ${LOCATION}" + echo "Environment(filename): $ENVIRONMENT_IN_FILENAME" + echo "Location(filename): $LOCATION_IN_FILENAME" + echo "" + + + if [ $ENVIRONMENT != $ENVIRONMENT_IN_FILENAME ]; then + echo "##vso[task.logissue type=error]The environment setting in $(workload_zone_configuration_file) '$ENVIRONMENT' does not match the $(workload_zone_configuration_file) file name '$ENVIRONMENT_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-INFRASTRUCTURE" + exit 2 + fi + + if [ $LOCATION != $LOCATION_IN_FILENAME ]; then + echo "##vso[task.logissue type=error]The location setting in $(workload_zone_configuration_file) '$LOCATION' does not match the $(workload_zone_configuration_file) file name '$LOCATION_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-INFRASTRUCTURE" + exit 2 + fi + + deployer_environment_file_name=$HOME/.sap_deployment_automation/$ENVIRONMENT$LOCATION_CODE; + echo "Environment file: $deployer_environment_file_name" + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Deployer_Key_Vault.value" --out tsv) + if [ -n "${az_var}" ]; then + key_vault="${az_var}" + else + echo "Reading key vault from environment file" + key_vault=$(grep -m "^keyvault=" ${deployer_environment_file_name} | awk -F'=' '{print $2}' | xargs) + fi + + export STATE_SUBSCRIPTION=$ARM_SUBSCRIPTION_ID + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Account_Name.value" --out tsv) + if [ -n "${az_var}" ]; then + REMOTE_STATE_SA="${az_var}" + + else + echo "Reading storage account from environment file" + REMOTE_STATE_SA=$(grep -m1 "^REMOTE_STATE_SA=" ${deployer_environment_file_name} | awk -F'=' '{print $2}' | xargs) + fi + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Resource_Group_Name.value" --out tsv) + if [ -n "${az_var}" ]; then + REMOTE_STATE_RG="${az_var}" + else + REMOTE_STATE_RG=$(grep "^REMOTE_STATE_RG" ${deployer_environment_file_name} | awk -F'=' '{print $2}' | xargs) + fi + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "DEPLOYER_RANDOM_ID_SEED.value" --out tsv) + if [ -n "${az_var}" ]; then + deployer_random_id="${az_var}" + else + if [ -f ${deployer_environment_file_name} ] ; then + deployer_random_id=$(grep "^deployer_random_id=" ${deployer_environment_file_name} | awk -F'=' '{print $2}' | xargs) + fi + fi + + echo "Terraform state subscription: $STATE_SUBSCRIPTION" + echo "Terraform state rg name: $REMOTE_STATE_RG" + echo "Terraform state account: $REMOTE_STATE_SA" + echo "Deployer Key Vault: ${key_vault}" + + if [ -f ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder)/state.zip ]; then + pass=$(echo $DEPLOYER_RANDOM_ID_SEED | sed 's/-//g') + unzip -qq -o -P "${pass}" ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder)/state.zip -d ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder) + fi + + if [ -f ${CONFIG_REPO_PATH}/DEPLOYER/$(deployer_folder)/state.zip ]; then + pass=$(echo $DEPLOYER_RANDOM_ID_SEED | sed 's/-//g') + unzip -qq -o -P "${pass}" ${CONFIG_REPO_PATH}/DEPLOYER/$(deployer_folder)/state.zip -d ${CONFIG_REPO_PATH}/DEPLOYER/$(deployer_folder) + fi + + echo -e "$green--- Running the remove region script that destroys deployer VM and SAP library ---$reset" + + $SAP_AUTOMATION_REPO_PATH/deploy/scripts/remove_controlplane.sh \ + --deployer_parameter_file $CONFIG_REPO_PATH/DEPLOYER/$(deployer_folder)/$(deployer_configuration_file) \ + --library_parameter_file $CONFIG_REPO_PATH/LIBRARY/$(library_folder)/$(library_configuration_file) \ + --storage_account $REMOTE_STATE_SA \ + --subscription ${STATE_SUBSCRIPTION} \ + --resource_group $REMOTE_STATE_RG \ + --ado --auto-approve --keep_agent + + return_code=$? + + echo "Return code from remove_controlplane: $return_code." + + echo -e "$green--- Remove Control Plane Part 1 ---$reset" + cd $CONFIG_REPO_PATH + git checkout -q $(Build.SourceBranchName) + + changed=0 + if [ -f $deployer_environment_file_name ]; then + git add $deployer_environment_file_name + changed=1 + fi + + if [ -f DEPLOYER/$(deployer_folder)/terraform.tfstate ]; then + echo "Compressing the state file." + sudo apt install zip + pass=$(echo $DEPLOYER_RANDOM_ID_SEED | sed 's/-//g') + zip -q -j -P "${pass}" DEPLOYER/$(deployer_folder)/state DEPLOYER/$(deployer_folder)/terraform.tfstate + git add -f DEPLOYER/$(deployer_folder)/state.zip + changed=1 + fi + if [$return_code != 0] ; then + backend=$(grep "local" LIBRARY/$(library_folder)/.terraform/terraform.tfstate || true) + if [ -n "${backend}" ]; then + echo "Local Terraform state" + if [ -f ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder)/terraform.tfstate ]; then + sudo apt install zip + echo "Compressing the library state file" + pass=$(echo $DEPLOYER_RANDOM_ID_SEED | sed 's/-//g') + zip -q -j -P "${pass}" ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder)/state ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder)/terraform.tfstate + git add -f ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder)/state.zip + changed=1 fi - - deployer_environment_file_name=$HOME/.sap_deployment_automation/$ENVIRONMENT$LOCATION_CODE; - echo "Environment file: $deployer_environment_file_name" - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Deployer_Key_Vault.value" --out tsv) - if [ -n "${az_var}" ]; then - key_vault="${az_var}" - else - echo "Reading key vault from environment file" - key_vault=$(grep -m "^keyvault=" ${deployer_environment_file_name} | awk -F'=' '{print $2}' | xargs) + else + echo "Remote Terraform state" + if [ -f ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder)/terraform.tfstate ]; then + git rm -q -f --ignore-unmatch ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder)/terraform.tfstate + added=1 fi - - export STATE_SUBSCRIPTION=$ARM_SUBSCRIPTION_ID - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Account_Name.value" --out tsv) - if [ -n "${az_var}" ]; then - REMOTE_STATE_SA="${az_var}" - - else - echo "Reading storage account from environment file" - REMOTE_STATE_SA=$(grep -m1 "^REMOTE_STATE_SA=" ${deployer_environment_file_name} | awk -F'=' '{print $2}' | xargs) + if [ -f ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder)/state.zip ]; then + git rm -q --ignore-unmatch -f ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder)/state.zip + added=1 fi - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Resource_Group_Name.value" --out tsv) - if [ -n "${az_var}" ]; then - REMOTE_STATE_RG="${az_var}" - else - REMOTE_STATE_RG=$(grep "^REMOTE_STATE_RG" ${deployer_environment_file_name} | awk -F'=' '{print $2}' | xargs) + fi + else + if [ -d LIBRARY/$(library_folder)/.terraform ]; then + git rm -q -r --ignore-unmatch LIBRARY/$(library_folder)/.terraform + changed=1 + fi + + if [ -f LIBRARY/$(library_folder)/state.zip ]; then + git rm -q --ignore-unmatch LIBRARY/$(library_folder)/state.zip + changed=1 + fi + + if [ -f LIBRARY/$(library_folder)/backend-config.tfvars ]; then + git rm -q --ignore-unmatch LIBRARY/$(library_folder)/backend-config.tfvars + changed=1 + fi + fi + + if [ -f "DEPLOYER/$(deployer_folder)/.terraform/terraform.tfstate" ]; then + git add -f "DEPLOYER/$(deployer_folder)/.terraform/terraform.tfstate" + changed=1 + fi + + if [ 1 == $changed ]; then + git config --global user.email "$(Build.RequestedForEmail)" + git config --global user.name "$(Build.RequestedFor)" + git commit -m "Control Plane $(deployer_folder) removal step 1[skip ci]" + git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" push --set-upstream origin $(Build.SourceBranchName) + return_code=$? + fi + + exit $return_code + displayName: Remove control plane + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + ARM_SUBSCRIPTION_ID: $(CP_ARM_SUBSCRIPTION_ID) + ARM_CLIENT_ID: $(CP_ARM_CLIENT_ID) + ARM_CLIENT_SECRET: $(CP_ARM_CLIENT_SECRET) + ARM_TENANT_ID: $(CP_ARM_TENANT_ID) + SAP_AUTOMATION_REPO_PATH: ${{ parameters.sap_automation_repo_path }} + CONFIG_REPO_PATH: ${{ parameters.config_repo_path }}/$(Deployment_Configuration_Path) + key_vault: $(Deployer_Key_Vault) + TF_IN_AUTOMATION: true + TF_LOG: $(TF_LOG) + USE_MSI: $(Use_MSI) + DEPLOYER_RANDOM_ID_SEED: $(DEPLOYER_RANDOM_ID_SEED) + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) + failOnStderr: false + +- stage: Remove_control_plane + displayName: "Finalize control plane removal" + variables: + - template: variables/12-remove-control-plane-variables.yaml + parameters: + deployer: ${{ parameters.deployer }} + deployer_environment: ${{ parameters.deployer_environment }} + library: ${{ parameters.library }} + use_deployer: ${{ parameters.use_deployer }} + pool: + name: $(Agent) + dependsOn: + - Remove_control_plane_remote + condition: in(dependencies.Remove_control_plane_remote.result, 'Succeeded', 'Skipped') + jobs: + - job: Remove_control_plane + displayName: "Finalize control plane removal" + variables: + - group: SDAF-${{ parameters.deployer_environment }} + workspace: + clean: all + steps: + - template: templates\download.yaml + parameters: + getLatestFromBranch: true + - task: PostBuildCleanup@4 + - task: AzureCLI@2 + continueOnError: false + inputs: + azureSubscription: ${{parameters.connection_name}} + scriptType: bash + scriptLocation: inlineScript + addSpnToEnvironment: true + inlineScript: | + #!/bin/bash + echo "##vso[build.updatebuildnumber]Removing the control plane defined in $(deployer_folder) $(library_folder)" + green="\e[1;32m" ; reset="\e[0m" ; boldred="\e[1;31m" ; cyan="\e[1;36m" + export ARM_USE_MSI=false + if [ $USE_MSI != "true" ]; then + echo -e "$cyan--- Remove using Service Principals ---$reset" + export ARM_CLIENT_ID=$CP_ARM_CLIENT_ID + export ARM_TENANT_ID=$CP_ARM_TENANT_ID + export ARM_CLIENT_SECRET=$CP_ARM_CLIENT_SECRET + else + echo -e "$cyan--- Remove using Managed Identity ---$reset" + export ARM_CLIENT_ID=$servicePrincipalId + export ARM_TENANT_ID=$tenantId + export ARM_CLIENT_SECRET=$servicePrincipalKey + fi + + # Treat unset variables as an error when substituting. + set -ue + + # echo -e "$green--- Checkout $(Build.SourceBranchName) ---$reset" + # git fetch -q --all + # git checkout -q $(Build.SourceBranchName) + + # Check if running on deployer + if [[ ! -f /etc/profile.d/deploy_server.sh ]]; then + echo -e "$green --- Install dos2unix ---$reset" + sudo apt-get -qq install dos2unix + + sudo apt -qq install zip + + echo -e "$green --- Install terraform ---$reset" + + wget -q $(tf_url) + return_code=$? + if [ 0 != $return_code ]; then + echo "##vso[task.logissue type=error]Unable to download Terraform version $(tf_version)." + exit 2 fi - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "DEPLOYER_RANDOM_ID_SEED.value" --out tsv) - if [ -n "${az_var}" ]; then - deployer_random_id="${az_var}" - else - if [ -f ${deployer_environment_file_name} ] ; then - deployer_random_id=$(grep "^deployer_random_id=" ${deployer_environment_file_name} | awk -F'=' '{print $2}' | xargs) - fi + unzip -qq terraform_$(tf_version)_linux_amd64.zip ; sudo mv terraform /bin/ + rm -f terraform_$(tf_version)_linux_amd64.zip + fi + + echo -e "$green--- Update .sap_deployment_automation/config as DEPLOYMENT_REPO_PATH can change on devops agent ---$reset" + DEPLOYMENT_REPO_PATH=$(Build.Repository.LocalPath) + export HOME=$(Build.Repository.LocalPath)/$(Deployment_Configuration_Path) + cd $HOME; mkdir -p .sap_deployment_automation + + echo -e "$green--- Configure devops CLI extension ---$reset" + az config set extension.use_dynamic_install=yes_without_prompt --only-show-errors + + az devops configure --defaults organization=$(System.CollectionUri) project='$(System.TeamProject)' --output none + + export VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(parent_variable_group)'].id | [0]") + + printf -v tempval '%s id:' $(parent_variable_group) + printf -v val '%-20s' "${tempval}" + echo "$val $VARIABLE_GROUP_ID" + + if [ -z ${VARIABLE_GROUP_ID} ]; then + echo "##vso[task.logissue type=error]Variable group $(parent_variable_group) could not be found." + exit 2 + fi + if [ -z $ARM_SUBSCRIPTION_ID ]; then + echo "##vso[task.logissue type=error]Variable ARM_SUBSCRIPTION_ID was not defined." + exit 2 + fi + if [ $USE_MSI != "true" ]; then + + if [ -z $ARM_CLIENT_ID ]; then + echo "##vso[task.logissue type=error]Variable ARM_CLIENT_ID was not defined." + exit 2 + fi + if [ -z $ARM_CLIENT_SECRET ]; then + echo "##vso[task.logissue type=error]Variable ARM_CLIENT_SECRET was not defined." + exit 2 + fi + if [ -z $ARM_TENANT_ID ]; then + echo "##vso[task.logissue type=error]Variable ARM_TENANT_ID was not defined." + exit 2 + fi + else + export ARM_SUBSCRIPTION_ID=$ARM_SUBSCRIPTION_ID + + fi + + echo -e "$green--- Convert config files to UX format ---$reset" + dos2unix -q $CONFIG_REPO_PATH/DEPLOYER/$(deployer_folder)/$(deployer_configuration_file) + dos2unix -q $CONFIG_REPO_PATH/LIBRARY/$(library_folder)/$(library_configuration_file) + + echo -e "$green--- Environment information ---$reset" + + ENVIRONMENT=$(grep "^environment" $CONFIG_REPO_PATH/DEPLOYER/$(deployer_folder)/$(deployer_configuration_file) | awk -F'=' '{print $2}' | xargs) + LOCATION=$(grep "^location" $CONFIG_REPO_PATH/DEPLOYER/$(deployer_folder)/$(deployer_configuration_file) | awk -F'=' '{print $2}' | xargs | tr 'A-Z' 'a-z') + + ENVIRONMENT_IN_FILENAME=$(echo $(deployer_folder) | awk -F'-' '{print $1}' | xargs ) + LOCATION_CODE=$(echo $(deployer_folder) | awk -F'-' '{print $2}' | xargs ) + case "$LOCATION_CODE" in + "AUCE") LOCATION_IN_FILENAME="australiacentral" ;; + "AUC2") LOCATION_IN_FILENAME="australiacentral2" ;; + "AUEA") LOCATION_IN_FILENAME="australiaeast" ;; + "AUSE") LOCATION_IN_FILENAME="australiasoutheast" ;; + "BRSO") LOCATION_IN_FILENAME="brazilsouth" ;; + "BRSE") LOCATION_IN_FILENAME="brazilsoutheast" ;; + "BRUS") LOCATION_IN_FILENAME="brazilus" ;; + "CACE") LOCATION_IN_FILENAME="canadacentral" ;; + "CAEA") LOCATION_IN_FILENAME="canadaeast" ;; + "CEIN") LOCATION_IN_FILENAME="centralindia" ;; + "CEUS") LOCATION_IN_FILENAME="centralus" ;; + "CEUA") LOCATION_IN_FILENAME="centraluseuap" ;; + "EAAS") LOCATION_IN_FILENAME="eastasia" ;; + "EAUS") LOCATION_IN_FILENAME="eastus" ;; + "EUSA") LOCATION_IN_FILENAME="eastus2euap" ;; + "EUS2") LOCATION_IN_FILENAME="eastus2" ;; + "EUSG") LOCATION_IN_FILENAME="eastusstg" ;; + "FRCE") LOCATION_IN_FILENAME="francecentral" ;; + "FRSO") LOCATION_IN_FILENAME="francesouth" ;; + "GENO") LOCATION_IN_FILENAME="germanynorth" ;; + "GEWE") LOCATION_IN_FILENAME="germanywest" ;; + "GEWC") LOCATION_IN_FILENAME="germanywestcentral" ;; + "ISCE") LOCATION_IN_FILENAME="israelcentral" ;; + "ITNO") LOCATION_IN_FILENAME="italynorth" ;; + "JAEA") LOCATION_IN_FILENAME="japaneast" ;; + "JAWE") LOCATION_IN_FILENAME="japanwest" ;; + "JINC") LOCATION_IN_FILENAME="jioindiacentral" ;; + "JINW") LOCATION_IN_FILENAME="jioindiawest" ;; + "KOCE") LOCATION_IN_FILENAME="koreacentral" ;; + "KOSO") LOCATION_IN_FILENAME="koreasouth" ;; + "NCUS") LOCATION_IN_FILENAME="northcentralus" ;; + "NOEU") LOCATION_IN_FILENAME="northeurope" ;; + "NOEA") LOCATION_IN_FILENAME="norwayeast" ;; + "NOWE") LOCATION_IN_FILENAME="norwaywest" ;; + "PLCE") LOCATION_IN_FILENAME="polandcentral" ;; + "QACE") LOCATION_IN_FILENAME="qatarcentral" ;; + "SANO") LOCATION_IN_FILENAME="southafricanorth" ;; + "SAWE") LOCATION_IN_FILENAME="southafricawest" ;; + "SCUS") LOCATION_IN_FILENAME="southcentralus" ;; + "SCUG") LOCATION_IN_FILENAME="southcentralusstg" ;; + "SOEA") LOCATION_IN_FILENAME="southeastasia" ;; + "SOIN") LOCATION_IN_FILENAME="southindia" ;; + "SECE") LOCATION_IN_FILENAME="swedencentral" ;; + "SWNO") LOCATION_IN_FILENAME="switzerlandnorth" ;; + "SWWE") LOCATION_IN_FILENAME="switzerlandwest" ;; + "UACE") LOCATION_IN_FILENAME="uaecentral" ;; + "UANO") LOCATION_IN_FILENAME="uaenorth" ;; + "UKSO") LOCATION_IN_FILENAME="uksouth" ;; + "UKWE") LOCATION_IN_FILENAME="ukwest" ;; + "WCUS") LOCATION_IN_FILENAME="westcentralus" ;; + "WEEU") LOCATION_IN_FILENAME="westeurope" ;; + "WEIN") LOCATION_IN_FILENAME="westindia" ;; + "WEUS") LOCATION_IN_FILENAME="westus" ;; + "WUS2") LOCATION_IN_FILENAME="westus2" ;; + "WUS3") LOCATION_IN_FILENAME="westus3" ;; + *) LOCATION_IN_FILENAME="westeurope" ;; + esac + + echo "Environment: ${ENVIRONMENT}" + echo "Location: ${LOCATION}" + echo "Location code: ${LOCATION_CODE}" + + echo "Environment(filename): $ENVIRONMENT_IN_FILENAME" + echo "Location(filename): $LOCATION_IN_FILENAME" + echo "" + + if [ $ENVIRONMENT != $ENVIRONMENT_IN_FILENAME ]; then + echo "##vso[task.logissue type=error]The environment setting in $(workload_zone_configuration_file) '$ENVIRONMENT' does not match the $(workload_zone_configuration_file) file name '$ENVIRONMENT_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-INFRASTRUCTURE" + exit 2 + fi + + if [ $LOCATION != $LOCATION_IN_FILENAME ]; then + echo "##vso[task.logissue type=error]The location setting in $(workload_zone_configuration_file) '$LOCATION' does not match the $(workload_zone_configuration_file) file name '$LOCATION_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-INFRASTRUCTURE" + exit 2 + fi + + echo -e "$green--- Running the remove region script that destroys deployer VM and SAP library ---$reset" + + deployer_environment_file_name=$HOME/.sap_deployment_automation/$ENVIRONMENT$LOCATION_CODE + echo "Environment file: $deployer_environment_file_name" + + echo -e "$green--- az login ---$reset" + + if [ $USE_MSI != "true" ]; then + echo -e "$cyan--- Remove using Service Principals ---$reset" + + unset ARM_USE_MSI + az login --service-principal --username $ARM_CLIENT_ID --password=$ARM_CLIENT_SECRET --tenant $ARM_TENANT_ID --output none + return_code=$? + if [ 0 != $return_code ]; then + echo -e "$boldred--- Login failed ---$reset" + echo "##vso[task.logissue type=error]az login failed." + exit $return_code + fi + fi + az account set --subscription $ARM_SUBSCRIPTION_ID + + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Deployer_Key_Vault.value" --out tsv) + if [ -n "${az_var}" ]; then + key_vault="${az_var}" + else + echo "Reading key vault from environment file" + key_vault=$(grep -m1 "^keyvault=" ${deployer_environment_file_name} | awk -F'=' '{print $2}' | xargs) + fi + + echo "Deployer Key Vault: $key_vault" + + key_vault_id=$(az resource list --name "${key_vault}" --resource-type Microsoft.KeyVault/vaults --query "[].id | [0]" -o tsv) + if [ -n "${key_vault_id}" ]; then + + if [ "azure pipelines" = "$(this_agent)" ]; then + this_ip=$(curl -s ipinfo.io/ip) >/dev/null 2>&1 + az keyvault network-rule add --name ${key_vault} --ip-address ${this_ip} --only-show-errors --output none + ip_added=1 + fi + fi + + echo -e "$green--- Running the remove_deployer script that destroys deployer VM ---$reset" + if [ -f $CONFIG_REPO_PATH/DEPLOYER/$(deployer_folder)/state.zip ]; then + echo "Unzipping state.zip" + pass=$(echo $DEPLOYER_RANDOM_ID_SEED | sed 's/-//g') + unzip -qq -o -P "${pass}" $CONFIG_REPO_PATH/DEPLOYER/$(deployer_folder)/state.zip -d ${CONFIG_REPO_PATH}/DEPLOYER/$(deployer_folder) + fi + + sudo chmod +x $SAP_AUTOMATION_REPO_PATH/deploy/scripts/remove_deployer.sh + cd $CONFIG_REPO_PATH/DEPLOYER/$(deployer_folder) + + $SAP_AUTOMATION_REPO_PATH/deploy/scripts/remove_deployer.sh --auto-approve \ + --parameterfile $(deployer_configuration_file) + + return_code=$? + + echo "Return code from remove_deployer: $return_code." + if [ 0 != $return_code ]; then + echo "##vso[task.logissue type=error]Return code from remove_deployer $return_code." + fi + + echo -e "$green--- Removing deployment automation configuration from devops repository ---$reset" + + if [ 0 == $return_code ] ; then + cd $CONFIG_REPO_PATH + changed=0 + echo "##vso[build.updatebuildnumber]Removing control plane $(deployer_folder) $(library_folder)" + if [ -f "DEPLOYER/$(deployer_folder)/.terraform/terraform.tfstate" ]; then + git rm -q -f --ignore-unmatch DEPLOYER/$(deployer_folder)/.terraform/terraform.tfstate + changed=1 fi - echo "Terraform state subscription: $STATE_SUBSCRIPTION" - echo "Terraform state rg name: $REMOTE_STATE_RG" - echo "Terraform state account: $REMOTE_STATE_SA" - echo "Deployer Key Vault: ${key_vault}" - if [ -f ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder)/state.zip ]; then - pass=$(echo $DEPLOYER_RANDOM_ID_SEED | sed 's/-//g') - unzip -qq -o -P "${pass}" ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder)/state.zip -d ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder) + if [ -d "DEPLOYER/$(deployer_folder)/.terraform" ]; then + git rm -q -r --ignore-unmatch DEPLOYER/$(deployer_folder)/.terraform + changed=1 fi - if [ -f ${CONFIG_REPO_PATH}/DEPLOYER/$(deployer_folder)/state.zip ]; then - pass=$(echo $DEPLOYER_RANDOM_ID_SEED | sed 's/-//g') - unzip -qq -o -P "${pass}" ${CONFIG_REPO_PATH}/DEPLOYER/$(deployer_folder)/state.zip -d ${CONFIG_REPO_PATH}/DEPLOYER/$(deployer_folder) + if [ -f "DEPLOYER/$(deployer_folder)/state.zip" ]; then + git rm -q -f --ignore-unmatch DEPLOYER/$(deployer_folder)/state.zip + changed=1 fi - echo -e "$green--- Running the remove region script that destroys deployer VM and SAP library ---$reset" - - $SAP_AUTOMATION_REPO_PATH/deploy/scripts/remove_controlplane.sh \ - --deployer_parameter_file $CONFIG_REPO_PATH/DEPLOYER/$(deployer_folder)/$(deployer_configuration_file) \ - --library_parameter_file $CONFIG_REPO_PATH/LIBRARY/$(library_folder)/$(library_configuration_file) \ - --storage_account $REMOTE_STATE_SA \ - --subscription ${STATE_SUBSCRIPTION} \ - --resource_group $REMOTE_STATE_RG \ - --ado --auto-approve --keep_agent - - return_code=$? - - echo "Return code from remove_controlplane: $return_code." - - echo -e "$green--- Remove Control Plane Part 1 ---$reset" - cd $CONFIG_REPO_PATH - git checkout -q $(Build.SourceBranchName) - - changed=0 - if [ -f $deployer_environment_file_name ]; then - git add $deployer_environment_file_name - changed=1 + if [ -d LIBRARY/$(library_folder)/.terraform ]; then + git rm -q -r --ignore-unmatch LIBRARY/$(library_folder)/.terraform + changed=1 fi - if [ -f DEPLOYER/$(deployer_folder)/terraform.tfstate ]; then - echo "Compressing the state file." - sudo apt install zip - pass=$(echo $DEPLOYER_RANDOM_ID_SEED | sed 's/-//g') - zip -q -j -P "${pass}" DEPLOYER/$(deployer_folder)/state DEPLOYER/$(deployer_folder)/terraform.tfstate - git add -f DEPLOYER/$(deployer_folder)/state.zip - changed=1 + if [ -f LIBRARY/$(library_folder)/state.zip ]; then + git rm -q -f --ignore-unmatch LIBRARY/$(library_folder)/state.zip + changed=1 fi - if [$return_code != 0] ; then - backend=$(grep "local" LIBRARY/$(library_folder)/.terraform/terraform.tfstate || true) - if [ -n "${backend}" ]; then - echo "Local Terraform state" - if [ -f ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder)/terraform.tfstate ]; then - sudo apt install zip - echo "Compressing the library state file" - pass=$(echo $DEPLOYER_RANDOM_ID_SEED | sed 's/-//g') - zip -q -j -P "${pass}" ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder)/state ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder)/terraform.tfstate - git add -f ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder)/state.zip - changed=1 - fi - else - echo "Remote Terraform state" - if [ -f ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder)/terraform.tfstate ]; then - git rm -q -f --ignore-unmatch ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder)/terraform.tfstate - added=1 - fi - if [ -f ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder)/state.zip ]; then - git rm -q --ignore-unmatch -f ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder)/state.zip - added=1 - fi - fi - else - if [ -d LIBRARY/$(library_folder)/.terraform ]; then - git rm -q -r --ignore-unmatch LIBRARY/$(library_folder)/.terraform - changed=1 - fi - - if [ -f LIBRARY/$(library_folder)/state.zip ]; then - git rm -q --ignore-unmatch LIBRARY/$(library_folder)/state.zip - changed=1 - fi - if [ -f LIBRARY/$(library_folder)/backend-config.tfvars ]; then - git rm -q --ignore-unmatch LIBRARY/$(library_folder)/backend-config.tfvars - changed=1 - fi + if [ -f .sap_deployment_automation/${ENVIRONMENT}${LOCATION_CODE} ]; then + rm .sap_deployment_automation/${ENVIRONMENT}${LOCATION_CODE} + git rm -q --ignore-unmatch .sap_deployment_automation/${ENVIRONMENT}${LOCATION_CODE} + changed=1 fi - - if [ -f "DEPLOYER/$(deployer_folder)/.terraform/terraform.tfstate" ]; then - git add -f "DEPLOYER/$(deployer_folder)/.terraform/terraform.tfstate" + if [ -f .sap_deployment_automation/${ENVIRONMENT}${LOCATION_CODE}.md ]; then + rm .sap_deployment_automation/${ENVIRONMENT}${LOCATION_CODE}.md + git rm -q --ignore-unmatch .sap_deployment_automation/${ENVIRONMENT}${LOCATION_CODE}.md changed=1 fi - if [ 1 == $changed ]; then - git config --global user.email "$(Build.RequestedForEmail)" - git config --global user.name "$(Build.RequestedFor)" - git commit -m "Control Plane $(deployer_folder) removal step 1[skip ci]" - git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" push --set-upstream origin $(Build.SourceBranchName) - return_code=$? + if [ -f LIBRARY/$(library_folder)/backend-config.tfvars ]; then + git rm -q --ignore-unmatch LIBRARY/$(library_folder)/backend-config.tfvars + changed=1 fi - exit $return_code - displayName: Remove control plane - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - ARM_SUBSCRIPTION_ID: $(CP_ARM_SUBSCRIPTION_ID) - ARM_CLIENT_ID: $(CP_ARM_CLIENT_ID) - ARM_CLIENT_SECRET: $(CP_ARM_CLIENT_SECRET) - ARM_TENANT_ID: $(CP_ARM_TENANT_ID) - SAP_AUTOMATION_REPO_PATH: ${{ parameters.sap_automation_repo_path }} - CONFIG_REPO_PATH: ${{ parameters.config_repo_path }}/$(Deployment_Configuration_Path) - key_vault: $(Deployer_Key_Vault) - TF_IN_AUTOMATION: true - TF_LOG: $(TF_LOG) - USE_MSI: $(Use_MSI) - DEPLOYER_RANDOM_ID_SEED: $(DEPLOYER_RANDOM_ID_SEED) - AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) - failOnStderr: false - - - stage: Remove_control_plane - displayName: "Finalize control plane removal" - variables: - - template: variables/12-remove-control-plane-variables.yaml - parameters: - deployer: ${{ parameters.deployer }} - deployer_environment: ${{ parameters.deployer_environment }} - library: ${{ parameters.library }} - use_deployer: ${{ parameters.use_deployer }} - pool: - name: $(Agent) - dependsOn: - - Remove_control_plane_remote - condition: in(dependencies.Remove_control_plane_remote.result, 'Succeeded', 'Skipped') - jobs: - - job: Remove_control_plane - displayName: "Finalize control plane removal" - variables: - - group: SDAF-${{ parameters.deployer_environment }} - workspace: - clean: all - steps: - - template: templates\download.yaml - parameters: - getLatestFromBranch: true - - task: PostBuildCleanup@4 - - task: AzureCLI@2 - continueOnError: false - inputs: - azureSubscription: ${{parameters.connection_name}} - scriptType: bash - scriptLocation: inlineScript - addSpnToEnvironment: true - inlineScript: | - #!/bin/bash - echo "##vso[build.updatebuildnumber]Removing the control plane defined in $(deployer_folder) $(library_folder)" - green="\e[1;32m" ; reset="\e[0m" ; boldred="\e[1;31m" ; cyan="\e[1;36m" - export ARM_USE_MSI=false - if [ $USE_MSI != "true" ]; then - echo -e "$cyan--- Remove using Service Principals ---$reset" - export ARM_CLIENT_ID=$CP_ARM_CLIENT_ID - export ARM_TENANT_ID=$CP_ARM_TENANT_ID - export ARM_CLIENT_SECRET=$CP_ARM_CLIENT_SECRET - else - echo -e "$cyan--- Remove using Managed Identity ---$reset" - export ARM_CLIENT_ID=$servicePrincipalId - export ARM_TENANT_ID=$tenantId - export ARM_CLIENT_SECRET=$servicePrincipalKey + if [ 1 == $changed ] ; then + git config --global user.email "$(Build.RequestedForEmail)" + git config --global user.name "$(Build.RequestedFor)" + git commit -m "Added updates from devops deployment $(Build.DefinitionName) [skip ci]" + git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" push fi + echo -e "$green--- Deleting variables ---$reset" + if [ ${#VARIABLE_GROUP_ID} != 0 ]; then + echo "Deleting variables" - # Treat unset variables as an error when substituting. - set -ue - - # echo -e "$green--- Checkout $(Build.SourceBranchName) ---$reset" - # git fetch -q --all - # git checkout -q $(Build.SourceBranchName) - - # Check if running on deployer - if [[ ! -f /etc/profile.d/deploy_server.sh ]]; then - echo -e "$green --- Install dos2unix ---$reset" - sudo apt-get -qq install dos2unix - - sudo apt -qq install zip - - echo -e "$green --- Install terraform ---$reset" - - wget -q $(tf_url) - return_code=$? - if [ 0 != $return_code ]; then - echo "##vso[task.logissue type=error]Unable to download Terraform version $(tf_version)." - exit 2 - fi - unzip -qq terraform_$(tf_version)_linux_amd64.zip ; sudo mv terraform /bin/ - rm -f terraform_$(tf_version)_linux_amd64.zip + variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Account_Name.value" ) + if [ ${#variable_value} != 0 ]; then + az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name Terraform_Remote_Storage_Account_Name --yes --only-show-errors fi - echo -e "$green--- Update .sap_deployment_automation/config as DEPLOYMENT_REPO_PATH can change on devops agent ---$reset" - DEPLOYMENT_REPO_PATH=$(Build.Repository.LocalPath) - export HOME=$(Build.Repository.LocalPath)/$(Deployment_Configuration_Path) - cd $HOME; mkdir -p .sap_deployment_automation - - echo -e "$green--- Configure devops CLI extension ---$reset" - az config set extension.use_dynamic_install=yes_without_prompt --only-show-errors - - az devops configure --defaults organization=$(System.CollectionUri) project='$(System.TeamProject)' --output none - - export VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(parent_variable_group)'].id | [0]") - - printf -v tempval '%s id:' $(parent_variable_group) - printf -v val '%-20s' "${tempval}" - echo "$val $VARIABLE_GROUP_ID" - - if [ -z ${VARIABLE_GROUP_ID} ]; then - echo "##vso[task.logissue type=error]Variable group $(parent_variable_group) could not be found." - exit 2 + variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Resource_Group_Name.value" ) + if [ ${#variable_value} != 0 ]; then + az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name Terraform_Remote_Storage_Resource_Group_Name --yes --only-show-errors fi - if [ -z $ARM_SUBSCRIPTION_ID ]; then - echo "##vso[task.logissue type=error]Variable ARM_SUBSCRIPTION_ID was not defined." - exit 2 - fi - if [ $USE_MSI != "true" ]; then - - if [ -z $ARM_CLIENT_ID ]; then - echo "##vso[task.logissue type=error]Variable ARM_CLIENT_ID was not defined." - exit 2 - fi - if [ -z $ARM_CLIENT_SECRET ]; then - echo "##vso[task.logissue type=error]Variable ARM_CLIENT_SECRET was not defined." - exit 2 - fi - if [ -z $ARM_TENANT_ID ]; then - echo "##vso[task.logissue type=error]Variable ARM_TENANT_ID was not defined." - exit 2 - fi - else - export ARM_SUBSCRIPTION_ID=$ARM_SUBSCRIPTION_ID + variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Subscription.value" ) + if [ ${#variable_value} != 0 ]; then + az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name Terraform_Remote_Storage_Subscription --yes --only-show-errors fi - echo -e "$green--- Convert config files to UX format ---$reset" - dos2unix -q $CONFIG_REPO_PATH/DEPLOYER/$(deployer_folder)/$(deployer_configuration_file) - dos2unix -q $CONFIG_REPO_PATH/LIBRARY/$(library_folder)/$(library_configuration_file) - - echo -e "$green--- Environment information ---$reset" - - ENVIRONMENT=$(grep "^environment" $CONFIG_REPO_PATH/DEPLOYER/$(deployer_folder)/$(deployer_configuration_file) | awk -F'=' '{print $2}' | xargs) - LOCATION=$(grep "^location" $CONFIG_REPO_PATH/DEPLOYER/$(deployer_folder)/$(deployer_configuration_file) | awk -F'=' '{print $2}' | xargs | tr 'A-Z' 'a-z') - - ENVIRONMENT_IN_FILENAME=$(echo $(deployer_folder) | awk -F'-' '{print $1}' | xargs ) - LOCATION_CODE=$(echo $(deployer_folder) | awk -F'-' '{print $2}' | xargs ) - case "$LOCATION_CODE" in - "AUCE") LOCATION_IN_FILENAME="australiacentral" ;; - "AUC2") LOCATION_IN_FILENAME="australiacentral2" ;; - "AUEA") LOCATION_IN_FILENAME="australiaeast" ;; - "AUSE") LOCATION_IN_FILENAME="australiasoutheast" ;; - "BRSO") LOCATION_IN_FILENAME="brazilsouth" ;; - "BRSE") LOCATION_IN_FILENAME="brazilsoutheast" ;; - "BRUS") LOCATION_IN_FILENAME="brazilus" ;; - "CACE") LOCATION_IN_FILENAME="canadacentral" ;; - "CAEA") LOCATION_IN_FILENAME="canadaeast" ;; - "CEIN") LOCATION_IN_FILENAME="centralindia" ;; - "CEUS") LOCATION_IN_FILENAME="centralus" ;; - "CEUA") LOCATION_IN_FILENAME="centraluseuap" ;; - "EAAS") LOCATION_IN_FILENAME="eastasia" ;; - "EAUS") LOCATION_IN_FILENAME="eastus" ;; - "EUSA") LOCATION_IN_FILENAME="eastus2euap" ;; - "EUS2") LOCATION_IN_FILENAME="eastus2" ;; - "EUSG") LOCATION_IN_FILENAME="eastusstg" ;; - "FRCE") LOCATION_IN_FILENAME="francecentral" ;; - "FRSO") LOCATION_IN_FILENAME="francesouth" ;; - "GENO") LOCATION_IN_FILENAME="germanynorth" ;; - "GEWE") LOCATION_IN_FILENAME="germanywest" ;; - "GEWC") LOCATION_IN_FILENAME="germanywestcentral" ;; - "ISCE") LOCATION_IN_FILENAME="israelcentral" ;; - "ITNO") LOCATION_IN_FILENAME="italynorth" ;; - "JAEA") LOCATION_IN_FILENAME="japaneast" ;; - "JAWE") LOCATION_IN_FILENAME="japanwest" ;; - "JINC") LOCATION_IN_FILENAME="jioindiacentral" ;; - "JINW") LOCATION_IN_FILENAME="jioindiawest" ;; - "KOCE") LOCATION_IN_FILENAME="koreacentral" ;; - "KOSO") LOCATION_IN_FILENAME="koreasouth" ;; - "NCUS") LOCATION_IN_FILENAME="northcentralus" ;; - "NOEU") LOCATION_IN_FILENAME="northeurope" ;; - "NOEA") LOCATION_IN_FILENAME="norwayeast" ;; - "NOWE") LOCATION_IN_FILENAME="norwaywest" ;; - "PLCE") LOCATION_IN_FILENAME="polandcentral" ;; - "QACE") LOCATION_IN_FILENAME="qatarcentral" ;; - "SANO") LOCATION_IN_FILENAME="southafricanorth" ;; - "SAWE") LOCATION_IN_FILENAME="southafricawest" ;; - "SCUS") LOCATION_IN_FILENAME="southcentralus" ;; - "SCUG") LOCATION_IN_FILENAME="southcentralusstg" ;; - "SOEA") LOCATION_IN_FILENAME="southeastasia" ;; - "SOIN") LOCATION_IN_FILENAME="southindia" ;; - "SECE") LOCATION_IN_FILENAME="swedencentral" ;; - "SWNO") LOCATION_IN_FILENAME="switzerlandnorth" ;; - "SWWE") LOCATION_IN_FILENAME="switzerlandwest" ;; - "UACE") LOCATION_IN_FILENAME="uaecentral" ;; - "UANO") LOCATION_IN_FILENAME="uaenorth" ;; - "UKSO") LOCATION_IN_FILENAME="uksouth" ;; - "UKWE") LOCATION_IN_FILENAME="ukwest" ;; - "WCUS") LOCATION_IN_FILENAME="westcentralus" ;; - "WEEU") LOCATION_IN_FILENAME="westeurope" ;; - "WEIN") LOCATION_IN_FILENAME="westindia" ;; - "WEUS") LOCATION_IN_FILENAME="westus" ;; - "WUS2") LOCATION_IN_FILENAME="westus2" ;; - "WUS3") LOCATION_IN_FILENAME="westus3" ;; - *) LOCATION_IN_FILENAME="westeurope" ;; - esac - - echo "Environment: ${ENVIRONMENT}" - echo "Location: ${LOCATION}" - echo "Location code: ${LOCATION_CODE}" - - echo "Environment(filename): $ENVIRONMENT_IN_FILENAME" - echo "Location(filename): $LOCATION_IN_FILENAME" - echo "" - - if [ $ENVIRONMENT != $ENVIRONMENT_IN_FILENAME ]; then - echo "##vso[task.logissue type=error]The environment setting in $(workload_zone_configuration_file) '$ENVIRONMENT' does not match the $(workload_zone_configuration_file) file name '$ENVIRONMENT_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-INFRASTRUCTURE" - exit 2 + variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Deployer_State_FileName.value" ) + if [ ${#variable_value} != 0 ]; then + az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name Deployer_State_FileName --yes --only-show-errors fi - if [ $LOCATION != $LOCATION_IN_FILENAME ]; then - echo "##vso[task.logissue type=error]The location setting in $(workload_zone_configuration_file) '$LOCATION' does not match the $(workload_zone_configuration_file) file name '$LOCATION_IN_FILENAME'. Filename should have the pattern [ENVIRONMENT]-[REGION_CODE]-[NETWORK_LOGICAL_NAME]-INFRASTRUCTURE" - exit 2 + variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Deployer_Key_Vault.value" ) + if [ ${#variable_value} != 0 ]; then + az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name Deployer_Key_Vault --yes --only-show-errors fi - echo -e "$green--- Running the remove region script that destroys deployer VM and SAP library ---$reset" - - deployer_environment_file_name=$HOME/.sap_deployment_automation/$ENVIRONMENT$LOCATION_CODE - echo "Environment file: $deployer_environment_file_name" - - echo -e "$green--- az login ---$reset" - - if [ $USE_MSI != "true" ]; then - echo -e "$cyan--- Remove using Service Principals ---$reset" - - unset ARM_USE_MSI - az login --service-principal --username $ARM_CLIENT_ID --password=$ARM_CLIENT_SECRET --tenant $ARM_TENANT_ID --output none - return_code=$? - if [ 0 != $return_code ]; then - echo -e "$boldred--- Login failed ---$reset" - echo "##vso[task.logissue type=error]az login failed." - exit $return_code - fi - fi - az account set --subscription $ARM_SUBSCRIPTION_ID - - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Deployer_Key_Vault.value" --out tsv) - if [ -n "${az_var}" ]; then - key_vault="${az_var}" - else - echo "Reading key vault from environment file" - key_vault=$(grep -m1 "^keyvault=" ${deployer_environment_file_name} | awk -F'=' '{print $2}' | xargs) + variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WEBAPP_URL_BASE.value" ) + if [ ${#variable_value} != 0 ]; then + az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_URL_BASE --yes --only-show-errors fi - echo "Deployer Key Vault: $key_vault" - - key_vault_id=$(az resource list --name "${key_vault}" --resource-type Microsoft.KeyVault/vaults --query "[].id | [0]" -o tsv) - if [ -n "${key_vault_id}" ]; then - - if [ "azure pipelines" = "$(this_agent)" ]; then - this_ip=$(curl -s ipinfo.io/ip) >/dev/null 2>&1 - az keyvault network-rule add --name ${key_vault} --ip-address ${this_ip} --only-show-errors --output none - ip_added=1 - fi + variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WEBAPP_IDENTITY.value" ) + if [ ${#variable_value} != 0 ]; then + az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_IDENTITY --yes --only-show-errors fi - echo -e "$green--- Running the remove_deployer script that destroys deployer VM ---$reset" - if [ -f $CONFIG_REPO_PATH/DEPLOYER/$(deployer_folder)/state.zip ]; then - echo "Unzipping state.zip" - pass=$(echo $DEPLOYER_RANDOM_ID_SEED | sed 's/-//g') - unzip -qq -o -P "${pass}" $CONFIG_REPO_PATH/DEPLOYER/$(deployer_folder)/state.zip -d ${CONFIG_REPO_PATH}/DEPLOYER/$(deployer_folder) + variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WEBAPP_ID.value" ) + if [ ${#variable_value} != 0 ]; then + az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_ID --yes --only-show-errors fi - sudo chmod +x $SAP_AUTOMATION_REPO_PATH/deploy/scripts/remove_deployer.sh - cd $CONFIG_REPO_PATH/DEPLOYER/$(deployer_folder) - - $SAP_AUTOMATION_REPO_PATH/deploy/scripts/remove_deployer.sh --auto-approve \ - --parameterfile $(deployer_configuration_file) - - return_code=$? - - echo "Return code from remove_deployer: $return_code." - if [ 0 != $return_code ]; then - echo "##vso[task.logissue type=error]Return code from remove_deployer $return_code." + variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WEBAPP_RESOURCE_GROUP.value" ) + if [ ${#variable_value} != 0 ]; then + az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_RESOURCE_GROUP --yes --only-show-errors fi - echo -e "$green--- Removing deployment automation configuration from devops repository ---$reset" - - if [ 0 == $return_code ] ; then - cd $CONFIG_REPO_PATH - changed=0 - echo "##vso[build.updatebuildnumber]Removing control plane $(deployer_folder) $(library_folder)" - if [ -f "DEPLOYER/$(deployer_folder)/.terraform/terraform.tfstate" ]; then - git rm -q -f --ignore-unmatch DEPLOYER/$(deployer_folder)/.terraform/terraform.tfstate - changed=1 - fi - - - if [ -d "DEPLOYER/$(deployer_folder)/.terraform" ]; then - git rm -q -r --ignore-unmatch DEPLOYER/$(deployer_folder)/.terraform - changed=1 - fi - - if [ -f "DEPLOYER/$(deployer_folder)/state.zip" ]; then - git rm -q -f --ignore-unmatch DEPLOYER/$(deployer_folder)/state.zip - changed=1 - fi - - if [ -d LIBRARY/$(library_folder)/.terraform ]; then - git rm -q -r --ignore-unmatch LIBRARY/$(library_folder)/.terraform - changed=1 - fi - - if [ -f LIBRARY/$(library_folder)/state.zip ]; then - git rm -q -f --ignore-unmatch LIBRARY/$(library_folder)/state.zip - changed=1 - fi - - if [ -f .sap_deployment_automation/${ENVIRONMENT}${LOCATION_CODE} ]; then - rm .sap_deployment_automation/${ENVIRONMENT}${LOCATION_CODE} - git rm -q --ignore-unmatch .sap_deployment_automation/${ENVIRONMENT}${LOCATION_CODE} - changed=1 - fi - if [ -f .sap_deployment_automation/${ENVIRONMENT}${LOCATION_CODE}.md ]; then - rm .sap_deployment_automation/${ENVIRONMENT}${LOCATION_CODE}.md - git rm -q --ignore-unmatch .sap_deployment_automation/${ENVIRONMENT}${LOCATION_CODE}.md - changed=1 - fi - - if [ -f LIBRARY/$(library_folder)/backend-config.tfvars ]; then - git rm -q --ignore-unmatch LIBRARY/$(library_folder)/backend-config.tfvars - changed=1 - fi - - if [ 1 == $changed ] ; then - git config --global user.email "$(Build.RequestedForEmail)" - git config --global user.name "$(Build.RequestedFor)" - git commit -m "Added updates from devops deployment $(Build.DefinitionName) [skip ci]" - git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" push - fi - echo -e "$green--- Deleting variables ---$reset" - if [ ${#VARIABLE_GROUP_ID} != 0 ]; then - echo "Deleting variables" - - variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Account_Name.value" ) - if [ ${#variable_value} != 0 ]; then - az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name Terraform_Remote_Storage_Account_Name --yes --only-show-errors - fi - - variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Resource_Group_Name.value" ) - if [ ${#variable_value} != 0 ]; then - az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name Terraform_Remote_Storage_Resource_Group_Name --yes --only-show-errors - fi - - variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Subscription.value" ) - if [ ${#variable_value} != 0 ]; then - az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name Terraform_Remote_Storage_Subscription --yes --only-show-errors - fi - - variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Deployer_State_FileName.value" ) - if [ ${#variable_value} != 0 ]; then - az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name Deployer_State_FileName --yes --only-show-errors - fi - - variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Deployer_Key_Vault.value" ) - if [ ${#variable_value} != 0 ]; then - az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name Deployer_Key_Vault --yes --only-show-errors - fi - - variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WEBAPP_URL_BASE.value" ) - if [ ${#variable_value} != 0 ]; then - az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_URL_BASE --yes --only-show-errors - fi - - variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WEBAPP_IDENTITY.value" ) - if [ ${#variable_value} != 0 ]; then - az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_IDENTITY --yes --only-show-errors - fi - - variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WEBAPP_ID.value" ) - if [ ${#variable_value} != 0 ]; then - az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_ID --yes --only-show-errors - fi - - variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WEBAPP_RESOURCE_GROUP.value" ) - if [ ${#variable_value} != 0 ]; then - az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_RESOURCE_GROUP --yes --only-show-errors - fi - - variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "INSTALLATION_MEDIA_ACCOUNT.value" ) - if [ ${#variable_value} != 0 ]; then - az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name INSTALLATION_MEDIA_ACCOUNT --yes --only-show-errors - fi - - fi - + variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "INSTALLATION_MEDIA_ACCOUNT.value" ) + if [ ${#variable_value} != 0 ]; then + az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name INSTALLATION_MEDIA_ACCOUNT --yes --only-show-errors fi - exit $return_code - displayName: Remove control plane - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - ARM_SUBSCRIPTION_ID: $(CP_ARM_SUBSCRIPTION_ID) - CP_ARM_CLIENT_ID: $(CP_ARM_CLIENT_ID) - CP_ARM_CLIENT_SECRET: $(CP_ARM_CLIENT_SECRET) - CP_ARM_TENANT_ID: $(CP_ARM_TENANT_ID) - SAP_AUTOMATION_REPO_PATH: ${{ parameters.sap_automation_repo_path }} - CONFIG_REPO_PATH: ${{ parameters.config_repo_path }}/$(Deployment_Configuration_Path) - key_vault: $(Deployer_Key_Vault) - TF_IN_AUTOMATION: true - TF_LOG: $(TF_LOG) - USE_MSI: $(Use_MSI) - DEPLOYER_RANDOM_ID_SEED: $(DEPLOYER_RANDOM_ID_SEED) - AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) + fi + + fi + + exit $return_code + displayName: Remove control plane + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + ARM_SUBSCRIPTION_ID: $(CP_ARM_SUBSCRIPTION_ID) + CP_ARM_CLIENT_ID: $(CP_ARM_CLIENT_ID) + CP_ARM_CLIENT_SECRET: $(CP_ARM_CLIENT_SECRET) + CP_ARM_TENANT_ID: $(CP_ARM_TENANT_ID) + SAP_AUTOMATION_REPO_PATH: ${{ parameters.sap_automation_repo_path }} + CONFIG_REPO_PATH: ${{ parameters.config_repo_path }}/$(Deployment_Configuration_Path) + key_vault: $(Deployer_Key_Vault) + TF_IN_AUTOMATION: true + TF_LOG: $(TF_LOG) + USE_MSI: $(Use_MSI) + DEPLOYER_RANDOM_ID_SEED: $(DEPLOYER_RANDOM_ID_SEED) + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) diff --git a/deploy/scripts/install_workloadzone.sh b/deploy/scripts/install_workloadzone.sh index 42af391e2a..6affb7075e 100755 --- a/deploy/scripts/install_workloadzone.sh +++ b/deploy/scripts/install_workloadzone.sh @@ -1075,7 +1075,7 @@ if [ 0 == $return_value ] ; then echo "" save_config_var "workloadkeyvault" "${workload_config_information}" - fi + fi_system fi fi diff --git a/deploy/scripts/installer.sh b/deploy/scripts/installer.sh index 3026b9e6a4..eeefbb53a5 100755 --- a/deploy/scripts/installer.sh +++ b/deploy/scripts/installer.sh @@ -240,6 +240,35 @@ if [[ -z $STATE_SUBSCRIPTION ]]; then STATE_SUBSCRIPTION=$ARM_SUBSCRIPTION_ID fi + +if [[ -n $STATE_SUBSCRIPTION ]]; +then + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $cyan Changing the subscription to: $STATE_SUBSCRIPTION $resetformatting #" + echo "# #" + echo "#########################################################################################" + echo "" + az account set --sub "${STATE_SUBSCRIPTION}" + + return_code=$? + if [ 0 != $return_code ]; then + + echo "#########################################################################################" + echo "# #" + echo -e "# $boldred The deployment account (MSI or SPN) does not have access to $resetformatting #" + echo -e "# $boldred ${STATE_SUBSCRIPTION} $resetformatting #" + echo "# #" + echo "#########################################################################################" + + echo "##vso[task.logissue type=error]The deployment account (MSI or SPN) does not have access to ${STATE_SUBSCRIPTION}" + exit $return_code + fi + + account_set=1 +fi + if [[ -n $STATE_SUBSCRIPTION ]]; then echo "" echo "#########################################################################################"