From c8991eaf691a329ca08c60d74b0cc10534930229 Mon Sep 17 00:00:00 2001 From: hdamecharla <71097261+hdamecharla@users.noreply.github.com> Date: Thu, 31 Oct 2024 13:09:33 +0530 Subject: [PATCH] Preparation for release v3.13.0.1 (#659) * 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 dynamic role assignment based on VM count and use managed service identity (MSI) for authentication * Refactor pipeline script to update echo statements and export variables for installation method, workload ARM_CLIENT_ID, and Terraform state information Co-authored-by: Kimmo Forss Co-authored-by: hdamecharla * ansible python fix (#653) Co-authored-by: swatibehl * Fix conditional statement in install_workloadzone.sh * Pipeline hotfixes (#654) * Refactor echo statements in deploy control plane pipeline * Refactor install_workloadzone.sh script to reset return_value variable * Refactor install_workloadzone.sh script to improve error handling * feng shui * Refactor variables_local.tf to improve readability and error handling * Refactor deploy control plane pipeline to include deployer_tfstate_key parameter * Refactor deploy control plane pipeline to include deployer_tfstate_key and landscape_tfstate_key parameters * Refactor echo statement in deploy control plane pipeline * Refactor remover script in deploy control plane pipeline * Refactor deploy control plane pipeline to remove unnecessary use_msi flag * Refactor deploy control plane pipeline to update default value for spn_keyvault_id * Refactor deploy control plane pipeline to update default value for spn_key_vault_arm_id * Refactor deploy control plane pipeline to trim deployer_tfstate_key in imports.tf * Refactor deploy control plane pipeline to include provider for azurerm.workload in imports.tf * Refactor deploy control plane pipeline to update storage account authentication and export TF_VAR_tfstate_resource_id * Refactor deploy control plane pipeline to update deployer and landscape state file paths * Refactor deploy control plane pipeline to remove unnecessary code in remover.sh * Refactor install_workloadzone.sh to export SPN key vault ID if keyvault is provided * Refactor tfvar_variables.tf to set default value of short_named_endpoints_nics to true * Refactor remover.sh to consolidate terraform destroy command * Refactor echo statements in remover.sh and remove-control-plane.yaml * Refactor echo statements in deploy/pipelines/01-deploy-control-plane.yaml * Refactor providers.tf to conditionally set use_msi based on var.use_spn * Refactor echo statements in deploy/pipelines/01-deploy-control-plane.yaml to improve clarity of deployment credentials * Refactor install_workloadzone.sh to improve argument parsing and readability * Refactor code for improved argument parsing and readability in install_workloadzone.sh * Refactor LandscapeModel.cs, LandscapeDetails.json, and LandscapeTemplate.txt to add prevent_deletion_if_contains_resources property * Refactor package dependencies in os-packages.yaml * Refactor ansible role to remove unused variable and update passlib dependency * Refactor echo statement in install_workloadzone.sh for improved clarity --------- Co-authored-by: Kimmo Forss * Suse 12 fix for python (#656) * suse 12 fix for python * Update 1.17.1-pre_checks.yml * Update 1.17.1-pre_checks.yml Fix linting issues --------- Co-authored-by: swatibehl Co-authored-by: hdamecharla <71097261+hdamecharla@users.noreply.github.com> * SLES 12 SP5 fixes (#658) * Fix conditional statement in install_workloadzone.sh * Fix subscription_id assignment in providers.tf * Fix indentation in deployment credential messages * Fix deployment credential messages and subscription_id assignment * chore: enable Azure scheduled events resource start and display output on SUSE * Refactor deployment script to improve readability and remove unnecessary output * Update provider version to 4.7 * Refactor tfvar_variables.tf to add a new variable for preventing deletion of resource groups with resources * Add prevent_deletion_if_contains_resources variable to SystemModel.cs * Refactor deployment script to improve readability and display deployment credentials * Refactor deployment script to enable Stonith and concurrent fencing * Refactor tfvar_variables.tf to add prevent_deletion_if_contains_resources variable * Refactor validate.yml to remove single quotes from crm_resource output * Refactor validate.yml to remove single quotes from crm_resource output * fix ansible schema errors * Refactor validate.yml to remove unnecessary 'when' condition --------- Co-authored-by: Kimmo Forss Co-authored-by: hdamecharla * extend timeout for zypp (#657) Co-authored-by: swatibehl --------- Co-authored-by: Kimmo Forss Co-authored-by: Kimmo Forss Co-authored-by: Swatibehl <127396693+Swatibehl@users.noreply.github.com> Co-authored-by: swatibehl --- README.md | 2 +- Webapp/SDAF/Models/LandscapeModel.cs | 2 + Webapp/SDAF/Models/SystemModel.cs | 2 + .../ParameterDetails/LandscapeDetails.json | 9 + .../ParameterDetails/LandscapeTemplate.txt | 3 +- .../SDAF/ParameterDetails/SystemDetails.json | 9 + .../SDAF/ParameterDetails/SystemTemplate.txt | 4 + Webapp/SDAF/SDAFWebApp.csproj | 12 +- .../roles-os/1.1-swap/defaults/main.yaml | 8 + .../ansible/roles-os/1.1-swap/tasks/main.yaml | 5 +- .../tasks/1.17.1-pre_checks.yml | 7 + .../tasks/1.17.2.0-cluster-Suse.yml | 22 +- .../tasks/1.3.0-preparation-Suse.yaml | 4 +- .../tasks/1.4.0-packages-Suse-prep.yaml | 2 +- .../tasks/1.4.3-update-packages-Suse.yaml | 2 +- .../1.4-packages/vars/os-packages.yaml | 14 +- .../tasks/5.6.6-validate.yml | 90 +- deploy/ansible/vars/ansible-input-api.yaml | 2 +- deploy/configs/version.txt | 2 +- deploy/pipelines/01-deploy-control-plane.yaml | 1109 +++++---- deploy/pipelines/02-sap-workload-zone.yaml | 620 ++--- .../pipelines/03-sap-system-deployment.yaml | 137 +- .../pipelines/04-sap-software-download.yaml | 18 +- .../pipelines/05-DB-and-SAP-installation.yaml | 54 +- deploy/pipelines/10-remover-terraform.yaml | 1009 ++++---- deploy/pipelines/11-remover-arm-fallback.yaml | 18 +- deploy/pipelines/12-remove-control-plane.yaml | 112 +- deploy/scripts/New-SDAFDevopsProject.ps1 | 2 +- deploy/scripts/New-SDAFDevopsWorkloadZone.ps1 | 10 +- deploy/scripts/advanced_state_management.sh | 16 +- deploy/scripts/deploy_controlplane.sh | 244 +- deploy/scripts/deploy_utils.sh | 46 +- deploy/scripts/helpers/script_helpers.sh | 101 +- deploy/scripts/install_deployer.sh | 554 ++--- deploy/scripts/install_library.sh | 799 ++++--- deploy/scripts/install_workloadzone.sh | 183 +- deploy/scripts/installer.sh | 2080 +++++++++-------- deploy/scripts/remove_controlplane.sh | 64 +- deploy/scripts/remove_deployer.sh | 2 +- deploy/scripts/remover.sh | 92 +- deploy/scripts/set_secrets.sh | 435 ++-- deploy/scripts/validate.sh | 117 +- .../bootstrap/sap_deployer/providers.tf | 4 +- .../bootstrap/sap_deployer/tfvar_variables.tf | 25 +- .../bootstrap/sap_deployer/transform.tf | 2 - .../bootstrap/sap_library/imports.tf | 8 +- .../bootstrap/sap_library/providers.tf | 9 +- .../bootstrap/sap_library/tfvar_variables.tf | 5 + .../bootstrap/sap_library/transform.tf | 122 +- .../terraform/run/sap_deployer/providers.tf | 10 +- .../run/sap_deployer/tfvar_variables.tf | 24 +- .../terraform/run/sap_deployer/transform.tf | 2 - .../run/sap_deployer/variables_local.tf | 8 +- deploy/terraform/run/sap_landscape/imports.tf | 15 +- .../terraform/run/sap_landscape/providers.tf | 5 +- .../run/sap_landscape/tfvar_variables.tf | 5 + .../run/sap_landscape/variables_local.tf | 14 +- deploy/terraform/run/sap_library/imports.tf | 8 +- deploy/terraform/run/sap_library/providers.tf | 7 +- .../run/sap_library/tfvar_variables.tf | 5 + deploy/terraform/run/sap_library/transform.tf | 119 +- .../run/sap_library/variables_local.tf | 3 +- deploy/terraform/run/sap_system/module.tf | 1 + deploy/terraform/run/sap_system/providers.tf | 5 +- .../run/sap_system/tfvar_variables.tf | 13 +- .../modules/sap_deployer/infrastructure.tf | 22 +- .../modules/sap_deployer/providers.tf | 2 +- .../templates/configure_deployer.sh.tmpl | 19 +- .../modules/sap_deployer/vm-deployer.tf | 7 +- .../sap_landscape/key_vault_sap_landscape.tf | 56 +- .../modules/sap_landscape/providers.tf | 2 +- .../modules/sap_landscape/storage_accounts.tf | 4 +- .../modules/sap_library/key_vault.tf | 2 +- .../modules/sap_library/providers.tf | 2 +- .../modules/sap_library/storage_accounts.tf | 10 +- .../sap_system/anydb_node/providers.tf | 2 +- .../modules/sap_system/app_tier/providers.tf | 2 +- .../common_infrastructure/providers.tf | 2 +- .../common_infrastructure/storage_accounts.tf | 39 +- .../common_infrastructure/variables_global.tf | 4 + .../modules/sap_system/hdb_node/providers.tf | 2 +- .../sap_system/output_files/providers.tf | 2 +- 82 files changed, 4549 insertions(+), 4072 deletions(-) create mode 100644 deploy/ansible/roles-os/1.1-swap/defaults/main.yaml diff --git a/README.md b/README.md index b00b803c9e..4293ee7693 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ The framework uses Terraform for infrastructure deployment, and Ansible for the ## Enterprise-scale - Reference Implementation -![Ansible Lint](https://github.com/Azure/sap-automation/workflows/Ansible%20Lint/badge.svg) [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/azure/sap-automation.svg)](http://isitmaintained.com/project/azure/sap-automation "Average time to resolve an issue") [![Percentage of issues still open](http://isitmaintained.com/badge/open/azure/sap-automation.svg)](http://isitmaintained.com/project/azure/sap-automation "Percentage of issues still open") +![Ansible Lint](https://github.com/Azure/sap-automation/workflows/Ansible%20Lint/badge.svg) [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/azure/sap-automation.svg)](http://isitmaintained.com/project/azure/sap-automation "Average time to resolve an issue") [![Percentage of issues still open](http://isitmaintained.com/badge/open/azure/sap-automation.svg)](http://isitmaintained.com/project/azure/sap-automation "Percentage of issues still open") [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/Azure/sap-automation/badge)](https://scorecard.dev/viewer/?uri=github.com/Azure/sap-automation) ## Partnership diff --git a/Webapp/SDAF/Models/LandscapeModel.cs b/Webapp/SDAF/Models/LandscapeModel.cs index ee7d46a981..d87e335508 100644 --- a/Webapp/SDAF/Models/LandscapeModel.cs +++ b/Webapp/SDAF/Models/LandscapeModel.cs @@ -221,6 +221,8 @@ public bool IsValid() public string resourcegroup_name { get; set; } + public bool? prevent_deletion_if_contains_resources { get; set; } = true; + /*---------------------------------------------------------------------------8 | | | Azure NetApp Files information | diff --git a/Webapp/SDAF/Models/SystemModel.cs b/Webapp/SDAF/Models/SystemModel.cs index 973fc66346..37fd26c4de 100644 --- a/Webapp/SDAF/Models/SystemModel.cs +++ b/Webapp/SDAF/Models/SystemModel.cs @@ -183,6 +183,8 @@ public bool IsValid() public string resourcegroup_name { get; set; } + public bool? prevent_deletion_if_contains_resources { get; set; } = true; + /*---------------------------------------------------------------------------8 | | | Miscallaneous information | diff --git a/Webapp/SDAF/ParameterDetails/LandscapeDetails.json b/Webapp/SDAF/ParameterDetails/LandscapeDetails.json index 7680110f6a..d88c961541 100644 --- a/Webapp/SDAF/ParameterDetails/LandscapeDetails.json +++ b/Webapp/SDAF/ParameterDetails/LandscapeDetails.json @@ -120,6 +120,15 @@ "Options": [], "Overrules": "", "Display": 2 + }, + { + "Name": "prevent_deletion_if_contains_resources", + "Required": false, + "Description": "Prevent deletion of resource group if there are Resources left within the Resource Group during deletion", + "Type": "checkbox", + "Options": [], + "Overrules": "", + "Display": 2 } ] }, diff --git a/Webapp/SDAF/ParameterDetails/LandscapeTemplate.txt b/Webapp/SDAF/ParameterDetails/LandscapeTemplate.txt index a971bf73fe..172bd1b026 100644 --- a/Webapp/SDAF/ParameterDetails/LandscapeTemplate.txt +++ b/Webapp/SDAF/ParameterDetails/LandscapeTemplate.txt @@ -305,7 +305,8 @@ $$resourcegroup_name$$ # The resourcegroup_name arm_id is optional, it can be used to provide an existing resource group for the deployment $$resourcegroup_arm_id$$ - +# Prevent deletion of resource group if there are Resources left within the Resource Group during deletion +$$prevent_deletion_if_contains_resources$$ ######################################################################################### # # diff --git a/Webapp/SDAF/ParameterDetails/SystemDetails.json b/Webapp/SDAF/ParameterDetails/SystemDetails.json index 0aebafb0a0..11867db5fd 100644 --- a/Webapp/SDAF/ParameterDetails/SystemDetails.json +++ b/Webapp/SDAF/ParameterDetails/SystemDetails.json @@ -203,6 +203,15 @@ "Options": [], "Overrules": "", "Display": 2 + }, + { + "Name": "prevent_deletion_if_contains_resources", + "Required": false, + "Description": "Prevent deletion of resource group if there are Resources left within the Resource Group during deletion", + "Type": "checkbox", + "Options": [], + "Overrules": "", + "Display": 2 } ] }, diff --git a/Webapp/SDAF/ParameterDetails/SystemTemplate.txt b/Webapp/SDAF/ParameterDetails/SystemTemplate.txt index 85dae6b1d6..9ff4392530 100644 --- a/Webapp/SDAF/ParameterDetails/SystemTemplate.txt +++ b/Webapp/SDAF/ParameterDetails/SystemTemplate.txt @@ -647,6 +647,10 @@ $$resourcegroup_name$$ # The resourcegroup_name arm_id is optional, it can be used to provide an existing resource group for the deployment $$resourcegroup_arm_id$$ +# Prevent deletion of resource group if there are Resources left within the Resource Group during deletion +$$prevent_deletion_if_contains_resources$$ + + ######################################################################################### # # # Proximity Placement Group # diff --git a/Webapp/SDAF/SDAFWebApp.csproj b/Webapp/SDAF/SDAFWebApp.csproj index 295391fb10..331fcadd00 100644 --- a/Webapp/SDAF/SDAFWebApp.csproj +++ b/Webapp/SDAF/SDAFWebApp.csproj @@ -16,18 +16,18 @@ - + - - - - - + + + + + diff --git a/deploy/ansible/roles-os/1.1-swap/defaults/main.yaml b/deploy/ansible/roles-os/1.1-swap/defaults/main.yaml new file mode 100644 index 0000000000..199a68459e --- /dev/null +++ b/deploy/ansible/roles-os/1.1-swap/defaults/main.yaml @@ -0,0 +1,8 @@ +--- +# TODO: Maybe move these to a group_vars/all/distro file so that they +# can be shared by all playbooks/tasks automatically, and extend with +# standardised versions of all similar patterns used in the playbooks. +# Changed from ansible_os_family to ansible_distribution to adopt Oracle Linux. os_family returns returns value Redhat by default. +distro_name: "{{ ansible_distribution | upper }}-{{ ansible_distribution_major_version }}" +distribution_id: "{{ ansible_distribution | lower ~ ansible_distribution_major_version }}" +distribution_full_id: "{{ ansible_distribution | lower ~ ansible_distribution_version }}" diff --git a/deploy/ansible/roles-os/1.1-swap/tasks/main.yaml b/deploy/ansible/roles-os/1.1-swap/tasks/main.yaml index 44b71b00e7..57c0f176d4 100644 --- a/deploy/ansible/roles-os/1.1-swap/tasks/main.yaml +++ b/deploy/ansible/roles-os/1.1-swap/tasks/main.yaml @@ -34,10 +34,9 @@ name: WALinuxAgent state: latest environment: - ZYPP_LOCK_TIMEOUT: "20" - + ZYPP_LOCK_TIMEOUT: "60" when: - - ansible_os_family == 'Suse' + - distribution_id == 'sles_sap15' tags: - skip_ansible_lint diff --git a/deploy/ansible/roles-os/1.17-generic-pacemaker/tasks/1.17.1-pre_checks.yml b/deploy/ansible/roles-os/1.17-generic-pacemaker/tasks/1.17.1-pre_checks.yml index 693c66ce8e..d7e688237e 100644 --- a/deploy/ansible/roles-os/1.17-generic-pacemaker/tasks/1.17.1-pre_checks.yml +++ b/deploy/ansible/roles-os/1.17-generic-pacemaker/tasks/1.17.1-pre_checks.yml @@ -6,10 +6,17 @@ # | | # +------------------------------------4--------------------------------------*/ +- name: "5.6 SCS/ERS Validation: - Set Python version {{ distribution_id }}" + ansible.builtin.set_fact: + python_version: "python2" + when: (ansible_distribution | lower ~ ansible_distribution_major_version) in ['sles_sap12'] + - name: "1.17 Generic Pacemaker: - Ensure passlib is installed" ansible.builtin.pip: name: passlib state: present + vars: + ansible_python_interpreter: "{{ python_version }}" tags: - always diff --git a/deploy/ansible/roles-os/1.17-generic-pacemaker/tasks/1.17.2.0-cluster-Suse.yml b/deploy/ansible/roles-os/1.17-generic-pacemaker/tasks/1.17.2.0-cluster-Suse.yml index 8b38f4ab87..7701031f47 100644 --- a/deploy/ansible/roles-os/1.17-generic-pacemaker/tasks/1.17.2.0-cluster-Suse.yml +++ b/deploy/ansible/roles-os/1.17-generic-pacemaker/tasks/1.17.2.0-cluster-Suse.yml @@ -185,7 +185,7 @@ - name: "1.17 Generic Pacemaker - Enable Stonith" ansible.builtin.shell: | - crm configure property stonith-enabled=true \ + crm configure property stonith-enabled=true crm configure property concurrent-fencing=true register: crm_configure_result failed_when: crm_configure_result.rc > 1 @@ -405,6 +405,26 @@ - name: "1.17 Generic Pacemaker - Remove false positives" ansible.builtin.shell: crm_resource -C + - name: "1.17 Generic Pacemaker - Ensure the Azure scheduled events resource is started" + ansible.builtin.shell: | + set -o pipefail + crm status full | grep health-azure-events | grep Started | wc -l + register: azure_scheduled_events_status + retries: 12 + delay: 10 + until: azure_scheduled_events_status.stdout | int == ansible_play_hosts_all | length + when: inventory_hostname == primary_instance_name + failed_when: false + + - name: "1.17 Generic Pacemaker - display output of Azure scheduled events" + when: inventory_hostname == primary_instance_name + ansible.builtin.debug: + msg: + - "output lines: {{ azure_scheduled_events_status.stdout_lines }}" + - "output: {{ azure_scheduled_events_status.stdout | int }}" + - "output_truthiness: {{ azure_scheduled_events_status.stdout | int == ansible_play_hosts_all | length }}" + verbosity: 2 + - name: "1.17 Generic Pacemaker - Ensure maintenance mode is disabled" ansible.builtin.shell: crm configure property maintenance-mode=false diff --git a/deploy/ansible/roles-os/1.3-repository/tasks/1.3.0-preparation-Suse.yaml b/deploy/ansible/roles-os/1.3-repository/tasks/1.3.0-preparation-Suse.yaml index 88434ec442..c0ccb75025 100644 --- a/deploy/ansible/roles-os/1.3-repository/tasks/1.3.0-preparation-Suse.yaml +++ b/deploy/ansible/roles-os/1.3-repository/tasks/1.3.0-preparation-Suse.yaml @@ -15,7 +15,7 @@ # change anything so ensure it doesn't report as changed. changed_when: false environment: - ZYPP_LOCK_TIMEOUT: "20" + ZYPP_LOCK_TIMEOUT: "60" rescue: # Attempt to configure the repos by re-registering instance @@ -39,7 +39,7 @@ # registercloudguest rc == 1 when successful failed_when: reg_result.rc > 1 environment: - ZYPP_LOCK_TIMEOUT: "20" + ZYPP_LOCK_TIMEOUT: "60" - name: "1.3 Packages - Wait 30 secs before retrying" ansible.builtin.wait_for: diff --git a/deploy/ansible/roles-os/1.4-packages/tasks/1.4.0-packages-Suse-prep.yaml b/deploy/ansible/roles-os/1.4-packages/tasks/1.4.0-packages-Suse-prep.yaml index 5e1cf68ec0..c1239a5950 100644 --- a/deploy/ansible/roles-os/1.4-packages/tasks/1.4.0-packages-Suse-prep.yaml +++ b/deploy/ansible/roles-os/1.4-packages/tasks/1.4.0-packages-Suse-prep.yaml @@ -35,7 +35,7 @@ SUSEConnect -p sle-module-public-cloud/{{ ansible_distribution_version }}/x86_64 register: cloud_extension environment: - ZYPP_LOCK_TIMEOUT: "20" + ZYPP_LOCK_TIMEOUT: "60" rescue: - name: "1.4 Packages - Wait 10 secs before retrying" diff --git a/deploy/ansible/roles-os/1.4-packages/tasks/1.4.3-update-packages-Suse.yaml b/deploy/ansible/roles-os/1.4-packages/tasks/1.4.3-update-packages-Suse.yaml index 7a705032be..ba8e896914 100644 --- a/deploy/ansible/roles-os/1.4-packages/tasks/1.4.3-update-packages-Suse.yaml +++ b/deploy/ansible/roles-os/1.4-packages/tasks/1.4.3-update-packages-Suse.yaml @@ -13,7 +13,7 @@ state: latest update_cache: true environment: - ZYPP_LOCK_TIMEOUT: "20" + ZYPP_LOCK_TIMEOUT: "60" tags: - skip_ansible_lint diff --git a/deploy/ansible/roles-os/1.4-packages/vars/os-packages.yaml b/deploy/ansible/roles-os/1.4-packages/vars/os-packages.yaml index 979d785afe..2f6c5bddbe 100644 --- a/deploy/ansible/roles-os/1.4-packages/vars/os-packages.yaml +++ b/deploy/ansible/roles-os/1.4-packages/vars/os-packages.yaml @@ -339,25 +339,27 @@ packages: - { tier: 'ha', package: 'socat', node_tier: 'all', state: 'present' } - { tier: 'ha', package: 'corosync', node_tier: 'all', state: 'present' } - { tier: 'ha', package: 'resource-agents>=4.3', node_tier: 'all', state: 'present' } - - { tier: 'ha', package: 'fence-agents>=4.4.0', node_tier: 'all', state: 'present' } - { tier: 'ha', package: 'cloud-netconfig-azure>=1.3', node_tier: 'all', state: 'present' } # Assumption: Public_Cloud_Module_x86_64 already available - { tier: 'ha', package: 'python-azure-mgmt-compute', node_tier: 'all', state: 'present' } - { tier: 'ha', package: 'python-azure-identity', node_tier: 'all', state: 'present' } # Added as part of documentation update - - { tier: 'ha', package: 'sap-suse-cluster-connector', node_tier: 'hana', state: 'present' } + - { tier: 'ha', package: 'sap-suse-cluster-connector', node_tier: 'hana', state: 'present' } - { tier: 'ha', package: 'sap-suse-cluster-connector', node_tier: 'scs', state: 'present' } - { tier: 'ha', package: 'sap-suse-cluster-connector', node_tier: 'ers', state: 'present' } # -------------------------- End - packages required for Clustering ------------------------------------8 sles_sap12.4: # --------------------------- Begin - Packages required for SYBASE -----------------------------------------8 # 2371942 - Error Executing isql or dscp on SAP ASE or SAP HANA Accelerator for SAP ASE - - { tier: 'os', package: 'glibc-32bit', node_tier: 'sybase', state: 'present' } + - { tier: 'os', package: 'glibc-32bit', node_tier: 'sybase', state: 'present' } + - { tier: 'ha', package: 'fence-agents>=4.4.0', node_tier: 'all', state: 'present' } # --------------------------- End - Packages required for SYBASE -------------------------------------------8 sles_sap12.5: # --------------------------- Begin - Packages required for SYBASE -----------------------------------------8 # 2371942 - Error Executing isql or dscp on SAP ASE or SAP HANA Accelerator for SAP ASE - - { tier: 'os', package: 'glibc-32bit', node_tier: 'sybase', state: 'present' } - # --------------------------- End - Packages required for SYBASE -------------------------------------------8 + - { tier: 'os', package: 'glibc-32bit', node_tier: 'sybase', state: 'present' } + - { tier: 'ha', package: 'fence-agents-azure-arm', node_tier: 'scs', state: 'present' } + - { tier: 'ha', package: 'fence-agents-azure-arm', node_tier: 'ers', state: 'present' } + - { tier: 'ha', package: 'fence-agents-azure-arm', node_tier: 'hana', state: 'present' } # --------------------------- End - Packages required for SYBASE -------------------------------------------8 sles_sap15: - { tier: 'os', package: 'chrony', node_tier: 'all', state: 'present' } # - { tier: 'os', package: 'libyui-qt-pkg11', node_tier: 'all', state: 'present' } @@ -365,7 +367,7 @@ packages: - { tier: 'os', package: 'systemd', node_tier: 'all', state: 'present' } - { tier: 'os', package: 'tuned', node_tier: 'all', state: 'present' } - { tier: 'os', package: 'numad', node_tier: 'all', state: 'present' } - - { tier: 'os', package: 'ntp', node_tier: 'all', state: 'absent' } + - { tier: 'os', package: 'ntp', node_tier: 'all', state: 'absent' } - { tier: 'os', package: 'unrar', node_tier: 'scs', state: 'present' } # --------------------------- Begin - Packages required for DB2 -----------------------------------------8 # https://www.ibm.com/docs/en/db2/11.5?topic=servers-linux diff --git a/deploy/ansible/roles-sap/5.6-scsers-pacemaker/tasks/5.6.6-validate.yml b/deploy/ansible/roles-sap/5.6-scsers-pacemaker/tasks/5.6.6-validate.yml index 0a60acd1c9..61108ed6cc 100644 --- a/deploy/ansible/roles-sap/5.6-scsers-pacemaker/tasks/5.6.6-validate.yml +++ b/deploy/ansible/roles-sap/5.6-scsers-pacemaker/tasks/5.6.6-validate.yml @@ -1,3 +1,5 @@ +--- + # Validate that the SCS cluster is working as expected - name: "5.6 SCS/ERS Validation: - Set Python version {{ distribution_id }}" @@ -83,56 +85,48 @@ when: - cluster_group_location.stdout_lines is defined - # move cluster group g-{{ sap_sid | upper }}_{{ instance_type | upper }} to primary_instance_name - name: "5.6 SCS/ERS Validation: Move cluster group g-{{ sap_sid | upper }}_{{ instance_type | upper }} to {{ primary_instance_name }}" - ansible.builtin.shell: "crm resource move g-{{ sap_sid | upper }}_{{ instance_type | upper }} {{ primary_instance_name }}" - vars: - allow_world_readable_tmpfiles: true - ansible_python_interpreter: "{{ python_version }}" when: - - ansible_os_family | upper == 'SUSE' - - cluster_group_location.stdout_lines != primary_instance_name + - primary_instance_name not in cluster_group_location.stdout_lines - scs_running_on is not defined - failed_when: false - changed_when: false - register: cluster_group_moved + block: - # move cluster group g-{{ sap_sid | upper }}_{{ instance_type | upper }} to primary_instance_name - - name: "5.6 SCS/ERS Validation: Move cluster group g-{{ sap_sid | upper }}_{{ instance_type | upper }} to {{ primary_instance_name }}" - ansible.builtin.shell: "pcs resource move g-{{ sap_sid | upper }}_{{ instance_type | upper }} {{ primary_instance_name }}" - vars: - allow_world_readable_tmpfiles: true - ansible_python_interpreter: "{{ python_version }}" - when: - - ansible_os_family | upper == 'REDHAT' - - ansible_hostname == primary_instance_name - - cluster_group_location.stdout_lines != primary_instance_name - - scs_running_on is not defined - register: cluster_group_moved - failed_when: false - changed_when: false - # failed_when: cluster_group_moved.rc != 0 and ( - # cluster_group_moved.stderr is not search('Already in requested state') - # or cluster_group_moved.stderr is not search('is already active on') - # ) + # move cluster group g-{{ sap_sid | upper }}_{{ instance_type | upper }} to primary_instance_name + - name: "5.6 SCS/ERS Validation: Move cluster group g-{{ sap_sid | upper }}_{{ instance_type | upper }} to {{ primary_instance_name }}" + ansible.builtin.shell: "crm resource move g-{{ sap_sid | upper }}_{{ instance_type | upper }} {{ primary_instance_name }}" + vars: + allow_world_readable_tmpfiles: true + ansible_python_interpreter: "{{ python_version }}" + when: + - ansible_os_family | upper == 'SUSE' + failed_when: false + changed_when: false + register: cluster_group_moved - - name: "5.6 SCS/ERS Validation: Wait {{ scs_wait_for_start_in_sec }} seconds for the StartService {{ sap_sid | upper }} to finish" - ansible.builtin.debug: - msg: "Wait for {{ scs_wait_for_start_in_sec }} seconds for the StartService {{ sap_sid | upper }} to finish" - when: - - ansible_hostname == primary_instance_name - - cluster_group_location.stdout_lines != primary_instance_name - - scs_running_on is not defined + # move cluster group g-{{ sap_sid | upper }}_{{ instance_type | upper }} to primary_instance_name + - name: "5.6 SCS/ERS Validation: Move cluster group g-{{ sap_sid | upper }}_{{ instance_type | upper }} to {{ primary_instance_name }}" + ansible.builtin.shell: "pcs resource move g-{{ sap_sid | upper }}_{{ instance_type | upper }} {{ primary_instance_name }}" + vars: + allow_world_readable_tmpfiles: true + ansible_python_interpreter: "{{ python_version }}" + when: + - ansible_os_family | upper == 'REDHAT' + register: cluster_group_moved + failed_when: false + changed_when: false - - name: "5.6 SCS/ERS Validation: Wait {{ scs_wait_for_start_in_sec }} seconds for the StartService {{ sap_sid | upper }} to finish" - ansible.builtin.wait_for: - timeout: "{{ scs_wait_for_start_in_sec }}" - when: - - ansible_hostname == primary_instance_name - - cluster_group_location.stdout_lines != primary_instance_name - - scs_running_on is not defined + - name: "5.6 SCS/ERS Validation: Wait {{ scs_wait_for_start_in_sec }} seconds for the StartService {{ sap_sid | upper }} to finish" + ansible.builtin.debug: + msg: "Wait for {{ scs_wait_for_start_in_sec }} seconds for the StartService {{ sap_sid | upper }} to finish" + + - name: "5.6 SCS/ERS Validation: Wait {{ scs_wait_for_start_in_sec }} seconds for the StartService {{ sap_sid | upper }} to finish" + ansible.builtin.wait_for: + timeout: "{{ scs_wait_for_start_in_sec }}" - name: "5.6 SCS/ERS Validation: Validate Cluster resource move and SAP start when the group g-{{ sap_sid | upper }}_{{ instance_type | upper }} has moved" + when: + - scs_running_on is not defined + - ansible_hostname == primary_instance_name block: - name: "Check if cluster group g-{{ sap_sid | upper }}_{{ instance_type | upper }} is running on {{ primary_instance_name }}" ansible.builtin.shell: >- @@ -146,13 +140,6 @@ failed_when: false changed_when: false - # - name: "5.6 SCS/ERS Validation: Validate that cluster group g-{{ sap_sid | upper }}_{{ instance_type | upper }} is running on {{ primary_instance_name }}" - # ansible.builtin.assert: - # that: - # - cluster_group_location.stdout == primary_instance_name - # fail_msg: "cluster group g-{{ sap_sid | upper }}_{{ instance_type | upper }} is not running on {{ primary_instance_name }}" - - # {{ sapcontrol_path }} -nr {{ scs_instance_number }} -function GetProcessList | grep MessageServer | awk '{split($0,result,", "); print result[1],result[3] }' - name: "5.6 SCS/ERS Validation: Determine if SCS is running on {{ ansible_hostname }}" ansible.builtin.shell: "{{ sapcontrol_path }} -nr {{ scs_instance_number }} -function StartService {{ sap_sid | upper }}" changed_when: false @@ -193,6 +180,5 @@ DIR_LIBRARY: /usr/sap/{{ sap_sid | upper }}/SYS/exe/run LD_LIBRARY_PATH: /usr/sap/{{ sap_sid | upper }}/SYS/exe/run:/usr/sap/{ sap_sid | upper }}/SYS/exe/uc/linuxx86_64 SAPSYSTEMNAME: "{{ sap_sid | upper }}" - when: - - scs_running_on is not defined - - ansible_hostname == primary_instance_name + +... diff --git a/deploy/ansible/vars/ansible-input-api.yaml b/deploy/ansible/vars/ansible-input-api.yaml index 18b4ae7722..b03529cb8d 100644 --- a/deploy/ansible/vars/ansible-input-api.yaml +++ b/deploy/ansible/vars/ansible-input-api.yaml @@ -5,7 +5,7 @@ become_user_name: root oracle_user_name: oracle orchestration_ansible_user: azureadm # ------------------- Begin - SDAF Ansible Version ---------------------------8 -SDAF_Version: "3.13.0.0" +SDAF_Version: "3.13.1.0" # ------------------- End - SDAF Ansible Version ---------------------------8 diff --git a/deploy/configs/version.txt b/deploy/configs/version.txt index c21c6f6867..bc8db301f8 100644 --- a/deploy/configs/version.txt +++ b/deploy/configs/version.txt @@ -1 +1 @@ -3.13.0.0 +3.13.1.0 diff --git a/deploy/pipelines/01-deploy-control-plane.yaml b/deploy/pipelines/01-deploy-control-plane.yaml index f96089caf3..b8aa970aa8 100644 --- a/deploy/pipelines/01-deploy-control-plane.yaml +++ b/deploy/pipelines/01-deploy-control-plane.yaml @@ -89,47 +89,45 @@ stages: boldred="\e[1;31m" cyan="\e[1;36m" - export ARM_CLIENT_ID=$servicePrincipalId - - if [ -n "$(servicePrincipalKey)" ]; then - export ARM_CLIENT_SECRET=$servicePrincipalKey - else - export ARM_USE_OIDC=true - export ARM_USE_AZUREAD=true - export ARM_OIDC_TOKEN=$idToken - fi + 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) ; echo Environment ${ENVIRONMENT} - LOCATION=$(echo $(deployerfolder) | awk -F'-' '{print $2}' | xargs) ; echo Location ${LOCATION} + 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 - az --version + az config set extension.use_dynamic_install=yes_without_prompt --only-show-errors - az extension add --name azure-devops --output none + az extension add --name azure-devops --output none --only-show-errors - echo "Agent: " $(this_agent) - echo "Organization: " $(System.CollectionUri) - echo "Project: " $(System.TeamProject) + 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 - 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]") - echo "$(variable_group) id: ${VARIABLE_GROUP_ID}" + printf -v tempval '%s id:' $(variable_group) + printf -v val '%-20s' "${tempval}" + echo "$val $VARIABLE_GROUP_ID" - echo "${{ parameters.force_reset }}" if [ "${{ parameters.force_reset }}" = "True" ]; then echo "##vso[task.logissue type=warning]Forcing a re-install" - echo "running on $(this_agent)" + 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 @@ -140,7 +138,7 @@ stages: key_vault="${az_var}" ; echo 'Deployer Key Vault' ${key_vault} else echo "Reading key vault from environment file" - key_vault=$(cat ${deployer_environment_file_name} | grep keyvault= -m1 | awk -F'=' '{print $2}' | xargs) ; echo 'Deployer Key Vault' ${key_vault} + 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) @@ -163,13 +161,13 @@ stages: 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' ${step} + 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 - echo "Agent: " $(this_agent) if [ -z ${VARIABLE_GROUP_ID} ]; then echo "##vso[task.logissue type=error]Variable group $(variable_group) could not be found." exit 2 @@ -198,19 +196,22 @@ stages: fi # Check if running on deployer if [ ! -f /etc/profile.d/deploy_server.sh ]; then - echo -e "$green --- Install dos2unix ---$reset" + echo -e "$green--- Install dos2unix ---$reset" sudo apt-get -qq install dos2unix - sudo apt -qq install zip - echo -e "$green --- Install terraform ---$reset" + 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/ + 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 >/dev/null + 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" @@ -220,23 +221,23 @@ stages: 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 is defined' + echo "Deployer Agent PAT: IsDefined" fi if [ -n "$(POOL)" ]; then - echo 'Deployer Agent Pool' $(POOL) + 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 - ls -lart ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder) - if [ $(use_webapp) = "true" ]; then - echo "Use WebApp is selected" + echo "Deploy Web App: true" + else - echo "No WebApp" + echo "Deploy Web App: false" fi export TF_LOG_PATH=$CONFIG_REPO_PATH/.sap_deployment_automation/terraform.log @@ -245,14 +246,26 @@ stages: 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_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) \ @@ -262,7 +275,7 @@ stages: fi return_code=$? - echo "Return code from deploy_controlplane $return_code." + echo "Deploy_controlplane returned $return_code." set -eu @@ -275,12 +288,13 @@ stages: if [ -z "$file_deployer_tfstate_key" ]; then file_deployer_tfstate_key=$DEPLOYER_TFSTATE_KEY fi - echo 'Deployer State File' $file_deployer_tfstate_key + 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} + 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) - echo 'Deployer Random ID' ${deployer_random_id} fi echo -e "$green--- Update repo ---$reset" @@ -293,9 +307,9 @@ stages: added=1 fi if [ -f ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/terraform.tfstate ]; then - sudo apt install zip + sudo apt-get install zip -y pass=$(echo $(System.CollectionId) | sed 's/-//g') - zip -j -P "${pass}" ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/state ${CONFIG_REPO_PATH}/DEPLOYER/$(deployerfolder)/terraform.tfstate + 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 @@ -310,26 +324,26 @@ stages: 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") + 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") + 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") + 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") + 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 @@ -337,7 +351,7 @@ stages: 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") + 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 @@ -407,491 +421,548 @@ stages: 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) - - 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 -e "$green--- Checkout $(Build.SourceBranchName) ---$reset" - cd $CONFIG_REPO_PATH - 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 - az extension add --name azure-devops --output none - - az devops configure --defaults organization=$(System.CollectionUri) project='$(System.TeamProject)' - - export VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(variable_group)'].id | [0]") - echo VARIABLE_GROUP_ID ${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 - 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 - key_vault="${az_var}" - echo -e "$cyan 'Deployer Key Vault' ${key_vault} $reset" - else - if [ -f ${deployer_environment_file_name} ] ; then - key_vault=$(cat ${deployer_environment_file_name} | grep keyvault= | awk -F'=' '{print $2}' | xargs) - echo -e "$cyan 'Deployer Key Vault' ${key_vault} $reset" - 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 - STATE_SUBSCRIPTION="${az_var}" ; echo 'Terraform state file subscription' $STATE_SUBSCRIPTION - else - if [ -f ${deployer_environment_file_name} ] ; then - STATE_SUBSCRIPTION=$(cat ${deployer_environment_file_name} | grep STATE_SUBSCRIPTION | awk -F'=' '{print $2}' | xargs) ; echo 'Terraform state file subscription' $STATE_SUBSCRIPTION - 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=$(cat ${deployer_environment_file_name} | grep deployer_random_id= | 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 - REMOTE_STATE_SA="${az_var}" ; echo 'Terraform state file storage account' $REMOTE_STATE_SA - else - if [ -f ${deployer_environment_file_name} ] ; then - REMOTE_STATE_SA=$(cat ${deployer_environment_file_name} | grep REMOTE_STATE_SA | awk -F'=' '{print $2}' | xargs) ; echo 'Terraform state file storage account' $REMOTE_STATE_SA - 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 - fi - - 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 "Use WebApp is selected" - - if [ -z ${APP_REGISTRATION_APP_ID} ]; then - echo "##vso[task.logissue type=error]Variable APP_REGISTRATION_APP_ID was not defined." - exit 2 - fi + #!/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 - export TF_VAR_app_registration_app_id=$(APP_REGISTRATION_APP_ID); echo 'App Registration App ID' ${TF_VAR_app_registration_app_id} - export TF_VAR_webapp_client_secret=$(WEB_APP_CLIENT_SECRET) - export TF_VAR_use_webapp=true - - 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") - 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") - 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") - 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") - 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 -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" - 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 - if [ $USE_MSI != "true" ]; then - echo -e "$cyan--- Using SPN ---$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=$ARM_SUBSCRIPTION_ID - export ARM_USE_MSI=false - 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 -e "$cyan--- Using MSI ---$reset" - source /etc/profile.d/deploy_server.sh - cat /etc/profile.d/deploy_server.sh - # export ARM_SUBSCRIPTION_ID=$ARM_SUBSCRIPTION_ID - export ARM_USE_MSI=true - export ARM_USE_AZUREAD=true - fi - 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 - echo -e "$green--- Configure parameters ---$reset" + 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 - 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) + fi - echo -e "$green--- Configuring variables ---$reset" + 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 - 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_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 - export key_vault="" - ip_added=0 + 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 - if [ -f ${deployer_environment_file_name} ]; then - if [ 0 = $bootstrapped ]; then - export key_vault=$(cat ${deployer_environment_file_name} | grep key_vault | awk -F'=' '{print $2}' | xargs) ; echo "Key Vault: $key_vault" - if [ -n "${key_vault}" ]; then - 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 + az account set --subscription "$ARM_SUBSCRIPTION_ID" - 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 -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 -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 -e "$cyan--- Using MSI ---$reset" - $SAP_AUTOMATION_REPO_PATH/deploy/scripts/deploy_controlplane.sh \ - --deployer_parameter_file "${deployer_configfile}" \ - --library_parameter_file "${library_configfile}" \ - --subscription $STATE_SUBSCRIPTION \ - --auto-approve --ado --msi \ - ${storage_account_parameter} ${keyvault_parameter} - else - $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} - 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} - git fetch -q --all - 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) - echo 'Deployer State File' $file_deployer_tfstate_key - - file_key_vault=$(cat ${deployer_environment_file_name} | grep keyvault= | awk -F'=' '{print $2}' | xargs) - echo '(File) Deployer Key Vault' ${file_key_vault} - - file_REMOTE_STATE_SA=$(cat ${deployer_environment_file_name} | grep REMOTE_STATE_SA | awk -F'=' '{print $2}' | xargs) - echo '(File) Terraform state file storage account' $file_REMOTE_STATE_SA - - file_REMOTE_STATE_RG=$(cat ${deployer_environment_file_name} | grep REMOTE_STATE_RG | awk -F'=' '{print $2}' | xargs) - echo '(File) Terraform state file resource group' $file_REMOTE_STATE_RG - 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 install zip - echo "Compressing the deployer state file" - pass=$(echo $(System.CollectionId) | sed 's/-//g') - zip -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 install zip - echo "Compressing the library state file" - pass=$(echo $(System.CollectionId) | sed 's/-//g') - zip -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") - 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") - 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") - 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") - 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") - 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") - 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") - 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 + 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]" + + 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) - ARM_SUBSCRIPTION_ID: $(CP_ARM_SUBSCRIPTION_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) diff --git a/deploy/pipelines/02-sap-workload-zone.yaml b/deploy/pipelines/02-sap-workload-zone.yaml index 169e5fa5e8..4c6eecb8bc 100644 --- a/deploy/pipelines/02-sap-workload-zone.yaml +++ b/deploy/pipelines/02-sap-workload-zone.yaml @@ -119,8 +119,8 @@ stages: 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 + # 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" @@ -128,94 +128,101 @@ stages: 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 + 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 + else source /etc/profile.d/deploy_server.sh - fi + fi - if [ ! -f $CONFIG_REPO_PATH/LANDSCAPE/$(workload_zone_folder)/$(workload_zone_configuration_file) ]; then + 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 + fi + + echo -e "$green--- Checkout $(Build.SourceBranchName) ---$reset" - echo -e "$green--- Checkout $(Build.SourceBranchName) ---$reset" + cd "${CONFIG_REPO_PATH}" || exit + mkdir -p .sap_deployment_automation + git checkout -q $(Build.SourceBranchName) - cd $CONFIG_REPO_PATH - mkdir -p .sap_deployment_automation - git checkout -q $(Build.SourceBranchName) + echo -e "$green--- Validations ---$reset" + if [ $USE_MSI != "true" ]; then - echo -e "$green--- Validations ---$reset" + 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 [ -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 [ $USE_MSI != "true" ]; then + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 - - 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) - echo Environment: ${ENVIRONMENT} - echo Location: ${LOCATION} - echo Network: ${NETWORK} - echo "TFvars $workload_zone_configuration_file" - echo "" - echo "Agent: $(this_agent)" - echo "Organization: $(System.CollectionUri)" - echo "Project: $(System.TeamProject)" - echo "" - echo "Azure CLI version:" - echo "-------------------------------------------------" - az --version - - 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 + 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" ;; @@ -272,392 +279,407 @@ stages: "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(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: $(this_agent)" - echo "Organization: $(System.CollectionUri)" - echo "Project: $(System.TeamProject)" - echo "" - echo "Azure CLI version:" - echo "-------------------------------------------------" - az --version - - - if [ $ENVIRONMENT != $ENVIRONMENT_IN_FILENAME ]; then + 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 + fi - if [ $LOCATION != $LOCATION_IN_FILENAME ]; then + 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 + fi - if [ $NETWORK != $NETWORK_IN_FILENAME ]; then + 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 + fi echo -e "$green--- Configure devops CLI extension ---$reset" - az config set extension.use_dynamic_install=yes_without_prompt --output none + az config set extension.use_dynamic_install=yes_without_prompt --output none - az extension add --name azure-devops --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 + 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]") - echo '$(parent_variable_group) id: ' $PARENT_VARIABLE_GROUP_ID - if [ -z ${PARENT_VARIABLE_GROUP_ID} ]; then + 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 + fi + + export VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(variable_group)'].id | [0]") - export VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(variable_group)'].id | [0]") - echo '$(variable_group) id: ' $VARIABLE_GROUP_ID - if [ -z ${VARIABLE_GROUP_ID} ]; then + if [ -z ${VARIABLE_GROUP_ID} ]; then echo "##vso[task.logissue type=error]Variable group $(variable_group) could not be found." exit 2 - fi + 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" - echo "Agent Pool: " $(this_agent) + deployer_environment_file_name=$CONFIG_REPO_PATH/.sap_deployment_automation/$(deployer_environment)$(deployer_region) + echo "Deployer Environment File: $deployer_environment_file_name" - echo -e "$green--- Set CONFIG_REPO_PATH variable ---$reset" + workload_environment_file_name=$CONFIG_REPO_PATH/.sap_deployment_automation/${ENVIRONMENT}${LOCATION_CODE}${NETWORK} + echo "Workload Zone Environment File: $workload_environment_file_name" - 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 Environment File' $workload_environment_file_name - dos2unix -q ${deployer_environment_file_name} - dos2unix -q ${workload_environment_file_name} + dos2unix -q ${deployer_environment_file_name} + dos2unix -q ${workload_environment_file_name} - if [ ! -f ${deployer_environment_file_name} ]; then + 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 - + fi echo -e "$green--- Read parameter values ---$reset" - if [ "true" == $(inherit) ]; then + if [ "true" == $(inherit) ]; then - az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Deployer_State_FileName.value" | tr -d \") + 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=$(cat ${deployer_environment_file_name} | grep deployer_tfstate_key | awk -F'=' '{print $2}' | xargs) ; echo 'Deployer State File' $deployer_tfstate_key + deployer_tfstate_key=$(grep "^deployer_tfstate_key=" ${deployer_environment_file_name} | awk -F'=' '{print $2}' | xargs) else - deployer_tfstate_key=${az_var} ; echo 'Deployer State File' $deployer_tfstate_key + 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" | tr -d \") + 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=$(cat ${deployer_environment_file_name} | grep keyvault= | awk -F'=' '{print $2}' | xargs) ; echo 'Deployer Key Vault' ${key_vault} + key_vault=$(grep "^keyvault=" ${deployer_environment_file_name} | awk -F'=' '{print $2}' | xargs) else - key_vault=${az_var}; echo 'Deployer Key Vault' ${key_vault} + 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" | tr -d \") + 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=$(cat ${deployer_environment_file_name} | grep REMOTE_STATE_SA | awk -F'=' '{print $2}' | xargs) ; echo 'Terraform state file storage account' $REMOTE_STATE_SA + REMOTE_STATE_SA=$(grep "^REMOTE_STATE_SA" ${deployer_environment_file_name} | awk -F'=' '{print $2}' | xargs) ; else - REMOTE_STATE_SA=${az_var}; echo 'Terraform state file storage account' $REMOTE_STATE_SA + 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" | tr -d \") + 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=$(cat ${deployer_environment_file_name} | grep STATE_SUBSCRIPTION | awk -F'=' '{print $2}' | xargs) ; echo 'Terraform state file subscription' $STATE_SUBSCRIPTION + STATE_SUBSCRIPTION=$(grep "^STATE_SUBSCRIPTION" ${deployer_environment_file_name} | awk -F'=' '{print $2}' | xargs) else - STATE_SUBSCRIPTION=${az_var}; echo 'Terraform state file subscription' $STATE_SUBSCRIPTION + STATE_SUBSCRIPTION=${az_var} + fi - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "ARM_SUBSCRIPTION_ID.value" | tr -d \") + 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 ARM_SUBSCRIPTION_ID was not defined." - exit 2 - else - echo 'Target subscription' $WL_ARM_SUBSCRIPTION_ID + 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" | tr -d \") + 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=$(cat ${workload_environment_file_name} | grep workloadkeyvault | awk -F'=' '{print $2}' | xargs) ; echo 'Workload Key Vault' ${workload_key_vault} - fi + 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) ; echo 'Workload Key Vault' ${workload_key_vault} + export workload_key_vault=$(Workload_Key_Vault) + fi - else - deployer_tfstate_key=$(cat ${workload_environment_file_name} | grep deployer_tfstate_key | awk -F'=' '{print $2}' | xargs) ; echo 'Deployer State File' $deployer_tfstate_key - key_vault=$(cat ${workload_environment_file_name} | grep workload_key_vault= -m1 | awk -F'=' '{print $2}' | xargs) ; echo 'Deployer Key Vault' ${key_vault} - REMOTE_STATE_SA=$(cat ${workload_environment_file_name} | grep REMOTE_STATE_SA | awk -F'=' '{print $2}' | xargs) ; echo 'Terraform state file storage account' $REMOTE_STATE_SA - STATE_SUBSCRIPTION=$(cat ${workload_environment_file_name} | grep STATE_SUBSCRIPTION | awk -F'=' '{print $2}' | xargs) ; echo 'Terraform state file subscription' $STATE_SUBSCRIPTION - fi + else + deployer_tfstate_key=$(grep "^deployer_tfstate_key=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) - secrets_set=1 - echo -e "$green--- az login ---$reset" + key_vault=$(grep -m1 "^workload_key_vault=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) ; - if [ $LOGON_USING_SPN == "true" ]; then - echo "Using SPN" - az login --service-principal --username $CP_ARM_CLIENT_ID --password=$CP_ARM_CLIENT_SECRET --tenant $CP_ARM_TENANT_ID --output none - else - echo "Using MSI" - export ARM_USE_MSI=true - export ARM_SUBSCRIPTION_ID=$WL_ARM_SUBSCRIPTION_ID - unset ARM_TENANT_ID + REMOTE_STATE_SA=$(grep "^REMOTE_STATE_SA=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) - az login --identity --allow-no-subscriptions --output none - fi + 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" - 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 + echo -e "$cyan---Sourcing the deploy_server.sh file$reset" + . /etc/profile.d/deploy_server.sh if [ $USE_MSI != "true" ]; then - echo -e "$green --- Set secrets ---$reset" - $SAP_AUTOMATION_REPO_PATH/deploy/scripts/set_secrets.sh --workload --vault "${key_vault}" --environment "${ENVIRONMENT}" \ - --region "${LOCATION}" --subscription $WL_ARM_SUBSCRIPTION_ID --spn_id $WL_ARM_CLIENT_ID --spn_secret "${WL_ARM_CLIENT_SECRET}" \ - --tenant_id $WL_ARM_TENANT_ID --keyvault_subscription $STATE_SUBSCRIPTION - secrets_set=$? ; echo -e "$cyan Set Secrets returned $secrets_set $reset" - az keyvault set-policy --name "${key_vault}" --object-id $WL_ARM_OBJECT_ID --secret-permissions get list --subscription $STATE_SUBSCRIPTION --output none + 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 - az login --service-principal --username $CP_ARM_CLIENT_ID --password=$CP_ARM_CLIENT_SECRET --tenant $CP_ARM_TENANT_ID --output none - isUserAccessAdmin=$(az role assignment list --role "User Access Administrator" --subscription $STATE_SUBSCRIPTION --query "[?principalType=='ServicePrincipal'].principalId | [0] " --assignee $CP_ARM_CLIENT_ID) + 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) + 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 + if [ -n "${isUserAccessAdmin}" ]; then - echo -e "$green--- Set permissions ---$reset" - perms=$(az role assignment list --subscription ${STATE_SUBSCRIPTION} --role "Reader" --query "[?principalId=='$WL_ARM_CLIENT_ID'].principalId | [0]" -o tsv --only-show-errors) - if [ -z "$perms" ]; then - echo -e "$green --- Assign subscription permissions to $perms ---$reset" - az role assignment create --assignee-object-id $WL_ARM_OBJECT_ID --assignee-principal-type ServicePrincipal --role "Reader" --scope "/subscriptions/${STATE_SUBSCRIPTION}" --output none - fi + 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 Account Contributor" --scope "${tfstate_resource_id}" --query "[?principalId=='$WL_ARM_OBJECT_ID'].principalName | [0]" -o tsv --only-show-errors) - if [ -z "$perms" ]; then - echo "Assigning Storage Account Contributor permissions for $WL_ARM_OBJECT_ID to ${tfstate_resource_id}" - az role assignment create --assignee-object-id $WL_ARM_OBJECT_ID --assignee-principal-type ServicePrincipal --role "Storage Account Contributor" --scope "${tfstate_resource_id}" --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) + 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 --query "[?principalId=='$WL_ARM_OBJECT_ID'].principalId | [0]" -o 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-object-id $WL_ARM_OBJECT_ID --assignee-principal-type ServicePrincipal --role "Private DNS Zone Contributor" --scope $scope --output none + 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 - done - fi - resource_group_name=$(az keyvault show --name "${key_vault}" --query resourceGroup --subscription ${STATE_SUBSCRIPTION} -o tsv) + 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) + 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 --only-show-errors --query "[].principalId | [0]" --assignee $WL_ARM_OBJECT_ID -o tsv --only-show-errors) + 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 $WL_ARM_OBJECT_ID to ${vnet_resource_id}" - az role assignment create --assignee-object-id $WL_ARM_OBJECT_ID --assignee-principal-type ServicePrincipal --role "Network Contributor" --scope $vnet_resource_id --output none - fi + 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 - else - echo "##vso[task.logissue type=warning]Service Principal $CP_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 [ $LOGON_USING_SPN == "true" ]; then - echo "Logon Using SPN" - - 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 - export ARM_USE_MSI=false - 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 + 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 - export ARM_USE_MSI=false - 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 + 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 - - if [ $USE_MSI != "true" ]; then - $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 - return_code=$? - - echo "Return code: ${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 Key Vault' ${workload_key_vault} - export workload_prefix=$(cat ${workload_environment_file_name} | grep workload_zone_prefix= | awk -F'=' '{print $2}' | xargs) ; echo 'Workload 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 + 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 + 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 + 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 + fi + az logout --output none echo -e "$green--- Add & update files in the DevOps Repository ---$reset" - cd $(Build.Repository.LocalPath) - git pull + cd $(Build.Repository.LocalPath) + git pull - echo -e "$green--- Pull latest ---$reset" - cd $CONFIG_REPO_PATH - git pull + echo -e "$green--- Pull latest ---$reset" + cd $CONFIG_REPO_PATH + git pull - added=0 - if [ -f ${workload_environment_file_name} ]; then + 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 + 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 + 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 + 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 + fi - if [ -f ${workload_environment_file_name}.md ]; then + if [ -f ${workload_environment_file_name}.md ]; then echo "##vso[task.uploadsummary]${workload_environment_file_name}.md" - fi + fi echo -e "$green--- Adding variables to the variable group" $(variable_group) "---$reset" - if [ -n $VARIABLE_GROUP_ID ]; then + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + fi - if [ 0 != $return_code ]; then + 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." + error_message=$(cat ${workload_environment_file_name}.err) + echo "##vso[task.logissue type=error]Error message: $error_message." fi - fi + fi exit $return_code diff --git a/deploy/pipelines/03-sap-system-deployment.yaml b/deploy/pipelines/03-sap-system-deployment.yaml index 4a8dbc626e..c265b05ae8 100644 --- a/deploy/pipelines/03-sap-system-deployment.yaml +++ b/deploy/pipelines/03-sap-system-deployment.yaml @@ -114,19 +114,11 @@ stages: 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" - echo "" - echo "Agent: $(this_agent)" - echo "Organization: $(System.CollectionUri)" - echo "Project: $(System.TeamProject)" - echo "" - echo "Azure CLI version:" - echo "-------------------------------------------------" - az --version + 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) ; @@ -191,10 +183,20 @@ stages: *) 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 "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]" @@ -231,18 +233,20 @@ stages: fi echo -e "$green--- Configure devops CLI extension ---$reset" - az config set extension.use_dynamic_install=yes_without_prompt --output none + az config set extension.use_dynamic_install=yes_without_prompt --output none --only-show-errors - az extension add --name azure-devops --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 + 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]") - echo '$(variable_group) id: ' $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 val '%-15s' "$(variable_group) id:" + echo "$val $VARIABLE_GROUP_ID" echo -e "$green--- Login ---$reset" if [ -z $USE_MSI ]; then @@ -255,73 +259,96 @@ stages: 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 "Using SPN" - - 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 - export ARM_USE_MSI=false - 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 + + 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 - 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 + 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" | tr -d \") + 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) ; echo 'Terraform state file subscription' $STATE_SUBSCRIPTION + export STATE_SUBSCRIPTION=$(grep STATE_SUBSCRIPTION ${environment_file_name} | awk -F'=' '{print $2}' | xargs) else - export STATE_SUBSCRIPTION=${az_var} ; echo 'Terraform state file subscription' $STATE_SUBSCRIPTION + 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" | tr -d \") + 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) ; echo 'Terraform state file storage account' $REMOTE_STATE_SA + export REMOTE_STATE_SA=$(grep REMOTE_STATE_SA ${environment_file_name} | awk -F'=' '{print $2}' | xargs) else - export REMOTE_STATE_SA=${az_var} ; echo 'Terraform state file storage account' $REMOTE_STATE_SA + 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" | tr -d \") + 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) ; echo 'Deployer State File' $deployer_tfstate_key + export deployer_tfstate_key=$(grep deployer_tfstate_key ${environment_file_name} | awk -F'=' '{print $2}' | xargs) else - export deployer_tfstate_key=${az_var} ; echo 'Deployer State File' $deployer_tfstate_key + 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) ; echo 'landscape_tfstate_key' $landscape_tfstate_key + export landscape_tfstate_key=$(grep landscape_tfstate_key= ${environment_file_name} | awk -F'=' '{print $2}' | xargs) else - export landscape_tfstate_key=${az_var} ; echo 'landscape_tfstate_key' $landscape_tfstate_key + 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" | tr -d \") + 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) ; echo 'Deployer Key Vault' $key_vault + export key_vault=$(grep keyvault= ${environment_file_name} | awk -F'=' '{print $2}' | xargs) else - export key_vault=${az_var} ; echo 'Deployer Key Vault' $key_vault + 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) ; echo 'Workload Key Vault' ${workload_key_vault} + export workload_key_vault=$(grep workloadkeyvault= ${environment_file_name} | awk -F'=' '{print $2}' | xargs) else - export workload_key_vault=${az_var} ; echo 'Workload Key Vault' ${workload_key_vault} + 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 \ diff --git a/deploy/pipelines/04-sap-software-download.yaml b/deploy/pipelines/04-sap-software-download.yaml index 0966999505..b677c49054 100644 --- a/deploy/pipelines/04-sap-software-download.yaml +++ b/deploy/pipelines/04-sap-software-download.yaml @@ -62,10 +62,10 @@ stages: green="\e[1;32m" ; reset="\e[0m" ; boldred="\e[1;31m" echo -e "$green--- Configure devops CLI extension ---$reset" - az config set extension.use_dynamic_install=yes_without_prompt --output none + az config set extension.use_dynamic_install=yes_without_prompt --output none --only-show-errors export AZURE_DEVOPS_EXT_PAT=$(System.AccessToken) - az devops configure --defaults organization=$(System.CollectionUri) project='$(System.TeamProject)' --output none + az devops configure --defaults organization=$(System.CollectionUri) project='$(System.TeamProject)' --output none --only-show-errors echo -e "$green--- Validations ---$reset" if [ ! -f ${environment_file_name} ]; then @@ -95,12 +95,13 @@ stages: echo -e "$green--- az login ---$reset" if [ "$USE_MSI" = "true" ]; then - echo "Using MSI" + echo "Deployment credentials: Managed Identity" source /etc/profile.d/deploy_server.sh else az login --service-principal --username $ARM_CLIENT_ID --password=${ARM_CLIENT_SECRET} --tenant $ARM_TENANT_ID --output none return_code=$? + echo "Deployment credentials: Service Principal" if [ 0 != $return_code ]; then echo -e "$boldred--- Login failed ---$reset" echo "##vso[task.logissue type=error]az login failed." @@ -112,18 +113,20 @@ stages: echo -e "$green--- Get key_vault name ---$reset" export VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(variable_group)'].id | [0]") - echo '$(variable_group) id: ' $VARIABLE_GROUP_ID + printf -v val '%-15s' "$(variable_group) id:" + echo "$val $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 - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Deployer_Key_Vault.value" | tr -d \") + 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 kv_name=${az_var}; echo "Key Vault="$kv_name else - kv_name=$(cat .sap_deployment_automation/$(environment_code)$(location_code) | grep keyvault |awk -F'=' '{print $2}'); echo "Key Vault="$kv_name + kv_name=$(cat .sap_deployment_automation/$(environment_code)$(location_code) | grep keyvault |awk -F'=' '{print $2}') fi + echo "Keyvault: $kv_name" echo "##vso[task.setvariable variable=KV_NAME;isOutput=true]$kv_name" echo -e "$green--- BoM $(bom) ---$reset" @@ -202,10 +205,11 @@ stages: fi if [ "$USE_MSI" = "true" ]; then - echo "Using MSI" + echo "Deployment credentials: Managed Identity" source /etc/profile.d/deploy_server.sh else + echo "Deployment credentials: Service Principal" if [ ! -n $ARM_CLIENT_ID ]; then echo "##vso[task.logissue type=error]Variable ARM_CLIENT_ID was not defined." exit 2 diff --git a/deploy/pipelines/05-DB-and-SAP-installation.yaml b/deploy/pipelines/05-DB-and-SAP-installation.yaml index f8d5303427..189b3877e0 100644 --- a/deploy/pipelines/05-DB-and-SAP-installation.yaml +++ b/deploy/pipelines/05-DB-and-SAP-installation.yaml @@ -159,20 +159,20 @@ stages: cd $HOME echo -e "$green--- Configure devops CLI extension ---$reset" - az config set extension.use_dynamic_install=yes_without_prompt --output none + az config set extension.use_dynamic_install=yes_without_prompt --output none --only-show-errors - az extension add --name azure-devops --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 echo -e "$green--- Validations ---$reset" - ENVIRONMENT=$(echo ${SAP_SYSTEM_CONFIGURATION_NAME} | awk -F'-' '{print $1}' | xargs) ; echo Environment $ENVIRONMENT - LOCATION=$(echo ${SAP_SYSTEM_CONFIGURATION_NAME} | awk -F'-' '{print $2}' | xargs) ; echo Location $LOCATION - NETWORK=$(echo ${SAP_SYSTEM_CONFIGURATION_NAME} | awk -F'-' '{print $3}' | xargs) ; echo Virtual network logical name $NETWORK - SID=$(echo ${SAP_SYSTEM_CONFIGURATION_NAME} | awk -F'-' '{print $4}' | xargs) ; echo SID $SID + ENVIRONMENT=$(echo ${SAP_SYSTEM_CONFIGURATION_NAME} | awk -F'-' '{print $1}' | xargs) + LOCATION=$(echo ${SAP_SYSTEM_CONFIGURATION_NAME} | awk -F'-' '{print $2}' | xargs) + NETWORK=$(echo ${SAP_SYSTEM_CONFIGURATION_NAME} | awk -F'-' '{print $3}' | xargs) + SID=$(echo ${SAP_SYSTEM_CONFIGURATION_NAME} | awk -F'-' '{print $4}' | xargs) - environment_file_name=$HOME/.sap_deployment_automation/$ENVIRONMENT$LOCATION$NETWORK ; echo configuration_file $environment_file_name - params_file=$HOME/SYSTEM/${SAP_SYSTEM_CONFIGURATION_NAME}/sap-parameters.yaml ; echo sap_parameters_file $params_file + environment_file_name=$HOME/.sap_deployment_automation/$ENVIRONMENT$LOCATION$NETWORK + params_file=$HOME/SYSTEM/${SAP_SYSTEM_CONFIGURATION_NAME}/sap-parameters.yaml if [ "azure pipelines" = "$(this_agent)" ]; then echo "##vso[task.logissue type=error]Please use a self hosted agent for this playbook. Define it in the SDAF-${ENVIRONMENT} variable group using the 'POOL' variable." @@ -206,7 +206,6 @@ stages: dos2unix -q $HOME/SYSTEM/${SAP_SYSTEM_CONFIGURATION_NAME}/${SID}_hosts.yaml export VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(variable_group)'].id | [0]") - echo '$(variable_group) id: ' $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 @@ -219,6 +218,19 @@ stages: echo "##vso[task.setvariable variable=FOLDER;isOutput=true]$HOME/SYSTEM/${SAP_SYSTEM_CONFIGURATION_NAME}" echo "##vso[task.setvariable variable=HOSTS;isOutput=true]${SID}_hosts.yaml" + echo "Environment: $ENVIRONMENT" + echo "Location: $LOCATION" + echo "Virtual network logical name: $NETWORK" + echo "SAP Application BoM: $BOM_BASE_NAME" + printf -v val '%-15s' "$(variable_group) id:" + echo "$val $VARIABLE_GROUP_ID" + + echo "SID: ${SID}" + echo "Folder: $HOME/SYSTEM/${SAP_SYSTEM_CONFIGURATION_NAME}" + echo "Hosts file: ${SID}_hosts.yaml" + echo "sap_parameters_file: $params_file" + echo "Configuration file: $environment_file_name" + echo -e "$green--- Get Files from the DevOps Repository ---$reset" cd ${CONFIG_REPO_PATH}/$(Deployment_Configuration_Path)/SYSTEM/${SAP_SYSTEM_CONFIGURATION_NAME} sap_params_updated=0 @@ -236,25 +248,34 @@ stages: az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "${NETWORK}"Workload_Key_Vault.value --output tsv) if [ -z ${az_var} ]; then - export workload_key_vault=$(cat "${environment_file_name}" | grep workloadkeyvault | awk -F'=' '{print $2}' | xargs) ; echo 'Workload Key Vault' ${workload_key_vault} + export workload_key_vault=$(cat "${environment_file_name}" | grep workloadkeyvault | awk -F'=' '{print $2}' | xargs) else - export workload_key_vault=${az_var} ; echo 'Workload Key Vault' ${workload_key_vault} ; + export workload_key_vault=${az_var} fi + echo "Workload Key Vault: ${workload_key_vault}" + echo "SID: ${SID}" + echo "Folder: $HOME/SYSTEM/${SAP_SYSTEM_CONFIGURATION_NAME}" + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "${NETWORK}"Workload_Secret_Prefix.value --output tsv) if [ -z ${az_var} ]; then - export workload_prefix=$(cat "${environment_file_name}" | grep workload_zone_prefix | awk -F'=' '{print $2}' | xargs) ; echo 'Workload Prefix' ${workload_prefix} + export workload_prefix=$(cat "${environment_file_name}" | grep workload_zone_prefix | awk -F'=' '{print $2}' | xargs) else - export workload_prefix=${az_var} ; echo 'Workload Prefix' ${workload_prefix}; + export workload_prefix=${az_var} fi + echo "Workload Prefix: ${workload_prefix}" + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query Terraform_Remote_Storage_Subscription.value --output tsv) if [ -z ${az_var} ]; then - export control_plane_subscription=$(cat "${environment_file_name}" | grep STATE_SUBSCRIPTION | awk -F'=' '{print $2}' | xargs) ; echo 'Control Plane Subscription' ${control_plane_subscription} + export control_plane_subscription=$(cat "${environment_file_name}" | grep STATE_SUBSCRIPTION | awk -F'=' '{print $2}' | xargs) else - export control_plane_subscription=${az_var} ; echo 'Control Plane Subscription' ${control_plane_subscription} + export control_plane_subscription=${az_var} fi + echo "Control Plane Subscription: ${control_plane_subscription}" + echo "Workload Prefix: ${workload_prefix}" + if [[ $EXTRA_PARAMETERS = "'$(EXTRA_PARAMETERS)'" ]]; then new_parameters=$PIPELINE_EXTRA_PARAMETERS else @@ -274,11 +295,12 @@ stages: # If the deployer_file exists we run on a deployer configured by the framework instead of a azdo hosted one deployer_file=/etc/profile.d/deploy_server.sh if [ "$USE_MSI" = "true" ]; then - echo "Using MSI" + echo "Deployment credentials: Managed Identity" source /etc/profile.d/deploy_server.sh az account set --subscription $control_plane_subscription else + echo "Deployment credentials: Service Principal" if [ ! -n $AZURE_CLIENT_ID ]; then echo "##vso[task.logissue type=error]Variable ARM_CLIENT_ID was not defined." exit 2 diff --git a/deploy/pipelines/10-remover-terraform.yaml b/deploy/pipelines/10-remover-terraform.yaml index cd4c80dded..08828c6ca1 100644 --- a/deploy/pipelines/10-remover-terraform.yaml +++ b/deploy/pipelines/10-remover-terraform.yaml @@ -7,193 +7,218 @@ # +------------------------------------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 displayName: "Removing the SAP System" condition: and(not(failed()), not(canceled()), eq(${{ parameters.cleanup_sap }}, true)) variables: - - template: variables/10-remover-terraform-variables.yaml + - 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 }} + 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" + - job: Remove_SAP_systems + displayName: "Removing the SAP System" variables: - - group: SDAF-${{ parameters.workload_environment }} + - group: SDAF-${{ parameters.workload_environment }} workspace: clean: all steps: - - template: templates\download.yaml + - template: templates\download.yaml - bash: | #!/bin/bash - green="\e[1;32m" ; reset="\e[0m" + 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 + 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 + 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 [ $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_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_SECRET ]; then - echo "##vso[task.logissue type=error]Variable ARM_CLIENT_SECRET was not defined." - 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 - 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" + echo -e "$green--- Install dos2unix ---$reset" sudo apt-get -qq install dos2unix - echo -e "$green --- Install terraform ---$reset" + 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 + 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 [ $LOGON_USING_SPN == "true" ]; then - echo "Logon Using SPN" - - 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 - export ARM_USE_MSI=false - 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 + 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 - else - export ARM_USE_MSI=true - 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 + 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 + 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]") - echo '$(variable_group) id: ' $VARIABLE_GROUP_ID - if [ -z ${VARIABLE_GROUP_ID} ]; then + 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 + 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) + 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" - - 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 + 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" ;; @@ -250,299 +275,345 @@ stages: "WUS2") LOCATION_IN_FILENAME="westus2" ;; "WUS3") LOCATION_IN_FILENAME="westus3" ;; *) LOCATION_IN_FILENAME="westeurope" ;; - esac + 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 "Environment(filename): $ENVIRONMENT_IN_FILENAME" - echo "Location(filename): $LOCATION_IN_FILENAME" - echo "Network(filename): $NETWORK_IN_FILENAME" - echo "SID(filename): $SID_IN_FILENAME" + echo "" - if [ $ENVIRONMENT != $ENVIRONMENT_IN_FILENAME ]; then + 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 + fi - if [ $LOCATION != $LOCATION_IN_FILENAME ]; then + 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 + fi - if [ $NETWORK != $NETWORK_IN_FILENAME ]; then + 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 + fi - if [ $SID != $SID_IN_FILENAME ]; then + 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 + fi # Check if running on deployer if [[ ! -f /etc/profile.d/deploy_server.sh ]]; then - if [ $LOGON_USING_SPN == "true" ]; then - echo "Logon Using SPN" - - 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 - export ARM_USE_MSI=false - 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 + 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 - export ARM_USE_MSI=true - az login --identity --allow-no-subscriptions --output none - fi else - echo -e "$green --- Running on deployer ---$reset" - - if [ $LOGON_USING_SPN == "true" ]; then - echo "Using SPN" - - 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 - export ARM_USE_MSI=false - 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 + 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 - else - 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" | tr -d \") - if [ -z ${az_var} ]; then - export workload_key_vault=$(cat "${workload_environment_file_name}" | grep workloadkeyvault | awk -F'=' '{print $2}' | xargs) ; echo 'Workload Key Vault' ${workload_key_vault} - else - export workload_key_vault="${az_var}" ; echo 'Workload Key Vault' ${workload_key_vault} - fi - - if [ -n $(Deployer_Key_Vault) ]; then - export key_vault=$(Deployer_Key_Vault) ; echo 'Deployer Key Vault' ${key_vault} - else - export key_vault=$(cat ${workload_environment_file_name} | grep keyvault= -m1 | awk -F'=' '{print $2}' | xargs) ; echo 'Deployer Key Vault' ${key_vault} - fi - - az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Subscription.value" | tr -d \") - if [ -n "${az_var}" ]; then - STATE_SUBSCRIPTION="${az_var}" ; echo 'Terraform state file subscription' $STATE_SUBSCRIPTION - else - STATE_SUBSCRIPTION=$(cat ${workload_environment_file_name} | grep STATE_SUBSCRIPTION= | awk -F'=' '{print $2}' | xargs) ; echo 'Terraform state file subscription' $STATE_SUBSCRIPTION - fi - - az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Account_Name.value" | tr -d \") - if [ -n "${az_var}" ]; then - REMOTE_STATE_SA="${az_var}" ; echo 'Terraform state file storage account' $REMOTE_STATE_SA - else - REMOTE_STATE_SA=$(cat ${workload_environment_file_name} | grep REMOTE_STATE_SA | awk -F'=' '{print $2}' | xargs) ; echo 'Terraform state file storage account' $REMOTE_STATE_SA - 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 "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" - cd $CONFIG_REPO_PATH/SYSTEM/$(sap_system_folder) - ${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=$? + ${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 + 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." + 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 + 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) + cd $(Build.Repository.LocalPath) - changed=0 - # Pull changes - git checkout -q $(Build.SourceBranchName) - git pull origin $(Build.SourceBranchName) + changed=0 + # Pull changes + git checkout -q $(Build.SourceBranchName) + git pull origin $(Build.SourceBranchName) - if [ 0 == $return_code ]; then + 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 + 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 + 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 + 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 + 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 + 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) + 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 + fi exit $return_code - displayName: "Remove SAP system" + displayName: "Remove SAP system" env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - WL_ARM_SUBSCRIPTION_ID: $(ARM_SUBSCRIPTION_ID) - WL_ARM_CLIENT_ID: $(ARM_CLIENT_ID) - WL_ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET) - WL_ARM_TENANT_ID: $(ARM_TENANT_ID) - AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) + 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) + CONFIG_REPO_PATH: ${{ parameters.config_repo_path }}/$(Deployment_Configuration_Path) + LOGON_USING_SPN: $(Logon_Using_SPN) + USE_MSI: $(Use_MSI) - failOnStderr: false + 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 + - 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 }} + 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 + - job: Remove_SAP_workload_zone + displayName: Remove the SAP Workload Zone variables: - - group: SDAF-${{ parameters.workload_environment }} + - group: SDAF-${{ parameters.workload_environment }} workspace: - clean: all + clean: all steps: - - template: templates\download.yaml + - template: templates\download.yaml - bash: | #!/bin/bash - #!/bin/bash - green="\e[1;32m" ; reset="\e[0m" + 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 + HOME_CONFIG=${CONFIG_REPO_PATH} + cd $HOME_CONFIG; mkdir -p .sap_deployment_automation - if [ ! -f LANDSCAPE/$(workload_zone_folder)/$(workload_zone_configuration_file) ]; then + 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 + fi - if [ -z $WL_ARM_SUBSCRIPTION_ID ]; then + if [ -z $WL_ARM_SUBSCRIPTION_ID ]; then echo "##vso[task.logissue type=error]Variable ARM_SUBSCRIPTION_ID was not defined." exit 2 - fi + fi - if [ -z $WL_ARM_CLIENT_ID ]; then + if [ -z $WL_ARM_CLIENT_ID ]; then echo "##vso[task.logissue type=error]Variable ARM_CLIENT_ID was not defined." exit 2 - fi + fi - if [ -z $WL_ARM_CLIENT_SECRET ]; then + if [ -z $WL_ARM_CLIENT_SECRET ]; then echo "##vso[task.logissue type=error]Variable ARM_CLIENT_SECRET was not defined." exit 2 - fi + fi - if [ -z $WL_ARM_TENANT_ID ]; then + if [ -z $WL_ARM_TENANT_ID ]; then echo "##vso[task.logissue type=error]Variable ARM_TENANT_ID was not defined." exit 2 - fi + fi # Check if running on deployer if [[ ! -f /etc/profile.d/deploy_server.sh ]]; then - echo -e "$green --- Install dos2unix ---$reset" + echo -e "$green--- Install dos2unix ---$reset" sudo apt-get -qq install dos2unix - echo -e "$green --- Install terraform ---$reset" + 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 + 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 + 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 config set extension.use_dynamic_install=yes_without_prompt --output none - az devops configure --defaults organization=$(System.CollectionUri) project='$(System.TeamProject)' --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]") - echo '$(variable_group) id: ' $VARIABLE_GROUP_ID - if [ -z ${VARIABLE_GROUP_ID} ]; then + 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 + 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) + 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) - echo Environment: ${ENVIRONMENT} - echo Location: ${LOCATION} - echo Network: ${NETWORK} + 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 + 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" ;; @@ -599,187 +670,239 @@ stages: "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(filename): $ENVIRONMENT_IN_FILENAME" - echo "Location(filename): $LOCATION_IN_FILENAME" - echo "Network(filename): $NETWORK_IN_FILENAME" - - if [ $ENVIRONMENT != $ENVIRONMENT_IN_FILENAME ]; then + 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 + fi - if [ $LOCATION != $LOCATION_IN_FILENAME ]; then + 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 + fi - if [ $NETWORK != $NETWORK_IN_FILENAME ]; then + 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 + fi - if [ -z $(Deployer_Key_Vault) ]; then + 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 + 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") - if [ -z ${az_var} ]; then - export workload_key_vault=$(cat "${workload_environment_file_name}" | grep workloadkeyvault | awk -F'=' '{print $2}' | xargs) ; echo 'Workload Key Vault' ${workload_key_vault} - else - export workload_key_vault="${az_var}" ; echo 'Workload Key Vault' ${workload_key_vault} - fi - - az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Deployer_Key_Vault.value" | tr -d \") - if [ -n "${az_var}" ]; then - key_vault="${az_var}" ; echo 'Deployer Key Vault' ${key_vault} - else - key_vault=$(cat ${workload_environment_file_name} | grep keyvault= -m1 | awk -F'=' '{print $2}' | xargs) ; echo 'Deployer Key Vault' ${key_vault} - fi - - az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Subscription.value" | tr -d \") - if [ -n "${az_var}" ]; then - STATE_SUBSCRIPTION="${az_var}" ; echo 'Terraform state file subscription' $STATE_SUBSCRIPTION - else - STATE_SUBSCRIPTION=$(cat ${workload_environment_file_name} | grep STATE_SUBSCRIPTION | awk -F'=' '{print $2}' | xargs) ; echo 'Terraform state file subscription' $STATE_SUBSCRIPTION - fi - - az_var=$(az pipelines variable-group variable list --group-id ${PARENT_VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Account_Name.value" | tr -d \") - if [ -n "${az_var}" ]; then - REMOTE_STATE_SA="${az_var}" ; echo 'Terraform state file storage account' $REMOTE_STATE_SA - else - REMOTE_STATE_SA=$(cat ${workload_environment_file_name} | grep REMOTE_STATE_SA | awk -F'=' '{print $2}' | xargs) ; echo 'Terraform state file storage account' $REMOTE_STATE_SA - fi + fi - # Check if running on deployer - if [[ ! -f /etc/profile.d/deploy_server.sh ]]; then + 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 - 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 + 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 - echo -e "$green --- Running on deployer ---$reset" + export landscape_tfstate_key=$(grep "^landscape_tfstate_key=" ${workload_environment_file_name} | awk -F'=' '{print $2}' | xargs) + fi - if [ $LOGON_USING_SPN == "true" ]; then - echo "Using SPN" + 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 - 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 - export ARM_USE_MSI=false - az login --service-principal --username $WL_ARM_CLIENT_ID --password=$WL_ARM_CLIENT_SECRET --tenant $WL_ARM_TENANT_ID --output none + 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 + 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 - else - 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) + 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 \ - --ado + $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=$? + 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 + #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 + 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 + cd $(Build.Repository.LocalPath) + changed=0 + git checkout -q $(Build.SourceBranchName) + git pull - if [ 0 == $return_code ]; then + 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}" + if [ -f "${workload_environment_file_name}" ]; then + git rm -q -f ${workload_environment_file_name} + echo "Removed ${workload_environment_file_name}" - changed=1 + changed=1 fi - if [ -f ${workload_environment_file_name}.md ]; then - git rm -q --ignore-unmatch -f ${workload_environment_file_name}.md - changed=1 + 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 + 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) + 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" + 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_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_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 + 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 + fi exit $return_code - displayName: Remove SAP workload_zone + displayName: Remove SAP workload_zone env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - WL_ARM_SUBSCRIPTION_ID: $(ARM_SUBSCRIPTION_ID) - WL_ARM_CLIENT_ID: $(ARM_CLIENT_ID) - WL_ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET) - WL_ARM_TENANT_ID: $(ARM_TENANT_ID) - AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) + 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) + CONFIG_REPO_PATH: ${{ parameters.config_repo_path }}/$(Deployment_Configuration_Path) + LOGON_USING_SPN: $(Logon_Using_SPN) + USE_MSI: $(Use_MSI) - failOnStderr: false + failOnStderr: false diff --git a/deploy/pipelines/11-remover-arm-fallback.yaml b/deploy/pipelines/11-remover-arm-fallback.yaml index bc2d5d8e38..1baad59df9 100644 --- a/deploy/pipelines/11-remover-arm-fallback.yaml +++ b/deploy/pipelines/11-remover-arm-fallback.yaml @@ -319,7 +319,7 @@ stages: return_code=0 export VARIABLE_GROUP_ID=$(az pipelines variable-group list --query "[?name=='$(parent_variable_group)'].id | [0]"); echo "Variable group: " $VARIABLE_GROUP_ID - variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "CP_ARM_SUBSCRIPTION_ID.value" | tr -d \") + variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "CP_ARM_SUBSCRIPTION_ID.value" --out tsv) if [ -z $variable_value ]; then subscription=$ARM_SUBSCRIPTION_ID else @@ -406,42 +406,42 @@ stages: 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" ) + variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Account_Name.value" --out tsv) 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" ) + variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Resource_Group_Name.value" --out tsv) 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" ) + variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Terraform_Remote_Storage_Subscription.value" --out tsv) 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" ) + variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Deployer_State_FileName.value" --out tsv) 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" ) + variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "Deployer_Key_Vault.value" --out tsv) 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" ) + variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WEBAPP_URL_BASE.value" --out tsv) 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" ) + variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WEBAPP_IDENTITY.value" --out tsv) 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" ) + variable_value=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WEBAPP_ID.value" --out tsv) if [ ${#variable_value} != 0 ]; then az pipelines variable-group variable delete --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_ID --yes --only-show-errors fi diff --git a/deploy/pipelines/12-remove-control-plane.yaml b/deploy/pipelines/12-remove-control-plane.yaml index 4ed304869e..8e5e5458ba 100644 --- a/deploy/pipelines/12-remove-control-plane.yaml +++ b/deploy/pipelines/12-remove-control-plane.yaml @@ -66,9 +66,7 @@ stages: set -u echo "##vso[build.updatebuildnumber]Removing the control plane defined in $(deployer_folder) $(library_folder)" - green="\e[1;32m" ; reset="\e[0m" - - + 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 @@ -81,13 +79,13 @@ stages: 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 - az config set extension.dynamic_install_allow_preview=true + 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]") - echo '$(parent_variable_group) id: ' $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 @@ -131,8 +129,8 @@ stages: rm -f terraform_$(tf_version)_linux_amd64.zip fi if [ $USE_MSI != "true" ]; then - echo "Login using SPN" - export ARM_USE_MSI=false + 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 @@ -141,6 +139,7 @@ stages: 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 @@ -152,12 +151,10 @@ stages: 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--- Running the remove region script that destroys deployer VM and SAP library ---$reset" + 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') - echo Environment: ${ENVIRONMENT} - echo Location: ${LOCATION} ENVIRONMENT_IN_FILENAME=$(echo $(deployer_folder) | awk -F'-' '{print $1}' | xargs ) LOCATION_CODE=$(echo $(deployer_folder) | awk -F'-' '{print $2}' | xargs ) @@ -220,8 +217,12 @@ stages: *) LOCATION_IN_FILENAME="westeurope" ;; esac - echo "Environment(filename): $ENVIRONMENT_IN_FILENAME" - echo "Location(filename): $LOCATION_IN_FILENAME" + 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" @@ -233,41 +234,49 @@ stages: exit 2 fi - deployer_environment_file_name=$HOME/.sap_deployment_automation/$ENVIRONMENT$LOCATION_CODE; echo "Environment file: " $deployer_environment_file_name + 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" | tr -d \") + 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}" ; echo 'Deployer Key Vault' ${key_vault} + key_vault="${az_var}" else echo "Reading key vault from environment file" - key_vault=$(cat ${deployer_environment_file_name} | grep keyvault= -m1 | awk -F'=' '{print $2}' | xargs) ; echo 'Deployer Key Vault' ${key_vault} + key_vault=$(grep -m "^keyvault=" ${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_Account_Name.value" | tr -d \") + 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}" ; echo 'Terraform state file storage account' $REMOTE_STATE_SA + REMOTE_STATE_SA="${az_var}" + else echo "Reading storage account from environment file" - REMOTE_STATE_SA=$(cat ${deployer_environment_file_name} | grep REMOTE_STATE_SA | awk -F'=' '{print $2}' | xargs) ; echo 'Terraform state file storage account' $REMOTE_STATE_SA + 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" | tr -d \") + 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}" ; echo 'Terraform state file resource group' $REMOTE_STATE_RG + REMOTE_STATE_RG="${az_var}" else - REMOTE_STATE_RG=$(cat ${deployer_environment_file_name} | grep REMOTE_STATE_RG | awk -F'=' '{print $2}' | xargs) ; echo 'Terraform state file resource group' $REMOTE_STATE_RG + 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" | tr -d \") + 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=$(cat ${deployer_environment_file_name} | grep deployer_random_id= | awk -F'=' '{print $2}' | xargs) + deployer_random_id=$(grep "^deployer_random_id=" ${deployer_environment_file_name} | awk -F'=' '{print $2}' | xargs) fi fi - export STATE_SUBSCRIPTION=$ARM_SUBSCRIPTION_ID ; echo 'Terraform state file subscription' $STATE_SUBSCRIPTION + 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) @@ -290,7 +299,7 @@ stages: return_code=$? - echo "Return code from remove_controlplane $return_code." + echo "Return code from remove_controlplane: $return_code." echo -e "$green--- Remove Control Plane Part 1 ---$reset" cd $CONFIG_REPO_PATH @@ -306,7 +315,7 @@ stages: echo "Compressing the state file." sudo apt install zip pass=$(echo $DEPLOYER_RANDOM_ID_SEED | sed 's/-//g') - zip -j -P "${pass}" DEPLOYER/$(deployer_folder)/state DEPLOYER/$(deployer_folder)/terraform.tfstate + 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 @@ -318,7 +327,7 @@ stages: sudo apt install zip echo "Compressing the library state file" pass=$(echo $DEPLOYER_RANDOM_ID_SEED | sed 's/-//g') - zip -j -P "${pass}" ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder)/state ${CONFIG_REPO_PATH}/LIBRARY/$(library_folder)/terraform.tfstate + 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 @@ -417,15 +426,15 @@ stages: inlineScript: | #!/bin/bash echo "##vso[build.updatebuildnumber]Removing the control plane defined in $(deployer_folder) $(library_folder)" - green="\e[1;32m" ; reset="\e[0m" + 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 "use Service Principal" + 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 "use MSI" + echo -e "$cyan--- Remove using Managed Identity ---$reset" export ARM_CLIENT_ID=$servicePrincipalId export ARM_TENANT_ID=$tenantId export ARM_CLIENT_SECRET=$servicePrincipalKey @@ -463,12 +472,16 @@ stages: 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 + 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]") - echo '$(variable_group) id: ' $VARIABLE_GROUP_ID + + 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 @@ -500,12 +513,10 @@ stages: 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--- Running the remove region script that destroys deployer VM and SAP library ---$reset" + 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') - echo Environment: ${ENVIRONMENT} - echo Location: ${LOCATION} ENVIRONMENT_IN_FILENAME=$(echo $(deployer_folder) | awk -F'-' '{print $1}' | xargs ) LOCATION_CODE=$(echo $(deployer_folder) | awk -F'-' '{print $2}' | xargs ) @@ -568,8 +579,13 @@ stages: *) LOCATION_IN_FILENAME="westeurope" ;; esac - echo "Environment(filename): $ENVIRONMENT_IN_FILENAME" - echo "Location(filename): $LOCATION_IN_FILENAME" + 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" @@ -583,13 +599,15 @@ stages: 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; echo "Environment file: " $deployer_environment_file_name + 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 "Login using SPN" - export ARM_USE_MSI=false + 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 @@ -600,14 +618,16 @@ stages: 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" | tr -d \") + 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}" ; echo 'Deployer Key Vault' ${key_vault} + key_vault="${az_var}" else echo "Reading key vault from environment file" - key_vault=$(cat ${deployer_environment_file_name} | grep keyvault= -m1 | awk -F'=' '{print $2}' | xargs) ; echo 'Deployer Key Vault' ${key_vault} + 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 @@ -633,7 +653,7 @@ stages: return_code=$? - echo "Return code from remove_deployer $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 diff --git a/deploy/scripts/New-SDAFDevopsProject.ps1 b/deploy/scripts/New-SDAFDevopsProject.ps1 index c0ac01fdd0..bb5181f51c 100644 --- a/deploy/scripts/New-SDAFDevopsProject.ps1 +++ b/deploy/scripts/New-SDAFDevopsProject.ps1 @@ -466,7 +466,7 @@ Write-Host "Creating the variable group SDAF-General" -ForegroundColor Green $general_group_id = (az pipelines variable-group list --query "[?name=='SDAF-General'].id | [0]" --only-show-errors) if ($general_group_id.Length -eq 0) { - az pipelines variable-group create --name SDAF-General --variables ANSIBLE_HOST_KEY_CHECKING=false Deployment_Configuration_Path=WORKSPACES Branch=main tf_version="1.9.5" ansible_core_version="2.15" S-Username=$SUserName S-Password=$SPassword --output yaml --authorize true --output none + az pipelines variable-group create --name SDAF-General --variables ANSIBLE_HOST_KEY_CHECKING=false Deployment_Configuration_Path=WORKSPACES Branch=main tf_version="1.9.8" ansible_core_version="2.15" S-Username=$SUserName S-Password=$SPassword --output yaml --authorize true --output none $general_group_id = (az pipelines variable-group list --query "[?name=='SDAF-General'].id | [0]" --only-show-errors) az pipelines variable-group variable update --group-id $general_group_id --name "S-Password" --value $SPassword --secret true --output none --only-show-errors } diff --git a/deploy/scripts/New-SDAFDevopsWorkloadZone.ps1 b/deploy/scripts/New-SDAFDevopsWorkloadZone.ps1 index 70a6887638..9c1c9c7d31 100644 --- a/deploy/scripts/New-SDAFDevopsWorkloadZone.ps1 +++ b/deploy/scripts/New-SDAFDevopsWorkloadZone.ps1 @@ -230,7 +230,7 @@ if ($authenticationMethod -eq "Service Principal") { $GroupID = (az pipelines variable-group list --query "[?name=='$WorkloadZonePrefix'].id | [0]" --only-show-errors ) if ($GroupID.Length -eq 0) { Write-Host "Creating the variable group" $WorkloadZonePrefix -ForegroundColor Green - az pipelines variable-group create --name $WorkloadZonePrefix --variables Agent='Azure Pipelines' ARM_CLIENT_ID=$ARM_CLIENT_ID ARM_OBJECT_ID=$ARM_OBJECT_ID ARM_CLIENT_SECRET=$ARM_CLIENT_SECRET ARM_SUBSCRIPTION_ID=$Workload_zone_subscriptionID ARM_TENANT_ID=$ARM_TENANT_ID POOL=$Pool_Name AZURE_CONNECTION_NAME=$Service_Connection_Name TF_LOG=OFF Logon_Using_SPN=true USE_MSI=false --output none --authorize true + az pipelines variable-group create --name $WorkloadZonePrefix --variables Agent='Azure Pipelines' WL_ARM_CLIENT_ID=$ARM_CLIENT_ID WL_ARM_OBJECT_ID=$ARM_OBJECT_ID WL_ARM_CLIENT_SECRET=$ARM_CLIENT_SECRET WL_ARM_SUBSCRIPTION_ID=$Workload_zone_subscriptionID ARM_TENANT_ID=$ARM_TENANT_ID POOL=$Pool_Name AZURE_CONNECTION_NAME=$Service_Connection_Name TF_LOG=OFF Logon_Using_SPN=true USE_MSI=false --output none --authorize true $GroupID = (az pipelines variable-group list --query "[?name=='$WorkloadZonePrefix'].id | [0]" --only-show-errors) } @@ -241,7 +241,7 @@ else { $GroupID = (az pipelines variable-group list --query "[?name=='$WorkloadZonePrefix'].id | [0]" --only-show-errors ) if ($GroupID.Length -eq 0) { Write-Host "Creating the variable group" $WorkloadZonePrefix -ForegroundColor Green - az pipelines variable-group create --name $WorkloadZonePrefix --variables Agent='Azure Pipelines' ARM_SUBSCRIPTION_ID=$Workload_zone_subscriptionID POOL=$Pool_Name AZURE_CONNECTION_NAME=$Service_Connection_Name TF_LOG=OFF Logon_Using_SPN=false USE_MSI=true --output none --authorize true + az pipelines variable-group create --name $WorkloadZonePrefix --variables Agent='Azure Pipelines' WL_ARM_SUBSCRIPTION_ID=$Workload_zone_subscriptionID POOL=$Pool_Name AZURE_CONNECTION_NAME=$Service_Connection_Name TF_LOG=OFF Logon_Using_SPN=false USE_MSI=true --output none --authorize true $GroupID = (az pipelines variable-group list --query "[?name=='$WorkloadZonePrefix'].id | [0]" --only-show-errors) } } @@ -250,9 +250,9 @@ if ($authenticationMethod -eq "Service Principal") { $Env:AZURE_DEVOPS_EXT_AZURE_RM_SERVICE_PRINCIPAL_KEY = $ARM_CLIENT_SECRET - az pipelines variable-group variable update --group-id $GroupID --name "ARM_CLIENT_SECRET" --value $ARM_CLIENT_SECRET --secret true --output none --only-show-errors - az pipelines variable-group variable update --group-id $GroupID --name "ARM_CLIENT_ID" --value $ARM_CLIENT_ID --output none --only-show-errors - az pipelines variable-group variable update --group-id $GroupID --name "ARM_OBJECT_ID" --value $ARM_OBJECT_ID --output none --only-show-errors + az pipelines variable-group variable update --group-id $GroupID --name "WL_ARM_CLIENT_SECRET" --value $ARM_CLIENT_SECRET --secret true --output none --only-show-errors + az pipelines variable-group variable update --group-id $GroupID --name "WL_ARM_CLIENT_ID" --value $ARM_CLIENT_ID --output none --only-show-errors + az pipelines variable-group variable update --group-id $GroupID --name "WL_ARM_OBJECT_ID" --value $ARM_OBJECT_ID --output none --only-show-errors $epExists = (az devops service-endpoint list --query "[?name=='$Service_Connection_Name'].name | [0]") diff --git a/deploy/scripts/advanced_state_management.sh b/deploy/scripts/advanced_state_management.sh index 16dd4d1d8b..b2c2198e90 100755 --- a/deploy/scripts/advanced_state_management.sh +++ b/deploy/scripts/advanced_state_management.sh @@ -196,14 +196,20 @@ automation_config_directory=$CONFIG_REPO_PATH/.sap_deployment_automation/ system_config_information="${automation_config_directory}""${environment}""${region_code}" #Plugins -if [ ! -d /opt/terraform/.terraform.d/plugin-cache ] -then +isInCloudShellCheck=$(checkIfCloudShell) + +if checkIfCloudShell; then + mkdir -p "${HOME}/.terraform.d/plugin-cache" + export TF_PLUGIN_CACHE_DIR="${HOME}/.terraform.d/plugin-cache" +else + if [ ! -d /opt/terraform/.terraform.d/plugin-cache ]; then mkdir -p /opt/terraform/.terraform.d/plugin-cache + sudo chown -R $USER /opt/terraform + fi + export TF_PLUGIN_CACHE_DIR=/opt/terraform/.terraform.d/plugin-cache fi -sudo chown -R $USER:$USER /opt/terraform - -export TF_PLUGIN_CACHE_DIR=/opt/terraform/.terraform.d/plugin-cache +# export TF_PLUGIN_CACHE_DIR=/opt/terraform/.terraform.d/plugin-cache set_executing_user_environment_variables "none" diff --git a/deploy/scripts/deploy_controlplane.sh b/deploy/scripts/deploy_controlplane.sh index 610c592e5b..77bba5e664 100755 --- a/deploy/scripts/deploy_controlplane.sh +++ b/deploy/scripts/deploy_controlplane.sh @@ -30,12 +30,19 @@ resetformatting="\e[0m" full_script_path="$(realpath "${BASH_SOURCE[0]}")" script_directory="$(dirname "${full_script_path}")" +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 + #call stack has full scriptname when using source source "${script_directory}/deploy_utils.sh" #helper files source "${script_directory}/helpers/script_helpers.sh" + + force=0 recover=0 ado_flag="" @@ -72,7 +79,19 @@ do esac done -echo "ADO flag ${ado_flag}" +echo "ADO flag: ${ado_flag}" + +key=$(basename "${deployer_parameter_file}" | cut -d. -f1) +deployer_tfstate_key="${key}.terraform.tfstate" + +echo "Deployer State File: ${deployer_tfstate_key}" +echo "Deployer Subscription: ${subscription}" + +key=$(basename "${library_parameter_file}" | cut -d. -f1) +library_tfstate_key="${key}.terraform.tfstate" + +echo "Deployer State File: ${deployer_tfstate_key}" +echo "Library State File: ${library_tfstate_key}" this_ip=$(curl -s ipinfo.io/ip) >/dev/null 2>&1 root_dirname=$(pwd) @@ -115,7 +134,8 @@ fi # Convert the region to the correct code get_region_code "$region" -echo "Region code for deployment: $region_code" +echo "Region code: ${region_code}" + automation_config_directory=$CONFIG_REPO_PATH/.sap_deployment_automation generic_config_information="${automation_config_directory}"/config @@ -129,6 +149,9 @@ fi init "${automation_config_directory}" "${generic_config_information}" "${deployer_config_information}" +save_config_var "deployer_tfstate_key" "${deployer_config_information}" + + # Check that the exports ARM_SUBSCRIPTION_ID and SAP_AUTOMATION_REPO_PATH are defined validate_exports return_code=$? @@ -157,25 +180,25 @@ relative_path="${deployer_dirname}" export TF_DATA_DIR="${relative_path}"/.terraform step=0 - +echo "" echo "#########################################################################################" echo "# #" echo -e "# $cyan Starting the control plane deployment $resetformatting #" echo "# #" echo "#########################################################################################" - +echo "" noAccess=$( az account show --query name | grep "N/A(tenant level account)") if [ -n "$noAccess" ]; then - echo "#########################################################################################" - echo "# #" - echo -e "# $boldred The provided credentials do not have access to the subscription!!! $resetformatting #" - echo "# #" - echo "#########################################################################################" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldred The provided credentials do not have access to the subscription!!! $resetformatting #" + echo "# #" + echo "#########################################################################################" - az account show --output table + az account show --output table - exit 65 + exit 65 fi az account list --query "[].{Name:name,Id:id}" --output table #setting the user environment variables @@ -209,38 +232,37 @@ if [ -n "${subscription}" ]; then if [ -n "${keyvault}" ] ; then - kv_found=$(az keyvault list --subscription "${subscription}" --query [].name | grep "${keyvault}") + kv_found=$(az keyvault list --subscription "${subscription}" --query [].name | grep "${keyvault}") - if [ -z "${kv_found}" ] ; then - echo "#########################################################################################" - echo "# #" - echo -e "# $boldred Detected a failed deployment $resetformatting #" - echo "# #" - echo -e "# $cyan Trying to recover $resetformatting #" - echo "# #" - echo "#########################################################################################" - step=0 - save_config_var "step" "${deployer_config_information}" - fi + if [ -z "${kv_found}" ] ; then + echo "#########################################################################################" + echo "# #" + echo -e "# $boldred Detected a failed deployment $resetformatting #" + echo "# #" + echo -e "# $cyan Trying to recover $resetformatting #" + echo "# #" + echo "#########################################################################################" + step=0 + save_config_var "step" "${deployer_config_information}" + fi else - step=0 - save_config_var "step" "${deployer_config_information}" + step=0 + save_config_var "step" "${deployer_config_information}" fi - - fi load_config_vars "${deployer_config_information}" "step" if [ 0 = "${deploy_using_msi_only:-}" ]; then - echo "Using Service Principal for deployment" - set_executing_user_environment_variables "${spn_secret}" + echo "Identity to use: Service Principal" + unset ARM_USE_MSI + set_executing_user_environment_variables "${spn_secret}" else - echo "Using Managed Identity for deployment" - set_executing_user_environment_variables "none" + echo "Identity to use: Managed Identity" + set_executing_user_environment_variables "none" fi if [ $recover == 1 ]; then @@ -253,6 +275,23 @@ if [ $recover == 1 ]; then fi fi +#Persist the parameters +if [ -n "$subscription" ]; then + save_config_var "subscription" "${deployer_config_information}" + export STATE_SUBSCRIPTION=$subscription + save_config_var "STATE_SUBSCRIPTION" "${deployer_config_information}" + export ARM_SUBSCRIPTION_ID=$subscription + save_config_var "ARM_SUBSCRIPTION_ID" "${deployer_config_information}" +fi + +if [ -n "$client_id" ]; then + save_config_var "client_id" "${deployer_config_information}" +fi + +if [ -n "$tenant_id" ]; then + save_config_var "tenant_id" "${deployer_config_information}" +fi + curdir=$(pwd) if [ 0 == $step ]; then echo "" @@ -265,15 +304,16 @@ if [ 0 == $step ]; then allParams=$(printf " --parameterfile %s %s" "${deployer_file_parametername}" "${approveparam}") - echo $allParams - cd "${deployer_dirname}" || exit if [ $force == 1 ]; then rm -Rf .terraform terraform.tfstate* fi - "${SAP_AUTOMATION_REPO_PATH}"/deploy/scripts/install_deployer.sh $allParams + echo "Calling install_deployer.sh: $allParams" + echo "Deployer State File: ${deployer_tfstate_key}" + + "${SAP_AUTOMATION_REPO_PATH}/deploy/scripts/install_deployer.sh" $allParams return_code=$? if [ 0 != $return_code ]; then echo "Bootstrapping of the deployer failed" > "${deployer_config_information}".err @@ -281,7 +321,7 @@ if [ 0 == $step ]; then fi load_config_vars "${deployer_config_information}" "keyvault" - echo "Key vault:" $keyvault + echo "Key vault: ${keyvault}" if [ -z "$keyvault" ]; then echo "#########################################################################################" @@ -292,28 +332,12 @@ if [ 0 == $step ]; then echo "Bootstrapping of the deployer failed" > "${deployer_config_information}".err exit 10 fi - - #Persist the parameters - if [ -n "$subscription" ]; then - save_config_var "subscription" "${deployer_config_information}" - export STATE_SUBSCRIPTION=$subscription - save_config_var "STATE_SUBSCRIPTION" "${deployer_config_information}" - fi - - if [ -n "$client_id" ]; then - save_config_var "client_id" "${deployer_config_information}" - fi - - if [ -n "$tenant_id" ]; then - save_config_var "tenant_id" "${deployer_config_information}" - fi - if [ -n "${FORCE_RESET}" ]; then - step=3 - save_config_var "step" "${deployer_config_information}" - exit 0 + step=3 + save_config_var "step" "${deployer_config_information}" + exit 0 else - export step=1 + export step=1 fi save_config_var "step" "${deployer_config_information}" @@ -341,18 +365,18 @@ if [ 1 == $step ] || [ 3 == $step ] ; then if [ -z "$keyvault" ]; then - key=$(echo "${deployer_file_parametername}" | cut -d. -f1) - if [ $recover == 1 ]; then - terraform_module_directory="$SAP_AUTOMATION_REPO_PATH"/deploy/terraform/run/sap_deployer/ - terraform -chdir="${terraform_module_directory}" init -upgrade=true \ - --backend-config "subscription_id=${STATE_SUBSCRIPTION}" \ - --backend-config "resource_group_name=${REMOTE_STATE_RG}" \ - --backend-config "storage_account_name=${REMOTE_STATE_SA}" \ - --backend-config "container_name=tfstate" \ - --backend-config "key=${key}.terraform.tfstate" - - keyvault=$(terraform -chdir="${terraform_module_directory}" output deployer_kv_user_name | tr -d \") - fi + key=$(echo "${deployer_file_parametername}" | cut -d. -f1) + if [ $recover == 1 ]; then + terraform_module_directory="$SAP_AUTOMATION_REPO_PATH"/deploy/terraform/run/sap_deployer/ + terraform -chdir="${terraform_module_directory}" init -upgrade=true \ + --backend-config "subscription_id=${STATE_SUBSCRIPTION}" \ + --backend-config "resource_group_name=${REMOTE_STATE_RG}" \ + --backend-config "storage_account_name=${REMOTE_STATE_SA}" \ + --backend-config "container_name=tfstate" \ + --backend-config "key=${key}.terraform.tfstate" + + keyvault=$(terraform -chdir="${terraform_module_directory}" output deployer_kv_user_name | tr -d \") + fi fi if [ -z "$keyvault" ]; then @@ -374,15 +398,15 @@ if [ 1 == $step ] || [ 3 == $step ] ; then kv_name_check=$(az keyvault list --query "[?name=='$keyvault'].name | [0]" --subscription "${subscription}") if [ -z $kv_name_check ]; then - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $cyan Retrying keyvault access $resetformatting #" - echo "# #" - echo "#########################################################################################" - echo "" - sleep 60 - kv_name_check=$(az keyvault list --query "[?name=='$keyvault'].name | [0]" --subscription "${subscription}") + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $cyan Retrying keyvault access $resetformatting #" + echo "# #" + echo "#########################################################################################" + echo "" + sleep 60 + kv_name_check=$(az keyvault list --query "[?name=='$keyvault'].name | [0]" --subscription "${subscription}") fi if [ -z $kv_name_check ]; then @@ -421,30 +445,30 @@ if [ 1 == $step ] || [ 3 == $step ] ; then if [ 0 = "${deploy_using_msi_only:-}" ]; then - read -p "Do you want to specify the SPN Details Y/N?" ans - answer=${ans^^} - if [ "$answer" == 'Y' ]; then - allParams=$(printf " -e %s -r %s -v %s " "${environment}" "${region_code}" "${keyvault}" ) + read -p "Do you want to specify the SPN Details Y/N?" ans + answer=${ans^^} + if [ "$answer" == 'Y' ]; then + allParams=$(printf " -e %s -r %s -v %s " "${environment}" "${region_code}" "${keyvault}" ) - #$allParams as an array (); array math can be done in shell, allowing dynamic parameter lists to be created - #"${allParams[@]}" - quotes all elements of the array + #$allParams as an array (); array math can be done in shell, allowing dynamic parameter lists to be created + #"${allParams[@]}" - quotes all elements of the array - "${SAP_AUTOMATION_REPO_PATH}"/deploy/scripts/set_secrets.sh $allParams - return_code=$? - if [ 0 != $return_code ]; then - exit $return_code - fi - fi + "${SAP_AUTOMATION_REPO_PATH}"/deploy/scripts/set_secrets.sh $allParams + return_code=$? + if [ 0 != $return_code ]; then + exit $return_code + fi + fi else - allParams=$(printf " -e %s -r %s -v %s --subscription %s --msi " "${environment}" "${region_code}" "${keyvault}" "${subscription}") + allParams=$(printf " -e %s -r %s -v %s --subscription %s --msi " "${environment}" "${region_code}" "${keyvault}" "${subscription}") - "${SAP_AUTOMATION_REPO_PATH}"/deploy/scripts/set_secrets.sh $allParams - if [ -f secret.err ]; then - error_message=$(cat secret.err) - echo "##vso[task.logissue type=error]${error_message}" + "${SAP_AUTOMATION_REPO_PATH}"/deploy/scripts/set_secrets.sh $allParams + if [ -f secret.err ]; then + error_message=$(cat secret.err) + echo "##vso[task.logissue type=error]${error_message}" - exit 65 - fi + exit 65 + fi fi fi @@ -458,8 +482,8 @@ if [ 1 == $step ] || [ 3 == $step ] ; then fi cd "${curdir}" || exit if [ 1 == $step ] ; then - step=2 - save_config_var "step" "${deployer_config_information}" + step=2 + save_config_var "step" "${deployer_config_information}" fi else az_subscription_id=$(az account show --query id -o tsv) @@ -511,7 +535,7 @@ if [ 2 == $step ]; then fi allParams=$(printf " -p %s -d %s %s" "${library_file_parametername}" "${relative_path}" "${approveparam}") - echo "${allParams}" + echo "Calling install_library.sh with: $allParams" "${SAP_AUTOMATION_REPO_PATH}"/deploy/scripts/install_library.sh $allParams return_code=$? @@ -526,7 +550,7 @@ if [ 2 == $step ]; then REMOTE_STATE_SA=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw remote_state_storage_account_name | tr -d \") STATE_SUBSCRIPTION=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw created_resource_group_subscription_id | tr -d \") - if [ $ado_flag != "--ado" ] ; then + if [ "${ado_flag}" != "--ado" ] ; then az storage account network-rule add -g "${REMOTE_STATE_RG}" --account-name "${REMOTE_STATE_SA}" --ip-address ${this_ip} --output none fi @@ -601,22 +625,30 @@ if [ 3 == $step ]; then v="" secret=$(az keyvault secret list --vault-name "${keyvault}" --query "[].{Name:name} | [? contains(Name,'${secretname}')] | [0]" | tr -d \") if [ "${secret}" == "${secretname}" ]; then - TF_VAR_sa_connection_string=$(az keyvault secret show --name "${secretname}" --vault-name "${keyvault}" --query value | tr -d \") - export TF_VAR_sa_connection_string + TF_VAR_sa_connection_string=$(az keyvault secret show --name "${secretname}" --vault-name "${keyvault}" --query value | tr -d \") + export TF_VAR_sa_connection_string fi if [[ -z $REMOTE_STATE_SA ]]; then - echo "Loading the State file information" load_config_vars "${deployer_config_information}" "REMOTE_STATE_SA" fi - allParams=$(printf " --parameterfile %s --storageaccountname %s --type sap_deployer %s %s " "${deployer_file_parametername}" "${REMOTE_STATE_SA}" "${approveparam}" "${ado_flag}" ) + if [[ -z $STATE_SUBSCRIPTION ]]; + then + load_config_vars "${deployer_config_information}" "STATE_SUBSCRIPTION" + fi - echo -e "$cyan calling installer.sh with parameters: $allParams" + if [[ -z $ARM_SUBSCRIPTION_ID ]]; + then + load_config_vars "${deployer_config_information}" "ARM_SUBSCRIPTION_ID" + fi - "${SAP_AUTOMATION_REPO_PATH}"/deploy/scripts/installer.sh $allParams + allParams=$(printf " --parameterfile %s --storageaccountname %s --state_subscription %s --type sap_deployer %s %s " "${deployer_file_parametername}" "${REMOTE_STATE_SA}" "${STATE_SUBSCRIPTION}" "${approveparam}" "${ado_flag}" ) + + echo "Calling installer.sh with: $allParams" + "${SAP_AUTOMATION_REPO_PATH}/deploy/scripts/installer.sh" $allParams return_code=$? if [ 0 != $return_code ]; then echo "Migrating the deployer state failed" > "${deployer_config_information}".err @@ -649,7 +681,7 @@ if [ 4 == $step ]; then cd "${library_dirname}" || exit allParams=$(printf " --parameterfile %s --storageaccountname %s --type sap_library %s %s" "${library_file_parametername}" "${REMOTE_STATE_SA}" "${approveparam}" "${ado_flag}") - echo -e "$cyan calling installer.sh with parameters: $allParams" + echo "Calling installer.sh with: $allParams" "${SAP_AUTOMATION_REPO_PATH}"/deploy/scripts/installer.sh $allParams return_code=$? diff --git a/deploy/scripts/deploy_utils.sh b/deploy/scripts/deploy_utils.sh index 42e2753ad0..db8929871e 100755 --- a/deploy/scripts/deploy_utils.sh +++ b/deploy/scripts/deploy_utils.sh @@ -1,6 +1,12 @@ #!/bin/bash -export PATH=${PATH}:/opt/terraform/bin:/opt/ansible/bin +if [ -d /opt/terraform/bin ]; then + export PATH=${PATH}:/opt/terraform/bin +fi + +if [ -d /opt/ansible/bin ]; then + export PATH=${PATH}:/opt/ansible/bin +fi ######################################################################### # Helper utilities @@ -40,12 +46,12 @@ function load_config_vars() { return fi for var_name; do # iterate over function params - # NOTE: Should we care if we fail to retrieve a value from the file? + # NOTE: Should we care if we fail to retrieve a value from the file? var_value="$(grep -m1 "^${var_name}=" "${var_file}" | cut -d'=' -f2- | tr -d ' ' | tr -d '"')" - if [ -z "${var_value}" ] + if [ -z ${var_value} ] then - var_value="$(grep -m1 "^${var_name} " "${var_file}" | cut -d'=' -f2- | tr -d ' ' | tr -d '"')" + var_value="$(grep -m1 "^${var_name}[[:space:]]=" "${var_file}" | cut -d'=' -f2- | tr -d ' ' | tr -d '"')" fi # NOTE: this continue means we skip setting an empty value for a variable @@ -122,23 +128,27 @@ function get_and_store_sa_details { local REMOTE_STATE_SA="${1}" local config_file_name="${2}" - echo "Trying to find the storage account ${REMOTE_STATE_SA}" + echo "Trying to find the storage account: ${REMOTE_STATE_SA}" save_config_vars "${config_file_name}" REMOTE_STATE_SA if [ -z $STATE_SUBSCRIPTION ];then - tfstate_resource_id=$(az resource list --name "${REMOTE_STATE_SA}" --resource-type Microsoft.Storage/storageAccounts --query "[].id | [0]" --output tsv) + tf_resource_id=$(az resource list --name "${REMOTE_STATE_SA}" --resource-type Microsoft.Storage/storageAccounts --query "[].id | [0]" --output tsv) + REMOTE_STATE_RGNAME=$(az resource list --name "${REMOTE_STATE_SA}" --resource-type Microsoft.Storage/storageAccounts --query "[].resourceGroup | [0]" --output tsv) else - tfstate_resource_id=$(az resource list --name "${REMOTE_STATE_SA}" --resource-type Microsoft.Storage/storageAccounts --subscription $STATE_SUBSCRIPTION --query "[].id | [0]" --output tsv) + tf_resource_id=$(az resource list --name "${REMOTE_STATE_SA}" --resource-type Microsoft.Storage/storageAccounts --subscription $STATE_SUBSCRIPTION --query "[].id | [0]" --output tsv) + REMOTE_STATE_RGNAME=$(az resource list --name "${REMOTE_STATE_SA}" --resource-type Microsoft.Storage/storageAccounts --subscription $STATE_SUBSCRIPTION --query "[].resourceGroup | [0]" --output tsv) + fi fail_if_null tfstate_resource_id - export STATE_SUBSCRIPTION=$(echo $tfstate_resource_id | cut -d/ -f3 | tr -d \" | xargs) - export REMOTE_STATE_RG=$(echo $tfstate_resource_id | cut -d/ -f5 | tr -d \" | xargs) + + export REMOTE_STATE_RG=$REMOTE_STATE_RGNAME + export tfstate_resource_id=$tf_resource_id save_config_vars "${config_file_name}" \ REMOTE_STATE_RG \ tfstate_resource_id \ STATE_SUBSCRIPTION - echo "Found the storage account ${REMOTE_STATE_SA}" + echo "Found the storage account: ${REMOTE_STATE_SA}" } # /*---------------------------------------------------------------------------8 @@ -188,9 +198,6 @@ function checkIfCloudShell() { local isRunInCloudShell=1 # default value is false if [ "$POWERSHELL_DISTRIBUTION_CHANNEL" == "CloudShell" ]; then isRunInCloudShell=0 - echo "isRunInCloudShell: true" - else - echo "isRunInCloudShell: false" fi return $isRunInCloudShell @@ -282,6 +289,12 @@ function set_executing_user_environment_variables() { az_client_secret="$1" + echo "" + echo "----------------------------------------------------------------------------------------------" + + echo "Setting the environment variables for the executing user" + + echo -e "\t[set_executing_user_environment_variables]: Identifying the executing user and client" set_azure_cloud_environment @@ -371,6 +384,7 @@ function set_executing_user_environment_variables() { export ARM_TENANT_ID export ARM_CLIENT_ID export ARM_CLIENT_SECRET + unset ARM_USE_MSI else echo -e "\t[set_executing_user_environment_variables]: unable to identify the executing user and client" @@ -384,6 +398,9 @@ function set_executing_user_environment_variables() { echo -e "\t\tARM_SUBSCRIPTION_ID: $(printenv ARM_SUBSCRIPTION_ID)" echo -e "\t\tARM_USE_MSI: $(printenv ARM_USE_MSI)" fi + echo "----------------------------------------------------------------------------------------------" + echo "" + } function unset_executing_user_environment_variables() { @@ -393,6 +410,7 @@ function unset_executing_user_environment_variables() { unset ARM_TENANT_ID unset ARM_CLIENT_ID unset ARM_CLIENT_SECRET + unset ARM_USE_MSI } # print the script name and function being called @@ -401,7 +419,7 @@ function print_script_name_and_function() { } function get_region_code() { - region_lower=$(echo "${region}" | tr [:upper:] [:lower:] ) + region_lower=$(echo "${region}" | tr [:upper:] [:lower:] | xargs | tr -d '\r') case "${region_lower}" in "australiacentral") export region_code="AUCE" ;; "australiacentral2") export region_code="AUC2" ;; diff --git a/deploy/scripts/helpers/script_helpers.sh b/deploy/scripts/helpers/script_helpers.sh index b179bf67db..516564242b 100755 --- a/deploy/scripts/helpers/script_helpers.sh +++ b/deploy/scripts/helpers/script_helpers.sh @@ -5,6 +5,18 @@ boldred="\e[1;31m" cyan="\e[1;36m" resetformatting="\e[0m" +full_script_path="$(realpath "${BASH_SOURCE[0]}")" +script_directory="$(dirname "${full_script_path}")" +script_directory_parent="$(dirname "${script_directory}")" + +#call stack has full scriptname when using source +source "${script_directory_parent}"/deploy_utils.sh + +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 + function control_plane_showhelp { echo "" echo "#################################################################################################################" @@ -297,21 +309,21 @@ function validate_webapp_exports { fi if [ "${ARM_USE_MSI}" == "false" ]; then - if [ -z "$TF_VAR_webapp_client_secret" ]; then - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldred Missing environment variables (TF_VAR_webapp_client_secret)!!! $resetformatting #" - echo "# #" - echo "# Please export the following variables to successfully deploy the Webapp: #" - echo "# TF_VAR_app_registration_app_id (webapp registration application id) #" - echo "# TF_VAR_webapp_client_secret (webapp registration password / secret) #" - echo "# #" - echo "# If you do not wish to deploy the Webapp, unset the TF_VAR_use_webapp variable #" - echo "# #" - echo "#########################################################################################" - return 65 #data format error - fi + if [ -z "$TF_VAR_webapp_client_secret" ]; then + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldred Missing environment variables (TF_VAR_webapp_client_secret)!!! $resetformatting #" + echo "# #" + echo "# Please export the following variables to successfully deploy the Webapp: #" + echo "# TF_VAR_app_registration_app_id (webapp registration application id) #" + echo "# TF_VAR_webapp_client_secret (webapp registration password / secret) #" + echo "# #" + echo "# If you do not wish to deploy the Webapp, unset the TF_VAR_use_webapp variable #" + echo "# #" + echo "#########################################################################################" + return 65 #data format error + fi fi return 0 @@ -380,8 +392,28 @@ function missing { function validate_dependencies { + tfPath="/opt/terraform/bin/terraform" + + if [ -f /opt/terraform/bin/terraform ]; then + tfPath="/opt/terraform/bin/terraform" + else + tfPath=$(which terraform) + fi + + echo "Checking Terraform: $tfPath" + + # if /opt/terraform exists, assign permissions to the user + if [ -d /opt/terraform ]; then + sudo chown -R "$USER" /opt/terraform + fi + # Check terraform - tf=$(terraform -version | grep Terraform) + if checkIfCloudShell; then + tf=$(terraform --version | grep Terraform) + else + tf=$($tfPath --version | grep Terraform) + fi + if [ -z "$tf" ]; then echo "" echo "#########################################################################################" @@ -392,13 +424,18 @@ function validate_dependencies { echo "" return 2 #No such file or directory fi - # Set Terraform Plug in cache - if [ ! -d /opt/terraform/.terraform.d/plugin-cache ] - then - mkdir -p /opt/terraform/.terraform.d/plugin-cache + + if checkIfCloudShell; then + mkdir -p "${HOME}/.terraform.d/plugin-cache" + export TF_PLUGIN_CACHE_DIR="${HOME}/.terraform.d/plugin-cache" + else + if [ ! -d /opt/terraform/.terraform.d/plugin-cache ]; then + mkdir -p /opt/terraform/.terraform.d/plugin-cache + fi + export TF_PLUGIN_CACHE_DIR=/opt/terraform/.terraform.d/plugin-cache fi - sudo chown -R $USER:$USER /opt/terraform - export TF_PLUGIN_CACHE_DIR=/opt/terraform/.terraform.d/plugin-cache + # Set Terraform Plug in cache + az --version >stdout.az 2>&1 @@ -448,21 +485,15 @@ function validate_dependencies { } function validate_key_parameters { - echo "Validating $1" - ext=$(echo $1 | cut -d. -f2) + echo "Validating: $1" # Helper variables - if [ "${ext}" == json ]; then - export environment=$(jq --raw-output .infrastructure.environment $1) - export region=$(jq --raw-output .infrastructure.region $1) - else - load_config_vars $1 "environment" - environment=$(echo ${environment} | xargs | tr "[:lower:]" "[:upper:]" ) - load_config_vars $1 "location" - region=$(echo ${location} | xargs) - fi + load_config_vars $1 "environment" + export environment=$(echo ${environment} | xargs | tr "[:lower:]" "[:upper:]" | tr -d '\r' ) + load_config_vars $1 "location" + export region=$(echo ${location} | xargs | tr -d '\r') - if [ -z "${environment}" ]; then + if [ -z ${environment} ]; then echo "#########################################################################################" echo "# #" echo -e "# $boldred Incorrect parameter file. $resetformatting #" @@ -474,7 +505,7 @@ function validate_key_parameters { return 64 #script usage wrong fi - if [ -z "${region}" ]; then + if [ -z ${region} ]; then echo "#########################################################################################" echo "# #" echo -e "# $boldred Incorrect parameter file. $resetformatting #" diff --git a/deploy/scripts/install_deployer.sh b/deploy/scripts/install_deployer.sh index bbf6648062..2a7bed526c 100755 --- a/deploy/scripts/install_deployer.sh +++ b/deploy/scripts/install_deployer.sh @@ -20,98 +20,105 @@ source "${script_directory}/helpers/script_helpers.sh" #Internal helper functions function showhelp { - echo "" - echo "#########################################################################################" - echo "# #" - echo "# #" - echo "# This file contains the logic to deploy the deployer. #" - echo "# The script experts the following exports: #" - echo "# #" - echo "# ARM_SUBSCRIPTION_ID to specify which subscription to deploy to #" - echo "# SAP_AUTOMATION_REPO_PATH the path to the folder containing the cloned sap-automation #" - echo "# #" - echo "# The script will persist the parameters needed between the executions in the #" - echo "# [CONFIG_REPO_PATH]/.sap_deployment_automation folder #" - echo "# #" - echo "# #" - echo "# Usage: install_deployer.sh #" - echo "# -p deployer parameter file #" - echo "# #" - echo "# -i interactive true/false setting the value to false will not prompt before apply #" - echo "# -h Show help #" - echo "# #" - echo "# Example: #" - echo "# #" - echo "# [REPO-ROOT]deploy/scripts/install_deployer.sh \ #" - echo "# -p PROD-WEEU-DEP00-INFRASTRUCTURE.json \ #" - echo "# -i true #" - echo "# #" - echo "#########################################################################################" + echo "" + echo "#########################################################################################" + echo "# #" + echo "# #" + echo "# This file contains the logic to deploy the deployer. #" + echo "# The script experts the following exports: #" + echo "# #" + echo "# ARM_SUBSCRIPTION_ID to specify which subscription to deploy to #" + echo "# SAP_AUTOMATION_REPO_PATH the path to the folder containing the cloned sap-automation #" + echo "# #" + echo "# The script will persist the parameters needed between the executions in the #" + echo "# [CONFIG_REPO_PATH]/.sap_deployment_automation folder #" + echo "# #" + echo "# #" + echo "# Usage: install_deployer.sh #" + echo "# -p deployer parameter file #" + echo "# #" + echo "# -i interactive true/false setting the value to false will not prompt before apply #" + echo "# -h Show help #" + echo "# #" + echo "# Example: #" + echo "# #" + echo "# [REPO-ROOT]deploy/scripts/install_deployer.sh \ #" + echo "# -p PROD-WEEU-DEP00-INFRASTRUCTURE.json \ #" + echo "# -i true #" + echo "# #" + echo "#########################################################################################" } - #process inputs - may need to check the option i for auto approve as it is not used INPUT_ARGUMENTS=$(getopt -n install_deployer -o p:ih --longoptions parameterfile:,auto-approve,help -- "$@") VALID_ARGUMENTS=$? if [ "$VALID_ARGUMENTS" != "0" ]; then - showhelp + showhelp fi eval set -- "$INPUT_ARGUMENTS" -while : -do - case "$1" in - -p | --parameterfile) parameterfile="$2" ; shift 2 ;; - -i | --auto-approve) approve="--auto-approve" ; shift ;; - -h | --help) showhelp - exit 3 ; shift ;; - --) shift; break ;; - esac +while :; do + case "$1" in + -p | --parameterfile) + parameterfile="$2" + shift 2 + ;; + -i | --auto-approve) + approve="--auto-approve" + shift + ;; + -h | --help) + showhelp + exit 3 + shift + ;; + --) + shift + break + ;; + esac done deployment_system=sap_deployer param_dirname=$(dirname "${parameterfile}") -echo "Parameter file: "${parameterfile}"" - -if [ ! -f "${parameterfile}" ] -then - printf -v val %-40.40s "$parameterfile" - echo "" - echo "#########################################################################################" - echo "# #" - echo "# Parameter file does not exist: ${val} #" - echo "# #" - echo "#########################################################################################" - exit 2 #No such file or directory +echo "Parameter file: ${parameterfile}" + +if [ ! -f "${parameterfile}" ]; then + printf -v val %-40.40s "$parameterfile" + echo "" + echo "#########################################################################################" + echo "# #" + echo "# Parameter file does not exist: ${val} #" + echo "# #" + echo "#########################################################################################" + exit 2 #No such file or directory fi if [ "$param_dirname" != '.' ]; then - echo "" - echo "#########################################################################################" - echo "# #" - echo "# Please run this command from the folder containing the parameter file #" - echo "# #" - echo "#########################################################################################" - exit 3 + echo "" + echo "#########################################################################################" + echo "# #" + echo "# Please run this command from the folder containing the parameter file #" + echo "# #" + echo "#########################################################################################" + exit 3 fi - # Check that parameter files have environment and location defined validate_key_parameters "$parameterfile" return_code=$? if [ 0 != $return_code ]; then - exit $return_code + exit $return_code fi region=$(echo "${region}" | tr "[:upper:]" "[:lower:]") # Convert the region to the correct code get_region_code $region - key=$(echo "${parameterfile}" | cut -d. -f1) #Persisting the parameters across executions @@ -131,7 +138,7 @@ var_file="${param_dirname}"/"${parameterfile}" validate_exports return_code=$? if [ 0 != $return_code ]; then - exit $return_code + exit $return_code fi terraform_module_directory="${SAP_AUTOMATION_REPO_PATH}"/deploy/terraform/bootstrap/"${deployment_system}"/ @@ -139,8 +146,7 @@ export TF_DATA_DIR="${param_dirname}"/.terraform this_ip=$(curl -s ipinfo.io/ip) >/dev/null 2>&1 export TF_VAR_Agent_IP=$this_ip -echo "Agent IP: $this_ip" - +echo "Agent IP: $this_ip" ok_to_proceed=false new_deployment=false @@ -149,72 +155,83 @@ new_deployment=false validate_dependencies return_code=$? if [ 0 != $return_code ]; then - exit $return_code + exit $return_code fi if [ ! -d ./.terraform/ ]; then - echo "#########################################################################################" - echo "# #" - echo "# New deployment #" - echo "# #" - echo "#########################################################################################" - terraform -chdir="${terraform_module_directory}" init -backend-config "path=${param_dirname}/terraform.tfstate" + echo "#########################################################################################" + echo "# #" + echo "# New deployment #" + echo "# #" + echo "#########################################################################################" + terraform -chdir="${terraform_module_directory}" init -backend-config "path=${param_dirname}/terraform.tfstate" else - if [ -f ./.terraform/terraform.tfstate ]; then - if grep "azurerm" ./.terraform/terraform.tfstate ; then - echo "#########################################################################################" - echo "# #" - echo "# The state is already migrated to Azure!!! #" - echo "# #" - echo "#########################################################################################" - sed -i /"use_microsoft_graph"/d "${param_dirname}/.terraform/terraform.tfstate" - if [ $approve == "--auto-approve" ] ; then - tfstate_resource_id=$(az resource list --name $REINSTALL_ACCOUNTNAME --subscription $REINSTALL_SUBSCRIPTION --resource-type Microsoft.Storage/storageAccounts --query "[].id | [0]" -o tsv) - if [ -n "${tfstate_resource_id}" ]; then - echo "Reinitializing against remote state" - export TF_VAR_tfstate_resource_id=$tfstate_resource_id - - terraform_module_directory="${SAP_AUTOMATION_REPO_PATH}"/deploy/terraform/run/"${deployment_system}"/ - terraform -chdir="${terraform_module_directory}" init -upgrade=true \ - --backend-config "subscription_id=$REINSTALL_SUBSCRIPTION" \ - --backend-config "resource_group_name=$REINSTALL_RESOURCE_GROUP" \ - --backend-config "storage_account_name=$REINSTALL_ACCOUNTNAME" \ - --backend-config "container_name=tfstate" \ - --backend-config "key=${key}.terraform.tfstate" - terraform -chdir="${terraform_module_directory}" refresh -var-file="${var_file}" - - else - terraform -chdir="${terraform_module_directory}" init -force-copy -migrate-state --backend-config "path=${param_dirname}/terraform.tfstate" - terraform -chdir="${terraform_module_directory}" init -reconfigure --backend-config "path=${param_dirname}/terraform.tfstate" - terraform -chdir="${terraform_module_directory}" refresh -var-file="${var_file}" - fi - else - read -p "Do you want to bootstrap the deployer again Y/N?" ans - answer=${ans^^} - if [ $answer == 'Y' ]; then - terraform -chdir="${terraform_module_directory}" init -upgrade=true -backend-config "path=${param_dirname}/terraform.tfstate" - terraform -chdir="${terraform_module_directory}" refresh -var-file="${var_file}" - else - unset TF_DATA_DIR - exit 0 - fi - fi + if [ -f ./.terraform/terraform.tfstate ]; then + if grep "azurerm" ./.terraform/terraform.tfstate; then + echo "#########################################################################################" + echo "# #" + echo "# The state is already migrated to Azure!!! #" + echo "# #" + echo "#########################################################################################" + sed -i /"use_microsoft_graph"/d "${param_dirname}/.terraform/terraform.tfstate" + if [ $approve == "--auto-approve" ]; then + tfstate_resource_id=$(az resource list --name $REINSTALL_ACCOUNTNAME --subscription $REINSTALL_SUBSCRIPTION --resource-type Microsoft.Storage/storageAccounts --query "[].id | [0]" -o tsv) + if [ -n "${tfstate_resource_id}" ]; then + echo "Reinitializing against remote state" + export TF_VAR_tfstate_resource_id=$tfstate_resource_id + + terraform_module_directory="${SAP_AUTOMATION_REPO_PATH}"/deploy/terraform/run/"${deployment_system}"/ + terraform -chdir="${terraform_module_directory}" init -upgrade=true \ + --backend-config "subscription_id=$REINSTALL_SUBSCRIPTION" \ + --backend-config "resource_group_name=$REINSTALL_RESOURCE_GROUP" \ + --backend-config "storage_account_name=$REINSTALL_ACCOUNTNAME" \ + --backend-config "container_name=tfstate" \ + --backend-config "key=${key}.terraform.tfstate" + terraform -chdir="${terraform_module_directory}" refresh -var-file="${var_file}" + else - terraform -chdir="${terraform_module_directory}" init -upgrade=true -backend-config "path=${param_dirname}/terraform.tfstate" + terraform -chdir="${terraform_module_directory}" init -force-copy -migrate-state --backend-config "path=${param_dirname}/terraform.tfstate" + terraform -chdir="${terraform_module_directory}" init -reconfigure --backend-config "path=${param_dirname}/terraform.tfstate" + terraform -chdir="${terraform_module_directory}" refresh -var-file="${var_file}" fi + else + read -p "Do you want to bootstrap the deployer again Y/N?" ans + answer=${ans^^} + if [ $answer == 'Y' ]; then + terraform -chdir="${terraform_module_directory}" init -upgrade=true -backend-config "path=${param_dirname}/terraform.tfstate" + terraform -chdir="${terraform_module_directory}" refresh -var-file="${var_file}" + else + unset TF_DATA_DIR + exit 0 + fi + fi else - terraform -chdir="${terraform_module_directory}" init -upgrade=true -backend-config "path=${param_dirname}/terraform.tfstate" + terraform -chdir="${terraform_module_directory}" init -upgrade=true -backend-config "path=${param_dirname}/terraform.tfstate" fi + else + terraform -chdir="${terraform_module_directory}" init -upgrade=true -backend-config "path=${param_dirname}/terraform.tfstate" + fi +fi +return_value=$? +if [ 1 == $return_value ]; then + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldreduscore Errors during the init phase $resetformatting #" + echo "# #" + echo "#########################################################################################" + echo "" + unset TF_DATA_DIR + exit $return_value fi extra_vars="" if [ -f terraform.tfvars ]; then - extra_vars=" -var-file=${param_dirname}/terraform.tfvars " + extra_vars=" -var-file=${param_dirname}/terraform.tfvars " fi -terraform -chdir="${terraform_module_directory}" refresh -var-file="${var_file}" $extra_vars - +terraform -chdir="${terraform_module_directory}" refresh -var-file="${var_file}" $extra_vars echo "" echo "#########################################################################################" @@ -224,29 +241,27 @@ echo "# echo "#########################################################################################" echo "" -terraform -chdir="${terraform_module_directory}" plan -detailed-exitcode -var-file="${var_file}" $extra_vars | tee -a plan_output.log +terraform -chdir="${terraform_module_directory}" plan -detailed-exitcode -var-file="${var_file}" $extra_vars | tee -a plan_output.log return_value=$? -if [ 1 == $return_value ] -then - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldreduscore Errors during the plan phase $resetformatting #" - echo "# #" - echo "#########################################################################################" - echo "" - if [ -f plan_output.log ] - then - cat plan_output.log - rm plan_output.log - fi - unset TF_DATA_DIR - exit $return_value +if [ 1 == $return_value ]; then + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldreduscore Errors during the plan phase $resetformatting #" + echo "# #" + echo "#########################################################################################" + echo "" + if [ -f plan_output.log ]; then + cat plan_output.log + rm plan_output.log + fi + unset TF_DATA_DIR + exit $return_value fi if [ -f plan_output.log ]; then - rm plan_output.log + rm plan_output.log fi echo "" @@ -261,183 +276,174 @@ parallelism=10 #Provide a way to limit the number of parallell tasks for Terraform if [[ -n "${TF_PARALLELLISM}" ]]; then - parallelism=$TF_PARALLELLISM + parallelism=$TF_PARALLELLISM fi -if [ -n "${approve}" ] -then - terraform -chdir="${terraform_module_directory}" apply ${approve} -parallelism="${parallelism}" -var-file="${var_file}" $extra_vars -json | tee -a apply_output.json +if [ -n "${approve}" ]; then + terraform -chdir="${terraform_module_directory}" apply ${approve} -parallelism="${parallelism}" -var-file="${var_file}" $extra_vars -json | tee -a apply_output.json else - terraform -chdir="${terraform_module_directory}" apply ${approve} -parallelism="${parallelism}" -var-file="${var_file}" $extra_vars + terraform -chdir="${terraform_module_directory}" apply ${approve} -parallelism="${parallelism}" -var-file="${var_file}" $extra_vars fi return_value=$? rerun_apply=0 -if [ -f apply_output.json ] -then +if [ -f apply_output.json ]; then + errors_occurred=$(jq 'select(."@level" == "error") | length' apply_output.json) + # Check for resource that can be imported + existing=$(jq 'select(."@level" == "error") | {address: .diagnostic.address, summary: .diagnostic.summary} | select(.summary | startswith("A resource with the ID"))' apply_output.json) + if [[ -n ${existing} ]]; then + + readarray -t existing_resources < <(echo ${existing} | jq -c '.') + for item in "${existing_resources[@]}"; do + moduleID=$(jq -c -r '.address ' <<<"$item") + resourceID=$(jq -c -r '.summary' <<<"$item" | awk -F'\"' '{print $2}') + echo "Trying to import" $resourceID "into" $moduleID + + echo terraform -chdir="${terraform_module_directory}" import -var-file="${var_file}" $extra_vars $moduleID $resourceID + terraform -chdir="${terraform_module_directory}" import -var-file="${var_file}" $extra_vars $moduleID $resourceID + done + rerun_apply=1 + fi + if [ -f apply_output.json ]; then + rm apply_output.json + fi + + if [ $rerun_apply == 1 ]; then + echo "" + echo "#########################################################################################" + echo "# #" + echo "# Re-running Terraform apply #" + echo "# #" + echo "#########################################################################################" + echo "" + terraform -chdir="${terraform_module_directory}" apply ${approve} -parallelism="${parallelism}" -var-file="${var_file}" $extra_vars -json | tee -a apply_output.json + return_value=$? + rerun_apply=0 + fi + + if [ -f apply_output.json ]; then + return_value=$? errors_occurred=$(jq 'select(."@level" == "error") | length' apply_output.json) # Check for resource that can be imported existing=$(jq 'select(."@level" == "error") | {address: .diagnostic.address, summary: .diagnostic.summary} | select(.summary | startswith("A resource with the ID"))' apply_output.json) - if [[ -n ${existing} ]] - then - - readarray -t existing_resources < <(echo ${existing} | jq -c '.' ) - for item in "${existing_resources[@]}"; do - moduleID=$(jq -c -r '.address ' <<< "$item") - resourceID=$(jq -c -r '.summary' <<< "$item" | awk -F'\"' '{print $2}') - echo "Trying to import" $resourceID "into" $moduleID - - echo terraform -chdir="${terraform_module_directory}" import -var-file="${var_file}" $extra_vars $moduleID $resourceID - terraform -chdir="${terraform_module_directory}" import -var-file="${var_file}" $extra_vars $moduleID $resourceID - done - rerun_apply=1 + if [[ -n ${existing} ]]; then + + readarray -t existing_resources < <(echo ${existing} | jq -c '.') + for item in "${existing_resources[@]}"; do + moduleID=$(jq -c -r '.address ' <<<"$item") + resourceID=$(jq -c -r '.summary' <<<"$item" | awk -F'\"' '{print $2}') + echo "Trying to import" $resourceID "into" $moduleID + + echo terraform -chdir="${terraform_module_directory}" import -var-file="${var_file}" $extra_vars $moduleID $resourceID + terraform -chdir="${terraform_module_directory}" import -var-file="${var_file}" $extra_vars $moduleID $resourceID + done + rerun_apply=1 + fi + if [ -f apply_output.json ]; then + rm apply_output.json fi - if [ -f apply_output.json ] - then - rm apply_output.json + + if [ $rerun_apply == 1 ]; then + echo "" + echo "#########################################################################################" + echo "# #" + echo "# Re-running Terraform apply #" + echo "# #" + echo "#########################################################################################" + echo "" + terraform -chdir="${terraform_module_directory}" apply ${approve} -parallelism="${parallelism}" -var-file="${var_file}" $extra_vars -json | tee -a apply_output.json + return_value=$? fi - if [ $rerun_apply == 1 ] ; then + return_value=$? + errors_occurred=$(jq 'select(."@level" == "error") | length' apply_output.json) + if [ -f apply_output.json ]; then + + if [[ -n $errors_occurred ]]; then echo "" echo "#########################################################################################" echo "# #" - echo "# Re-running Terraform apply #" - echo "# #" - echo "#########################################################################################" - echo "" - terraform -chdir="${terraform_module_directory}" apply ${approve} -parallelism="${parallelism}" -var-file="${var_file}" $extra_vars -json | tee -a apply_output.json - return_value=$? - rerun_apply=0 - fi - - if [ -f apply_output.json ] - then - return_value=$? - errors_occurred=$(jq 'select(."@level" == "error") | length' apply_output.json) - # Check for resource that can be imported - existing=$(jq 'select(."@level" == "error") | {address: .diagnostic.address, summary: .diagnostic.summary} | select(.summary | startswith("A resource with the ID"))' apply_output.json) - if [[ -n ${existing} ]] - then - - readarray -t existing_resources < <(echo ${existing} | jq -c '.' ) - for item in "${existing_resources[@]}"; do - moduleID=$(jq -c -r '.address ' <<< "$item") - resourceID=$(jq -c -r '.summary' <<< "$item" | awk -F'\"' '{print $2}') - echo "Trying to import" $resourceID "into" $moduleID - - echo terraform -chdir="${terraform_module_directory}" import -var-file="${var_file}" $extra_vars $moduleID $resourceID - terraform -chdir="${terraform_module_directory}" import -var-file="${var_file}" $extra_vars $moduleID $resourceID - done - rerun_apply=1 - fi - if [ -f apply_output.json ] - then - rm apply_output.json - fi + echo -e "# $boldreduscore!Errors during the apply phase!$resetformatting #" - if [ $rerun_apply == 1 ] ; then - echo "" - echo "#########################################################################################" - echo "# #" - echo "# Re-running Terraform apply #" - echo "# #" - echo "#########################################################################################" - echo "" - terraform -chdir="${terraform_module_directory}" apply ${approve} -parallelism="${parallelism}" -var-file="${var_file}" $extra_vars -json | tee -a apply_output.json - return_value=$? - fi + return_value=2 + all_errors=$(jq 'select(."@level" == "error") | {summary: .diagnostic.summary, detail: .diagnostic.detail}' apply_output.json) + if [[ -n ${all_errors} ]]; then + readarray -t errors_strings < <(echo ${all_errors} | jq -c '.') + for errors_string in "${errors_strings[@]}"; do + string_to_report=$(jq -c -r '.detail ' <<<"$errors_string") + if [[ -z ${string_to_report} ]]; then + string_to_report=$(jq -c -r '.summary ' <<<"$errors_string") + fi - return_value=$? - errors_occurred=$(jq 'select(."@level" == "error") | length' apply_output.json) - if [ -f apply_output.json ] - then - - if [[ -n $errors_occurred ]] - then - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldreduscore!Errors during the apply phase!$resetformatting #" - - return_value=2 - all_errors=$(jq 'select(."@level" == "error") | {summary: .diagnostic.summary, detail: .diagnostic.detail}' apply_output.json) - if [[ -n ${all_errors} ]] - then - readarray -t errors_strings < <(echo ${all_errors} | jq -c '.' ) - for errors_string in "${errors_strings[@]}"; do - string_to_report=$(jq -c -r '.detail ' <<< "$errors_string" ) - if [[ -z ${string_to_report} ]] - then - string_to_report=$(jq -c -r '.summary ' <<< "$errors_string" ) - fi - - echo -e "# $boldreduscore $string_to_report $resetformatting" - echo "##vso[task.logissue type=error]${string_to_report}" - - done + echo -e "# $boldreduscore $string_to_report $resetformatting" + echo "##vso[task.logissue type=error]${string_to_report}" - fi - echo "# #" - echo "#########################################################################################" - echo "" + done - fi fi + echo "# #" + echo "#########################################################################################" + echo "" + fi fi - if [ -f apply_output.json ] - then - rm apply_output.json - fi + fi + + if [ -f apply_output.json ]; then + rm apply_output.json + fi +fi +if [ 0 != $return_value ]; then + echo "#########################################################################################" + echo "# #" + echo -e "# $boldreduscore !!! Error when Creating the deployer !!! $resetformatting #" + echo "# #" + echo "#########################################################################################" + echo "" + exit $return_value fi -keyvault=$(terraform -chdir="${terraform_module_directory}" output deployer_kv_user_name | tr -d \") +keyvault=$(terraform -chdir="${terraform_module_directory}" output deployer_kv_user_name | tr -d \") temp=$(echo "${keyvault}" | grep "Warning") -if [ -z "${temp}" ] -then - temp=$(echo "${keyvault}" | grep "Backend reinitialization required") - if [ -z "${temp}" ] - then - touch "${deployer_config_information}" - printf -v val %-.20s "$keyvault" +if [ -z "${temp}" ]; then + temp=$(echo "${keyvault}" | grep "Backend reinitialization required") + if [ -z "${temp}" ]; then + touch "${deployer_config_information}" + printf -v val %-.20s "$keyvault" - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# Keyvault to use for SPN details:$cyan $val $resetformatting #" - echo "# #" - echo "#########################################################################################" - echo "" - - save_config_var "keyvault" "${deployer_config_information}" - return_value=0 - else - return_value=2 - fi -fi + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# Keyvault to use for SPN details:$cyan $val $resetformatting #" + echo "# #" + echo "#########################################################################################" + echo "" -sshsecret=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw deployer_sshkey_secret_name | tr -d \") -if [ -n "${sshsecret}" ] -then - save_config_var "sshsecret" "${deployer_config_information}" + save_config_var "keyvault" "${deployer_config_information}" return_value=0 + else + return_value=2 + fi fi -random_id=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw random_id_b64 | tr -d \") -if [ -n "${random_id}" ] -then - deployer_random_id="${random_id}" - save_config_var "deployer_random_id" "${deployer_config_information}" - return_value=0 +sshsecret=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw deployer_sshkey_secret_name | tr -d \") +if [ -n "${sshsecret}" ]; then + save_config_var "sshsecret" "${deployer_config_information}" + return_value=0 fi -deployer_public_ip_address=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw deployer_public_ip_address | tr -d \") -if [ -n "${deployer_public_ip_address}" ] -then - save_config_var "deployer_public_ip_address" "${deployer_config_information}" - return_value=0 +random_id=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw random_id_b64 | tr -d \") +if [ -n "${random_id}" ]; then + deployer_random_id="${random_id}" + save_config_var "deployer_random_id" "${deployer_config_information}" + return_value=0 fi +deployer_public_ip_address=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw deployer_public_ip_address | tr -d \") +if [ -n "${deployer_public_ip_address}" ]; then + save_config_var "deployer_public_ip_address" "${deployer_config_information}" + return_value=0 +fi unset TF_DATA_DIR diff --git a/deploy/scripts/install_library.sh b/deploy/scripts/install_library.sh index 3a6259d733..e0a9f22d5f 100755 --- a/deploy/scripts/install_library.sh +++ b/deploy/scripts/install_library.sh @@ -17,33 +17,33 @@ source "${script_directory}/deploy_utils.sh" #Internal helper functions function showhelp { - echo "" - echo "#########################################################################################" - echo "# #" - echo "# #" - echo "# This file contains the logic to deploy the deployer. #" - echo "# The script experts the following exports: #" - echo "# #" - echo "# ARM_SUBSCRIPTION_ID to specify which subscription to deploy to #" - echo "# SAP_AUTOMATION_REPO_PATH the path to the folder containing the cloned sap-automation #" - echo "# #" - echo "# The script will persist the parameters needed between the executions in the #" - echo "# [CONFIG_REPO_PATH]/.sap_deployment_automation folder #" - echo "# #" - echo "# #" - echo "# Usage: install_deployer.sh #" - echo "# -p deployer parameter file #" - echo "# -i interactive true/false setting the value to false will not prompt before apply #" - echo "# -h Show help #" - echo "# #" - echo "# Example: #" - echo "# #" - echo "# [REPO-ROOT]deploy/scripts/install_library.sh \ #" - echo "# -p PROD-WEEU-SAP_LIBRARY.json \ #" - echo "# -d ../../DEPLOYER/PROD-WEEU-DEP00-INFRASTRUCTURE/ \ #" - echo "# -i true #" - echo "# #" - echo "#########################################################################################" + echo "" + echo "#########################################################################################" + echo "# #" + echo "# #" + echo "# This file contains the logic to deploy the deployer. #" + echo "# The script experts the following exports: #" + echo "# #" + echo "# ARM_SUBSCRIPTION_ID to specify which subscription to deploy to #" + echo "# SAP_AUTOMATION_REPO_PATH the path to the folder containing the cloned sap-automation #" + echo "# #" + echo "# The script will persist the parameters needed between the executions in the #" + echo "# [CONFIG_REPO_PATH]/.sap_deployment_automation folder #" + echo "# #" + echo "# #" + echo "# Usage: install_deployer.sh #" + echo "# -p deployer parameter file #" + echo "# -i interactive true/false setting the value to false will not prompt before apply #" + echo "# -h Show help #" + echo "# #" + echo "# Example: #" + echo "# #" + echo "# [REPO-ROOT]deploy/scripts/install_library.sh \ #" + echo "# -p PROD-WEEU-SAP_LIBRARY.json \ #" + echo "# -d ../../DEPLOYER/PROD-WEEU-DEP00-INFRASTRUCTURE/ \ #" + echo "# -i true #" + echo "# #" + echo "#########################################################################################" } #process inputs - may need to check the option i for auto approve as it is not used @@ -56,107 +56,114 @@ if [ "$VALID_ARGUMENTS" != "0" ]; then fi eval set -- "$INPUT_ARGUMENTS" -while : -do +while :; do case "$1" in - -p | --parameterfile) parameterfile="$2" ; shift 2 ;; - -d | --deployer_statefile_foldername) deployer_statefile_foldername="$2" ; shift 2 ;; - -i | --auto-approve) approve="--auto-approve" ; shift ;; - -h | --help) showhelp - exit 3 ; shift ;; - --) shift; break ;; + -p | --parameterfile) + parameterfile="$2" + shift 2 + ;; + -d | --deployer_statefile_foldername) + deployer_statefile_foldername="$2" + shift 2 + ;; + -i | --auto-approve) + approve="--auto-approve" + shift + ;; + -h | --help) + showhelp + exit 3 + shift + ;; + --) + shift + break + ;; esac done deployment_system=sap_library use_deployer=true -if [ ! -f "${parameterfile}" ] -then - printf -v val %-40.40s "$parameterfile" - echo "" - echo "#########################################################################################" - echo "# #" - echo "# Parameter file does not exist: ${val} #" - echo "# #" - echo "#########################################################################################" - exit +if [ ! -f "${parameterfile}" ]; then + printf -v val %-40.40s "$parameterfile" + echo "" + echo "#########################################################################################" + echo "# #" + echo "# Parameter file does not exist: ${val} #" + echo "# #" + echo "#########################################################################################" + exit fi param_dirname=$(dirname "${parameterfile}") if [ $param_dirname != '.' ]; then - echo "" - echo "#########################################################################################" - echo "# #" - echo "# Please run this command from the folder containing the parameter file #" - echo "# #" - echo "#########################################################################################" - exit 3 + echo "" + echo "#########################################################################################" + echo "# #" + echo "# Please run this command from the folder containing the parameter file #" + echo "# #" + echo "#########################################################################################" + exit 3 fi ext=$(echo ${parameterfile} | cut -d. -f2) # Helper variables if [ "${ext}" == json ]; then - environment=$(jq --raw-output .infrastructure.environment "${parameterfile}") - region=$(jq --raw-output .infrastructure.region "${parameterfile}") - use_deployer=$(jq --raw-output .deployer.use "${parameterfile}") + environment=$(jq --raw-output .infrastructure.environment "${parameterfile}") + region=$(jq --raw-output .infrastructure.region "${parameterfile}") + use_deployer=$(jq --raw-output .deployer.use "${parameterfile}") else - load_config_vars "${param_dirname}"/"${parameterfile}" "environment" - load_config_vars "${param_dirname}"/"${parameterfile}" "location" - region=$(echo ${location} | xargs) + load_config_vars "${param_dirname}"/"${parameterfile}" "environment" + load_config_vars "${param_dirname}"/"${parameterfile}" "location" + region=$(echo ${location} | xargs) fi - key=$(echo "${parameterfile}" | cut -d. -f1) -if [ -z "${environment}" ] -then - echo "#########################################################################################" - echo "# #" - echo "# Incorrect parameter file. #" - echo "# #" - echo "# The file needs to contain the environment attribute!! #" - echo "# #" - echo "#########################################################################################" - echo "" - exit 64 +if [ -z "${environment}" ]; then + echo "#########################################################################################" + echo "# #" + echo "# Incorrect parameter file. #" + echo "# #" + echo "# The file needs to contain the environment attribute!! #" + echo "# #" + echo "#########################################################################################" + echo "" + exit 64 fi -if [ -z "${region}" ] -then - echo "#########################################################################################" - echo "# #" - echo "# Incorrect parameter file. #" - echo "# #" - echo "# The file needs to contain the infrastructure.region attribute!! #" - echo "# #" - echo "#########################################################################################" - echo "" - exit 64 +if [ -z "${region}" ]; then + echo "#########################################################################################" + echo "# #" + echo "# Incorrect parameter file. #" + echo "# #" + echo "# The file needs to contain the infrastructure.region attribute!! #" + echo "# #" + echo "#########################################################################################" + echo "" + exit 64 fi # Convert the region to the correct code region=$(echo "${region}" | tr "[:upper:]" "[:lower:]") get_region_code $region - -if [ true == "$use_deployer" ] -then - if [ ! -d "${deployer_statefile_foldername}" ] - then - printf -v val %-40.40s "$deployer_statefile_foldername" - echo "" - echo "#########################################################################################" - echo "# #" - echo "# Directory does not exist: "${deployer_statefile_foldername}" #" - echo "# #" - echo "#########################################################################################" - exit - fi +if [ true == "$use_deployer" ]; then + if [ ! -d "${deployer_statefile_foldername}" ]; then + printf -v val %-40.40s "$deployer_statefile_foldername" + echo "" + echo "#########################################################################################" + echo "# #" + echo "# Directory does not exist: "${deployer_statefile_foldername}" #" + echo "# #" + echo "#########################################################################################" + exit + fi fi #Persisting the parameters across executions @@ -165,17 +172,21 @@ generic_config_information="${automation_config_directory}"config library_config_information="${automation_config_directory}""${environment}""${region_code}" #Plugins -if [ ! -d /opt/terraform/.terraform.d/plugin-cache ] -then +isInCloudShellCheck=$(checkIfCloudShell) + +if checkIfCloudShell; then + mkdir -p "${HOME}/.terraform.d/plugin-cache" + export TF_PLUGIN_CACHE_DIR="${HOME}/.terraform.d/plugin-cache" +else + if [ ! -d /opt/terraform/.terraform.d/plugin-cache ]; then mkdir -p /opt/terraform/.terraform.d/plugin-cache + sudo chown -R "$USER" /opt/terraform + fi + export TF_PLUGIN_CACHE_DIR=/opt/terraform/.terraform.d/plugin-cache fi -sudo chown -R $USER:$USER /opt/terraform -export TF_PLUGIN_CACHE_DIR=/opt/terraform/.terraform.d/plugin-cache - param_dirname=$(pwd) - arm_config_stored=false param_dirname=$(pwd) @@ -186,144 +197,140 @@ export TF_DATA_DIR="${param_dirname}"/.terraform var_file="${param_dirname}"/"${parameterfile}" if [ ! -n "${SAP_AUTOMATION_REPO_PATH}" ]; then - echo "" - echo "#########################################################################################" - echo "# #" - echo "# Missing environment variables (SAP_AUTOMATION_REPO_PATH)!!! #" - echo "# #" - echo "# Please export the folloing variables: #" - echo "# SAP_AUTOMATION_REPO_PATH (path to the repo folder (sap-automation)) #" - echo "# ARM_SUBSCRIPTION_ID (subscription containing the state file storage account) #" - echo "# #" - echo "#########################################################################################" - unset TF_DATA_DIR - exit 4 + echo "" + echo "#########################################################################################" + echo "# #" + echo "# Missing environment variables (SAP_AUTOMATION_REPO_PATH)!!! #" + echo "# #" + echo "# Please export the folloing variables: #" + echo "# SAP_AUTOMATION_REPO_PATH (path to the repo folder (sap-automation)) #" + echo "# ARM_SUBSCRIPTION_ID (subscription containing the state file storage account) #" + echo "# #" + echo "#########################################################################################" + unset TF_DATA_DIR + exit 4 fi templen=$(echo "${ARM_SUBSCRIPTION_ID}" | wc -c) # Subscription length is 37 -if [ 37 != $templen ] -then - arm_config_stored=false +if [ 37 != $templen ]; then + arm_config_stored=false fi if [ ! -n "$ARM_SUBSCRIPTION_ID" ]; then - echo "" - echo "#########################################################################################" - echo "# #" - echo "# Missing environment variables (ARM_SUBSCRIPTION_ID)!!! #" - echo "# #" - echo "# Please export the folloing variables: #" - echo "# SAP_AUTOMATION_REPO_PATH (path to the repo folder (sap-automation)) #" - echo "# ARM_SUBSCRIPTION_ID (subscription containing the state file storage account) #" - echo "# #" - echo "#########################################################################################" - unset TF_DATA_DIR - exit 3 + echo "" + echo "#########################################################################################" + echo "# #" + echo "# Missing environment variables (ARM_SUBSCRIPTION_ID)!!! #" + echo "# #" + echo "# Please export the folloing variables: #" + echo "# SAP_AUTOMATION_REPO_PATH (path to the repo folder (sap-automation)) #" + echo "# ARM_SUBSCRIPTION_ID (subscription containing the state file storage account) #" + echo "# #" + echo "#########################################################################################" + unset TF_DATA_DIR + exit 3 fi terraform_module_directory="${SAP_AUTOMATION_REPO_PATH}"/deploy/terraform/bootstrap/"${deployment_system}"/ -if [ ! -d ${terraform_module_directory} ] -then - echo "#########################################################################################" - echo "# #" - echo "# Incorrect system deployment type specified :" ${deployment_system} " #" - echo "# #" - echo "# Valid options are: #" - echo "# sap_library #" - echo "# #" - echo "#########################################################################################" - echo "" - unset TF_DATA_DIR - exit 64 +if [ ! -d ${terraform_module_directory} ]; then + echo "#########################################################################################" + echo "# #" + echo "# Incorrect system deployment type specified :" ${deployment_system} " #" + echo "# #" + echo "# Valid options are: #" + echo "# sap_library #" + echo "# #" + echo "#########################################################################################" + echo "" + unset TF_DATA_DIR + exit 64 fi reinitialized=0 -if [ -f ./backend-config.tfvars ] -then - echo "#########################################################################################" - echo "# #" - echo "# The bootstrapping has already been done! #" - echo "# #" - echo "#########################################################################################" +if [ -f ./backend-config.tfvars ]; then + echo "#########################################################################################" + echo "# #" + echo "# The bootstrapping has already been done! #" + echo "# #" + echo "#########################################################################################" else - sed -i /REMOTE_STATE_RG/d "${library_config_information}" - sed -i /REMOTE_STATE_SA/d "${library_config_information}" - sed -i /tfstate_resource_id/d "${library_config_information}" + sed -i /REMOTE_STATE_RG/d "${library_config_information}" + sed -i /REMOTE_STATE_SA/d "${library_config_information}" + sed -i /tfstate_resource_id/d "${library_config_information}" fi if [ ! -d ./.terraform/ ]; then - echo "#########################################################################################" - echo "# #" - echo "# New deployment #" - echo "# #" - echo "#########################################################################################" - terraform -chdir="${terraform_module_directory}" init -upgrade=true -backend-config "path=${param_dirname}/terraform.tfstate" - sed -i /REMOTE_STATE_RG/d "${library_config_information}" - sed -i /REMOTE_STATE_SA/d "${library_config_information}" - sed -i /tfstate_resource_id/d "${library_config_information}" + echo "#########################################################################################" + echo "# #" + echo "# New deployment #" + echo "# #" + echo "#########################################################################################" + terraform -chdir="${terraform_module_directory}" init -upgrade=true -backend-config "path=${param_dirname}/terraform.tfstate" + sed -i /REMOTE_STATE_RG/d "${library_config_information}" + sed -i /REMOTE_STATE_SA/d "${library_config_information}" + sed -i /tfstate_resource_id/d "${library_config_information}" else - if [ -f ./.terraform/terraform.tfstate ]; then - if grep "azurerm" ./.terraform/terraform.tfstate ; then + if [ -f ./.terraform/terraform.tfstate ]; then + if grep "azurerm" ./.terraform/terraform.tfstate; then + echo "#########################################################################################" + echo "# #" + echo "# The state is already migrated to Azure!!! #" + echo "# #" + echo "#########################################################################################" + + if [ $approve == "--auto-approve" ]; then + tfstate_resource_id=$(az resource list --name $REINSTALL_ACCOUNTNAME --subscription $REINSTALL_SUBSCRIPTION --resource-type Microsoft.Storage/storageAccounts --query "[].id | [0]" -o tsv) + if [ -n "${tfstate_resource_id}" ]; then + echo "Reinitializing against remote state" + terraform_module_directory="${SAP_AUTOMATION_REPO_PATH}"/deploy/terraform/run/"${deployment_system}"/ + export TF_VAR_tfstate_resource_id=$tfstate_resource_id + terraform -chdir="${terraform_module_directory}" init -upgrade=true \ + --backend-config "subscription_id=$REINSTALL_SUBSCRIPTION" \ + --backend-config "resource_group_name=$REINSTALL_RESOURCE_GROUP" \ + --backend-config "storage_account_name=$REINSTALL_ACCOUNTNAME" \ + --backend-config "container_name=tfstate" \ + --backend-config "key=${key}.terraform.tfstate" + terraform -chdir="${terraform_module_directory}" refresh -var-file="${var_file}" + + else + terraform -chdir="${terraform_module_directory}" init -upgrade=true -reconfigure -backend-config "path=${param_dirname}/terraform.tfstate" + terraform -chdir="${terraform_module_directory}" refresh -var-file="${var_file}" + fi + else + + read -p "Do you want to re bootstrap the SAP library Y/N?" ans + answer=${ans^^} + if [ $answer == 'Y' ]; then + terraform -chdir="${terraform_module_directory}" init -upgrade=true -reconfigure -backend-config "path=${param_dirname}/terraform.tfstate" + return_value=$? + if [ 0 != $return_value ]; then + echo "" echo "#########################################################################################" echo "# #" - echo "# The state is already migrated to Azure!!! #" + echo -e "# $boldreduscore Errors during the init phase $resetformatting #" echo "# #" echo "#########################################################################################" - - if [ $approve == "--auto-approve" ] ; then - tfstate_resource_id=$(az resource list --name $REINSTALL_ACCOUNTNAME --subscription $REINSTALL_SUBSCRIPTION --resource-type Microsoft.Storage/storageAccounts --query "[].id | [0]" -o tsv) - if [ -n "${tfstate_resource_id}" ]; then - echo "Reinitializing against remote state" - terraform_module_directory="${SAP_AUTOMATION_REPO_PATH}"/deploy/terraform/run/"${deployment_system}"/ - export TF_VAR_tfstate_resource_id=$tfstate_resource_id - terraform -chdir="${terraform_module_directory}" init -upgrade=true \ - --backend-config "subscription_id=$REINSTALL_SUBSCRIPTION" \ - --backend-config "resource_group_name=$REINSTALL_RESOURCE_GROUP" \ - --backend-config "storage_account_name=$REINSTALL_ACCOUNTNAME" \ - --backend-config "container_name=tfstate" \ - --backend-config "key=${key}.terraform.tfstate" - terraform -chdir="${terraform_module_directory}" refresh -var-file="${var_file}" - - else - terraform -chdir="${terraform_module_directory}" init -upgrade=true -reconfigure -backend-config "path=${param_dirname}/terraform.tfstate" - terraform -chdir="${terraform_module_directory}" refresh -var-file="${var_file}" - fi - else - - read -p "Do you want to re bootstrap the SAP library Y/N?" ans - answer=${ans^^} - if [ $answer == 'Y' ]; then - terraform -chdir="${terraform_module_directory}" init -upgrade=true -reconfigure -backend-config "path=${param_dirname}/terraform.tfstate" - return_value=$? - if [ 0 != $return_value ] ; then - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldreduscore Errors during the init phase $resetformatting #" - echo "# #" - echo "#########################################################################################" - echo "" - unset TF_DATA_DIR - exit $return_value - fi - else - unset TF_DATA_DIR - exit 0 - fi - fi + echo "" + unset TF_DATA_DIR + exit $return_value + fi else - terraform -chdir="${terraform_module_directory}" init -upgrade=true -backend-config "path=${param_dirname}/terraform.tfstate" + unset TF_DATA_DIR + exit 0 fi + fi else - terraform -chdir="${terraform_module_directory}" init -upgrade=true -backend-config "path=${param_dirname}/terraform.tfstate" + terraform -chdir="${terraform_module_directory}" init -upgrade=true -backend-config "path=${param_dirname}/terraform.tfstate" fi + else + terraform -chdir="${terraform_module_directory}" init -upgrade=true -backend-config "path=${param_dirname}/terraform.tfstate" + fi fi - echo "" echo "#########################################################################################" echo "# #" @@ -333,60 +340,58 @@ echo "########################################################################## echo "" if [ -n "${deployer_statefile_foldername}" ]; then - echo "Deployer folder specified:" "${deployer_statefile_foldername}" - terraform -chdir="${terraform_module_directory}" plan -no-color -detailed-exitcode -var-file="${var_file}" -var deployer_statefile_foldername="${deployer_statefile_foldername}" > plan_output.log 2>&1 + echo "Deployer folder specified: ${deployer_statefile_foldername}" + terraform -chdir="${terraform_module_directory}" plan -no-color -detailed-exitcode -var-file="${var_file}" -var deployer_statefile_foldername="${deployer_statefile_foldername}" >plan_output.log 2>&1 else - terraform -chdir="${terraform_module_directory}" plan -no-color -detailed-exitcode -var-file="${var_file}" > plan_output.log 2>&1 + terraform -chdir="${terraform_module_directory}" plan -no-color -detailed-exitcode -var-file="${var_file}" >plan_output.log 2>&1 fi return_value=$? -if [ 0 == $return_value ] ; then - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $cyan Infrastructure is up to date $resetformatting #" - echo "# #" - echo "#########################################################################################" - echo "" - if [ -f plan_output.log ] - then - rm plan_output.log - fi +if [ 0 == $return_value ]; then + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $cyan Infrastructure is up to date $resetformatting #" + echo "# #" + echo "#########################################################################################" + echo "" + if [ -f plan_output.log ]; then + rm plan_output.log + fi - tfstate_resource_id=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw tfstate_resource_id| tr -d \") - STATE_SUBSCRIPTION=$(echo $tfstate_resource_id | cut -d/ -f3 | tr -d \" | xargs) + tfstate_resource_id=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw tfstate_resource_id | tr -d \") + STATE_SUBSCRIPTION=$(echo $tfstate_resource_id | cut -d/ -f3 | tr -d \" | xargs) - az account set --sub $STATE_SUBSCRIPTION + az account set --sub $STATE_SUBSCRIPTION - REMOTE_STATE_SA=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw remote_state_storage_account_name| tr -d \") + REMOTE_STATE_SA=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw remote_state_storage_account_name | tr -d \") - get_and_store_sa_details ${REMOTE_STATE_SA} "${system_config_information}" + get_and_store_sa_details ${REMOTE_STATE_SA} "${system_config_information}" - unset TF_DATA_DIR - exit $return_value + unset TF_DATA_DIR + exit $return_value fi -if [ 1 == $return_value ] -then - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldreduscore Errors during the plan phase $resetformatting #" - echo "# #" - echo "#########################################################################################" - echo "" +if [ 1 == $return_value ]; then + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldreduscore Errors during the plan phase $resetformatting #" + echo "# #" + echo "#########################################################################################" + echo "" - if [ -f plan_output.log ]; then - cat plan_output.log - rm plan_output.log - fi - unset TF_DATA_DIR - exit $return_value + if [ -f plan_output.log ]; then + cat plan_output.log + rm plan_output.log + fi + unset TF_DATA_DIR + exit $return_value fi if [ -f plan_output.log ]; then - cat plan_output.log - rm plan_output.log + cat plan_output.log + rm plan_output.log fi echo "" @@ -398,117 +403,106 @@ echo "########################################################################## echo "" deployer_parameter="" -if [ -n "${deployer_statefile_foldername}" ]; -then - echo "Deployer folder specified:" "${deployer_statefile_foldername}" - if [ -n "${approve}" ] - then - terraform -chdir="${terraform_module_directory}" apply -var-file="${var_file}" -var deployer_statefile_foldername="${deployer_statefile_foldername}" -auto-approve -json | tee -a apply_output.json - else - terraform -chdir="${terraform_module_directory}" apply -var-file="${var_file}" -var deployer_statefile_foldername="${deployer_statefile_foldername}" - fi +if [ -n "${deployer_statefile_foldername}" ]; then + echo "Deployer folder specified: ${deployer_statefile_foldername}" + if [ -n "${approve}" ]; then + terraform -chdir="${terraform_module_directory}" apply -var-file="${var_file}" -var deployer_statefile_foldername="${deployer_statefile_foldername}" -auto-approve -json | tee -a apply_output.json + else + terraform -chdir="${terraform_module_directory}" apply -var-file="${var_file}" -var deployer_statefile_foldername="${deployer_statefile_foldername}" + fi else - if [ -n "${approve}" ] - then - terraform -chdir="${terraform_module_directory}" apply -var-file="${var_file}" -auto-approve -json | tee -a apply_output.json - else - terraform -chdir="${terraform_module_directory}" apply -var-file="${var_file}" - fi + if [ -n "${approve}" ]; then + terraform -chdir="${terraform_module_directory}" apply -var-file="${var_file}" -auto-approve -json | tee -a apply_output.json + else + terraform -chdir="${terraform_module_directory}" apply -var-file="${var_file}" + fi fi return_value=$? rerun_apply=0 -if [ -f apply_output.json ] -then - errors_occurred=$(jq 'select(."@level" == "error") | length' apply_output.json) - - # Check for resource that can be imported - existing=$(jq 'select(."@level" == "error") | {address: .diagnostic.address, summary: .diagnostic.summary} | select(.summary | startswith("A resource with the ID"))' apply_output.json) - if [[ -n ${existing} ]] - then - - readarray -t existing_resources < <(echo ${existing} | jq -c '.' ) - for item in "${existing_resources[@]}"; do - moduleID=$(jq -c -r '.address ' <<< "$item") - resourceID=$(jq -c -r '.summary' <<< "$item" | awk -F'\"' '{print $2}') - echo "Trying to import" $resourceID "into" $moduleID - - if [ -n "${deployer_statefile_foldername}" ]; - then - echo "Deployer folder specified:" "${deployer_statefile_foldername}" - terraform -chdir="${terraform_module_directory}" import -var-file="${var_file}" -var deployer_statefile_foldername="${deployer_statefile_foldername}" $moduleID $resourceID - else - terraform -chdir="${terraform_module_directory}" import -var-file="${var_file}" $moduleID $resourceID - fi - - done - rerun_apply=1 - fi - if [ $rerun_apply == 1 ] ; then - echo "" - echo "#########################################################################################" - echo "# #" - echo "# Re-running Terraform apply #" - echo "# #" - echo "#########################################################################################" - echo "" - if [ -n "${deployer_statefile_foldername}" ]; - then - echo "Deployer folder specified:" "${deployer_statefile_foldername}" - terraform -chdir="${terraform_module_directory}" apply -var-file="${var_file}" -var deployer_statefile_foldername="${deployer_statefile_foldername}" -auto-approve -json | tee -a apply_output.json - else - terraform -chdir="${terraform_module_directory}" apply -var-file="${var_file}" -auto-approve -json | tee -a apply_output.json - fi - return_value=$? - rerun_apply=0 - fi - errors_occurred=$(jq 'select(."@level" == "error") | length' apply_output.json) - - # Check for resource that can be imported - existing=$(jq 'select(."@level" == "error") | {address: .diagnostic.address, summary: .diagnostic.summary} | select(.summary | startswith("A resource with the ID"))' apply_output.json) - if [[ -n ${existing} ]] - then - - readarray -t existing_resources < <(echo ${existing} | jq -c '.' ) - for item in "${existing_resources[@]}"; do - moduleID=$(jq -c -r '.address ' <<< "$item") - resourceID=$(jq -c -r '.summary' <<< "$item" | awk -F'\"' '{print $2}') - echo "Trying to import" $resourceID "into" $moduleID - - if [ -n "${deployer_statefile_foldername}" ]; - then - echo "Deployer folder specified:" "${deployer_statefile_foldername}" - terraform -chdir="${terraform_module_directory}" import -var-file="${var_file}" -var deployer_statefile_foldername="${deployer_statefile_foldername}" $moduleID $resourceID - else - terraform -chdir="${terraform_module_directory}" import -var-file="${var_file}" $moduleID $resourceID - fi - - done - rerun_apply=1 +if [ -f apply_output.json ]; then + errors_occurred=$(jq 'select(."@level" == "error") | length' apply_output.json) + + # Check for resource that can be imported + existing=$(jq 'select(."@level" == "error") | {address: .diagnostic.address, summary: .diagnostic.summary} | select(.summary | startswith("A resource with the ID"))' apply_output.json) + if [[ -n ${existing} ]]; then + + readarray -t existing_resources < <(echo ${existing} | jq -c '.') + for item in "${existing_resources[@]}"; do + moduleID=$(jq -c -r '.address ' <<<"$item") + resourceID=$(jq -c -r '.summary' <<<"$item" | awk -F'\"' '{print $2}') + echo "Trying to import" $resourceID "into" $moduleID + + if [ -n "${deployer_statefile_foldername}" ]; then + echo "Deployer folder specified: ${deployer_statefile_foldername}" + terraform -chdir="${terraform_module_directory}" import -var-file="${var_file}" -var deployer_statefile_foldername="${deployer_statefile_foldername}" $moduleID $resourceID + else + terraform -chdir="${terraform_module_directory}" import -var-file="${var_file}" $moduleID $resourceID + fi + + done + rerun_apply=1 + fi + if [ $rerun_apply == 1 ]; then + echo "" + echo "#########################################################################################" + echo "# #" + echo "# Re-running Terraform apply #" + echo "# #" + echo "#########################################################################################" + echo "" + if [ -n "${deployer_statefile_foldername}" ]; then + echo "Deployer folder specified: ${deployer_statefile_foldername}" + terraform -chdir="${terraform_module_directory}" apply -var-file="${var_file}" -var deployer_statefile_foldername="${deployer_statefile_foldername}" -auto-approve -json | tee -a apply_output.json + else + terraform -chdir="${terraform_module_directory}" apply -var-file="${var_file}" -auto-approve -json | tee -a apply_output.json fi - - if [ $rerun_apply == 1 ] ; then - echo "" - echo "#########################################################################################" - echo "# #" - echo "# Re-running Terraform apply #" - echo "# #" - echo "#########################################################################################" - echo "" - if [ -n "${deployer_statefile_foldername}" ]; - then - echo "Deployer folder specified:" "${deployer_statefile_foldername}" - terraform -chdir="${terraform_module_directory}" apply -var-file="${var_file}" -var deployer_statefile_foldername="${deployer_statefile_foldername}" -auto-approve -json | tee -a apply_output.json - else - terraform -chdir="${terraform_module_directory}" apply -var-file="${var_file}" -auto-approve -json | tee -a apply_output.json - fi - return_value=$? - rerun_apply=0 + return_value=$? + rerun_apply=0 + fi + errors_occurred=$(jq 'select(."@level" == "error") | length' apply_output.json) + + # Check for resource that can be imported + existing=$(jq 'select(."@level" == "error") | {address: .diagnostic.address, summary: .diagnostic.summary} | select(.summary | startswith("A resource with the ID"))' apply_output.json) + if [[ -n ${existing} ]]; then + + readarray -t existing_resources < <(echo ${existing} | jq -c '.') + for item in "${existing_resources[@]}"; do + moduleID=$(jq -c -r '.address ' <<<"$item") + resourceID=$(jq -c -r '.summary' <<<"$item" | awk -F'\"' '{print $2}') + echo "Trying to import" $resourceID "into" $moduleID + + if [ -n "${deployer_statefile_foldername}" ]; then + echo "Deployer folder specified: ${deployer_statefile_foldername}" + terraform -chdir="${terraform_module_directory}" import -var-file="${var_file}" -var deployer_statefile_foldername="${deployer_statefile_foldername}" $moduleID $resourceID + else + terraform -chdir="${terraform_module_directory}" import -var-file="${var_file}" $moduleID $resourceID + fi + + done + rerun_apply=1 + fi + + if [ $rerun_apply == 1 ]; then + echo "" + echo "#########################################################################################" + echo "# #" + echo "# Re-running Terraform apply #" + echo "# #" + echo "#########################################################################################" + echo "" + if [ -n "${deployer_statefile_foldername}" ]; then + echo "Deployer folder specified: ${deployer_statefile_foldername}" + terraform -chdir="${terraform_module_directory}" apply -var-file="${var_file}" -var deployer_statefile_foldername="${deployer_statefile_foldername}" -auto-approve -json | tee -a apply_output.json + else + terraform -chdir="${terraform_module_directory}" apply -var-file="${var_file}" -auto-approve -json | tee -a apply_output.json fi - errors_occurred=$(jq 'select(."@level" == "error") | length' apply_output.json) + return_value=$? + rerun_apply=0 + fi + errors_occurred=$(jq 'select(."@level" == "error") | length' apply_output.json) - if [[ -n $errors_occurred ]] - then + if [[ -n $errors_occurred ]]; then echo "" echo "#########################################################################################" echo "# #" @@ -516,91 +510,80 @@ then return_value=2 all_errors=$(jq 'select(."@level" == "error") | {summary: .diagnostic.summary, detail: .diagnostic.detail}' apply_output.json) - if [[ -n ${all_errors} ]] - then - readarray -t errors_strings < <(echo ${all_errors} | jq -c '.' ) - for errors_string in "${errors_strings[@]}"; do - string_to_report=$(jq -c -r '.detail ' <<< "$errors_string" ) - if [[ -z ${string_to_report} ]] - then - string_to_report=$(jq -c -r '.summary ' <<< "$errors_string" ) - fi + if [[ -n ${all_errors} ]]; then + readarray -t errors_strings < <(echo ${all_errors} | jq -c '.') + for errors_string in "${errors_strings[@]}"; do + string_to_report=$(jq -c -r '.detail ' <<<"$errors_string") + if [[ -z ${string_to_report} ]]; then + string_to_report=$(jq -c -r '.summary ' <<<"$errors_string") + fi - echo -e "# $boldreduscore $string_to_report $resetformatting" - echo "##vso[task.logissue type=error]${string_to_report}" + echo -e "# $boldreduscore $string_to_report $resetformatting" + echo "##vso[task.logissue type=error]${string_to_report}" - done + done fi echo "# #" echo "#########################################################################################" echo "" - fi + fi fi -if [ -f apply_output.json ] -then - rm apply_output.json +if [ -f apply_output.json ]; then + rm apply_output.json fi -if [ 1 == $return_value ] ; then - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldreduscore Errors during the apply phase $resetformatting #" - echo "# #" - echo "#########################################################################################" - echo "" - unset TF_DATA_DIR - exit $return_value +if [ 1 == $return_value ]; then + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldreduscore Errors during the apply phase $resetformatting #" + echo "# #" + echo "#########################################################################################" + echo "" + unset TF_DATA_DIR + exit $return_value fi -REMOTE_STATE_SA=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw remote_state_storage_account_name| tr -d \") +REMOTE_STATE_SA=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw remote_state_storage_account_name | tr -d \") temp=$(echo "${REMOTE_STATE_SA}" | grep -m1 "Warning") -if [ -z "${temp}" ] -then - temp=$(echo "${REMOTE_STATE_SA}" | grep "Backend reinitialization required") - if [ -z "${temp}" ] - then - save_config_var "REMOTE_STATE_SA" "${library_config_information}" - fi +if [ -z "${temp}" ]; then + temp=$(echo "${REMOTE_STATE_SA}" | grep "Backend reinitialization required") + if [ -z "${temp}" ]; then + save_config_var "REMOTE_STATE_SA" "${library_config_information}" + fi fi -tfstate_resource_id=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw tfstate_resource_id| tr -d \") +tfstate_resource_id=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw tfstate_resource_id | tr -d \") temp=$(echo $tfstate_resource_id | grep -m1 "Warning") -if [ -z "${temp}" ] -then - temp=$(echo "${tfstate_resource_id}" | grep "Backend reinitialization required") - if [ -z "${temp}" ] - then - save_config_var "tfstate_resource_id" "${library_config_information}" - fi +if [ -z "${temp}" ]; then + temp=$(echo "${tfstate_resource_id}" | grep "Backend reinitialization required") + if [ -z "${temp}" ]; then + save_config_var "tfstate_resource_id" "${library_config_information}" + fi fi REMOTE_STATE_RG=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw created_resource_group_name | tr -d \") temp=$(echo "${REMOTE_STATE_RG}" | grep -m1 "Warning") -if [ -z "${temp}" ] -then - temp=$(echo "${REMOTE_STATE_RG}" | grep "Backend reinitialization required") - if [ -z "${temp}" ] - then - save_config_var "REMOTE_STATE_RG" "${library_config_information}" - return_value=0 - fi +if [ -z "${temp}" ]; then + temp=$(echo "${REMOTE_STATE_RG}" | grep "Backend reinitialization required") + if [ -z "${temp}" ]; then + save_config_var "REMOTE_STATE_RG" "${library_config_information}" + return_value=0 + fi fi random_id_b64=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw random_id_b64 | tr -d \") temp=$(echo "${random_id_b64}" | grep -m1 "Warning") -if [ -z "${temp}" ] -then - temp=$(echo "${random_id_b64}" | grep "Backend reinitialization required") - if [ -z "${temp}" ] - then - save_config_var "library_random_id" "${random_id_b64}" - return_value=0 - fi +if [ -z "${temp}" ]; then + temp=$(echo "${random_id_b64}" | grep "Backend reinitialization required") + if [ -z "${temp}" ]; then + save_config_var "library_random_id" "${random_id_b64}" + return_value=0 + fi fi exit $return_value diff --git a/deploy/scripts/install_workloadzone.sh b/deploy/scripts/install_workloadzone.sh index e2e9c9a6b9..42af391e2a 100755 --- a/deploy/scripts/install_workloadzone.sh +++ b/deploy/scripts/install_workloadzone.sh @@ -12,9 +12,11 @@ full_script_path="$(realpath "${BASH_SOURCE[0]}")" script_directory="$(dirname "${full_script_path}")" #call stack has full scriptname when using source +# shellcheck disable=SC1091 source "${script_directory}/deploy_utils.sh" #helper files +# shellcheck disable=SC1091 source "${script_directory}/helpers/script_helpers.sh" force=0 @@ -64,14 +66,14 @@ this_ip=$(curl -s ipinfo.io/ip) >/dev/null 2>&1 deployer_environment=$(echo "${deployer_environment}" | tr "[:lower:]" "[:upper:]") -echo "Deployer environment: $deployer_environment" +echo "Deployer environment: $deployer_environment" if [ 1 == $called_from_ado ] ; then this_ip=$(curl -s ipinfo.io/ip) >/dev/null 2>&1 export TF_VAR_Agent_IP=$this_ip - echo "Agent IP: $this_ip" -fi + echo "Agent IP: $this_ip" +fi workload_file_parametername=$(basename "${parameterfile}") @@ -115,12 +117,24 @@ fi # Check that parameter files have environment and location defined validate_key_parameters "$workload_file_parametername" +return_code=$? if [ 0 != $return_code ]; then exit $return_code fi +# Convert the region to the correct code +get_region_code "$region" + + +if [ "${region_code}" == 'UNKN' ]; then + LOCATION_CODE=$(echo "$workload_file_parametername" | awk -F'-' '{print $2}' ) + region_code=$(echo "${LOCATION_CODE}" | tr "[:lower:]" "[:upper:]" | xargs) +fi + +echo "Region code: ${region_code}" + load_config_vars "$workload_file_parametername" "network_logical_name" -network_logical_name=$(echo "${network_logical_name}" | tr "[:lower:]" "[:upper:]") +network_logical_name=$(echo "${network_logical_name}" | tr "[:lower:]" "[:upper:]" | xargs) if [ -z "${network_logical_name}" ]; then echo "#########################################################################################" @@ -134,31 +148,25 @@ if [ -z "${network_logical_name}" ]; then return 64 #script usage wrong fi - -# Convert the region to the correct code -region=$(echo "${region}" | tr "[:upper:]" "[:lower:]") -get_region_code "$region" - key=$(echo "${workload_file_parametername}" | cut -d. -f1) landscape_tfstate_key=${key}.terraform.tfstate -echo "Deployment region: $region" -echo "Deployment region code: $region_code" -echo "Keyvault: $keyvault" - #Persisting the parameters across executions automation_config_directory=$CONFIG_REPO_PATH/.sap_deployment_automation generic_config_information="${automation_config_directory}"/config -if [ $deployer_environment != $environment ]; then +if [ "$deployer_environment" != "$environment" ]; then if [ -f "${automation_config_directory}"/"${environment}""${region_code}" ]; then # Add support for having multiple vnets in the same environment and zone - rename exiting file to support seamless transition mv "${automation_config_directory}"/"${environment}""${region_code}" "${automation_config_directory}"/"${environment}""${region_code}""${network_logical_name}" fi fi -workload_config_information="${automation_config_directory}"/"${environment}""${region_code}""${network_logical_name}" +workload_config_information="${automation_config_directory}/${environment}${region_code}${network_logical_name}" +deployer_config_information="${automation_config_directory}/${deployer_environment}${region_code}" +save_config_vars "${workload_config_information}" \ + STATE_SUBSCRIPTION REMOTE_STATE_SA subscription if [ "${force}" == 1 ] then @@ -169,13 +177,20 @@ then rm -Rf .terraform terraform.tfstate* fi -echo "Workload configuration file: $workload_config_information" - -if [ -n "$STATE_SUBSCRIPTION" ] +echo "" +echo "Configuration file: ${environment}${region_code}${network_logical_name}" +echo "Deployment region: $region" +echo "Deployment region code: $region_code" +echo "Deployment environment: $deployer_environment" +echo "Deployer Keyvault: $keyvault" +echo "Deployer Subscription: $STATE_SUBSCRIPTION" +echo "Remote state storage account: $REMOTE_STATE_SA" +echo "Target Subscription: $subscription" + +if [[ -n $STATE_SUBSCRIPTION ]] then - echo "Saving the state subscription" if is_valid_guid "$STATE_SUBSCRIPTION" ; then - echo "Valid subscription format" + save_config_vars "${workload_config_information}" \ STATE_SUBSCRIPTION @@ -202,7 +217,6 @@ then fi if [ -n "$REMOTE_STATE_SA" ] ; then - get_and_store_sa_details ${REMOTE_STATE_SA} ${workload_config_information} fi @@ -265,7 +279,7 @@ then if [ -n "$deployer_environment" ] then deployer_config_information="${automation_config_directory}"/"${deployer_environment}""${region_code}" - echo "Deployer config file $deployer_config_information" + echo "Deployer config file: $deployer_config_information" if [ -f "$deployer_config_information" ] then load_config_vars "${deployer_config_information}" "keyvault" @@ -273,7 +287,7 @@ then load_config_vars "${deployer_config_information}" "REMOTE_STATE_SA" load_config_vars "${deployer_config_information}" "tfstate_resource_id" load_config_vars "${deployer_config_information}" "deployer_tfstate_key" - echo "tfstate_resource_id: $tfstate_resource_id" + save_config_vars "${workload_config_information}" \ tfstate_resource_id @@ -286,12 +300,15 @@ then fi fi else - echo "tfstate_resource_id $tfstate_resource_id" + + echo "Terraform Storage Account Id: $tfstate_resource_id" + save_config_vars "${workload_config_information}" \ tfstate_resource_id fi +echo "" init "${automation_config_directory}" "${generic_config_information}" "${workload_config_information}" param_dirname=$(pwd) @@ -301,7 +318,8 @@ export TF_DATA_DIR="${param_dirname}/.terraform" if [ -n "$subscription" ] then if is_valid_guid "$subscription" ; then - echo "Valid subscription format" + echo "" + export ARM_SUBSCRIPTION_ID="${subscription}" else printf -v val %-40.40s "$subscription" echo "#########################################################################################" @@ -319,7 +337,7 @@ if [ 0 = "${deploy_using_msi_only:-}" ]; then if [ -n "$client_id" ] then if is_valid_guid "$client_id" ; then - echo "Valid spn id format" + echo "" else printf -v val %-40.40s "$client_id" echo "#########################################################################################" @@ -334,7 +352,7 @@ if [ 0 = "${deploy_using_msi_only:-}" ]; then if [ -n "$tenant_id" ] then if is_valid_guid "$tenant_id" ; then - echo "Valid tenant id format" + echo "" else printf -v val %-40.40s "$tenant_id" echo "#########################################################################################" @@ -347,7 +365,12 @@ if [ 0 = "${deploy_using_msi_only:-}" ]; then fi #setting the user environment variables - set_executing_user_environment_variables "${spn_secret}" + if [ -n "${spn_secret}" ] + then + set_executing_user_environment_variables "${spn_secret}" + else + set_executing_user_environment_variables "none" + fi else #setting the user environment variables set_executing_user_environment_variables "N/A" @@ -419,10 +442,10 @@ fi useSAS=$(az storage account show --name "${REMOTE_STATE_SA}" --query allowSharedKeyAccess --subscription "${STATE_SUBSCRIPTION}" --out tsv) if [ "$useSAS" = "true" ] ; then - echo "Authenticate storage using SAS" + echo "Storage Account authentication: key" export ARM_USE_AZUREAD=false else - echo "Authenticate storage using Entra ID" + echo "Storage Account authentication: Entra ID" export ARM_USE_AZUREAD=true fi @@ -432,9 +455,9 @@ if [ 1 = "${deploy_using_msi_only:-}" ]; then then echo "Setting the secrets" - allParams=$(printf " --workload --environment %s --region %s --vault %s --subscription %s --msi " "${environment}" "${region_code}" "${keyvault}" "${subscription}" ) + allParams=$(printf " --workload --environment %s --region %s --vault %s --keyvault_subscription %s --subscription %s --msi " "${environment}" "${region_code}" "${keyvault}" "${STATE_SUBSCRIPTION}" "${ARM_SUBSCRIPTION_ID}" ) - echo "Calling set_secrets with " "${allParams}" + echo "Calling set_secrets with: ${allParams}" "${SAP_AUTOMATION_REPO_PATH}"/deploy/scripts/set_secrets.sh ${allParams} @@ -456,13 +479,13 @@ else if [ -n "$spn_secret" ] then - allParams=$(printf " --workload --environment %s --region %s --vault %s --spn_secret ***** --subscription %s --spn_id %s --tenant_id %s " "${environment}" "${region_code}" "${keyvault}" "${subscription}" "${client_id}" "${tenant_id}" ) + fixed_allParams=$(printf " --workload --environment %s --region %s --vault %s --subscription %s --spn_secret ***** --keyvault_subscription %s --spn_id %s --tenant_id %s " "${environment}" "${region_code}" "${keyvault}" "${ARM_SUBSCRIPTION_ID}" "${STATE_SUBSCRIPTION}" "${client_id}" "${tenant_id}" ) - echo "Calling set_secrets with " "${allParams}" + echo "Calling set_secrets with: ${fixed_allParams}" - allParams=$(printf " --workload --environment %s --region %s --vault %s --spn_secret %s --subscription %s --spn_id %s --tenant_id %s " "${environment}" "${region_code}" "${keyvault}" "${spn_secret}" "${subscription}" "${client_id}" "${tenant_id}" ) + allParams=$(printf " --workload --environment %s --region %s --vault %s --spn_secret %s --subscription %s --keyvault_subscription %s --spn_id %s --tenant_id %s " "${environment}" "${region_code}" "${keyvault}" "${spn_secret}" "${ARM_SUBSCRIPTION_ID}" "${STATE_SUBSCRIPTION}" "${client_id}" "${tenant_id}" ) - "${SAP_AUTOMATION_REPO_PATH}"/deploy/scripts/set_secrets.sh ${allParams} + "${SAP_AUTOMATION_REPO_PATH}/deploy/scripts/set_secrets.sh" ${allParams} if [ -f secret.err ]; then error_message=$(cat secret.err) @@ -474,9 +497,9 @@ else read -p "Do you want to specify the Workload SPN Details Y/N?" ans answer=${ans^^} if [ ${answer} == 'Y' ]; then - allParams=$(printf " --workload --environment %s --region %s --vault %s --subscription %s --spn_id %s " "${environment}" "${region_code}" "${keyvault}" "${subscription}" "${client_id}" ) + allParams=$(printf " --workload --environment %s --region %s --vault %s --subscription %s --spn_id %s " "${environment}" "${region_code}" "${keyvault}" "${STATE_SUBSCRIPTION}" "${client_id}" ) - "${SAP_AUTOMATION_REPO_PATH}"/deploy/scripts/set_secrets.sh ${allParams} + "${SAP_AUTOMATION_REPO_PATH}/deploy/scripts/set_secrets.sh ${allParams}" if [ $? -eq 255 ] then exit $? @@ -567,19 +590,29 @@ ok_to_proceed=false new_deployment=false #Plugins -if [ ! -d /opt/terraform/.terraform.d/plugin-cache ] -then +isInCloudShellCheck=$(checkIfCloudShell) + +if checkIfCloudShell; then + mkdir -p "${HOME}/.terraform.d/plugin-cache" + export TF_PLUGIN_CACHE_DIR="${HOME}/.terraform.d/plugin-cache" +else + if [ ! -d /opt/terraform/.terraform.d/plugin-cache ]; then mkdir -p /opt/terraform/.terraform.d/plugin-cache + sudo chown -R "$USER" /opt/terraform + fi + export TF_PLUGIN_CACHE_DIR=/opt/terraform/.terraform.d/plugin-cache fi -sudo chown -R $USER:$USER /opt/terraform -export TF_PLUGIN_CACHE_DIR=/opt/terraform/.terraform.d/plugin-cache root_dirname=$(pwd) -echo " subscription_id=${STATE_SUBSCRIPTION}" -echo " resource_group_name=${REMOTE_STATE_RG}" -echo "storage_account_name=${REMOTE_STATE_SA}" - +echo "" +echo "Terraform details" +echo "-------------------------------------------------------------------------" +echo "Subscription: ${STATE_SUBSCRIPTION}" +echo "Storage Account: ${REMOTE_STATE_SA}" +echo "Resource Group: ${REMOTE_STATE_RG}" +echo "State file: ${key}.terraform.tfstate" +echo "Target subscription: ${ARM_SUBSCRIPTION_ID}" if [ ! -d ./.terraform/ ]; then @@ -751,7 +784,7 @@ else fi return_value=$? -echo "Terraform Plan return code: " $return_value +echo "Terraform Plan return code: $return_value" if [ 1 == $return_value ] then echo "#########################################################################################" @@ -1063,10 +1096,12 @@ echo "" if [ -n "${spn_secret}" ] then az logout - echo "Login as SPN" az login --service-principal --username "${client_id}" --password="${spn_secret}" --tenant "${tenant_id}" --output none fi +full_script_path="$(realpath "${BASH_SOURCE[0]}")" +script_directory="$(dirname "${full_script_path}")" + rg_name=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw created_resource_group_name | tr -d \") az deployment group create --resource-group "${rg_name}" --name "SAP-WORKLOAD-ZONE_${rg_name}" --subscription "${subscription}" --template-file "${script_directory}/templates/empty-deployment.json" --output none @@ -1086,37 +1121,47 @@ Date : "${now}" EOF -if [ -f "${workload_config_information}".err ]; then - cat "${workload_config_information}".err -fi - +printf -v kvname '%-40s' "${workloadkeyvault}" echo "" echo "#########################################################################################" echo "# #" -echo -e "# $cyan Adding the subnets to storage account firewalls $resetformatting #" +echo -e "# $cyan Please save these values: $resetformatting #" +echo "# - Key Vault: ${kvname} #" echo "# #" echo "#########################################################################################" -echo "" -subnet_id=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw app_subnet_id | tr -d \") -useSAS=$(az storage account show --name "${REMOTE_STATE_SA}" --query allowSharedKeyAccess --subscription "${STATE_SUBSCRIPTION}" --out tsv) -echo "useSAS = $useSAS" - -if [ -n "${subnet_id}" ]; then - echo "Adding the app subnet" - az storage account network-rule add --resource-group "${REMOTE_STATE_RG}" --account-name "${REMOTE_STATE_SA}" --subscription "${STATE_SUBSCRIPTION}" --subnet $subnet_id --output none - if [ -n "$SAPBITS" ] ; then - az storage account network-rule add --resource-group "${REMOTE_STATE_RG}" --account-name $SAPBITS --subscription "${STATE_SUBSCRIPTION}" --subnet $subnet_id --output none - fi +if [ -f "${workload_config_information}".err ]; then + cat "${workload_config_information}".err fi -subnet_id=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw db_subnet_id | tr -d \") +# echo "" +# echo "#########################################################################################" +# echo "# #" +# echo -e "# $cyan Adding the subnets to storage account firewalls $resetformatting #" +# echo "# #" +# echo "#########################################################################################" +# echo "" + +# subnet_id=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw app_subnet_id | tr -d \") + +# useSAS=$(az storage account show --name "${REMOTE_STATE_SA}" --query allowSharedKeyAccess --subscription "${STATE_SUBSCRIPTION}" --out tsv) +# echo "Shared Access Key access: $useSAS" + +# if [ -n "${subnet_id}" ]; then +# echo "Adding the application subnet to the storage account hosting the Terraform State files" +# az storage account network-rule add --resource-group "${REMOTE_STATE_RG}" --account-name "${REMOTE_STATE_SA}" --subscription "${STATE_SUBSCRIPTION}" --subnet $subnet_id --output none +# if [ -n "$SAPBITS" ] ; then +# az storage account network-rule add --resource-group "${REMOTE_STATE_RG}" --account-name $SAPBITS --subscription "${STATE_SUBSCRIPTION}" --subnet $subnet_id --output none +# fi +# fi + +# subnet_id=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw db_subnet_id | tr -d \") -if [ -n "${subnet_id}" ]; then - echo "Adding the db subnet" - az storage account network-rule add --resource-group "${REMOTE_STATE_RG}" --account-name "${REMOTE_STATE_SA}" --subscription "${STATE_SUBSCRIPTION}" --subnet $subnet_id --output none -fi +# if [ -n "${subnet_id}" ]; then +# echo "Adding the db subnet" +# az storage account network-rule add --resource-group "${REMOTE_STATE_RG}" --account-name "${REMOTE_STATE_SA}" --subscription "${STATE_SUBSCRIPTION}" --subnet $subnet_id --output none +# fi unset TF_DATA_DIR diff --git a/deploy/scripts/installer.sh b/deploy/scripts/installer.sh index 95be504f6f..1c02bb90bf 100755 --- a/deploy/scripts/installer.sh +++ b/deploy/scripts/installer.sh @@ -8,6 +8,7 @@ set -o pipefail boldreduscore="\e[1;4;31m" boldred="\e[1;31m" cyan="\e[1;36m" +green="\e[1;32m" resetformatting="\e[0m" #External helper functions @@ -27,31 +28,64 @@ INPUT_ARGUMENTS=$(getopt -n installer -o p:t:o:d:l:s:ahif --longoptions type:,pa VALID_ARGUMENTS=$? if [ "$VALID_ARGUMENTS" != "0" ]; then - showhelp + showhelp fi called_from_ado=0 eval set -- "$INPUT_ARGUMENTS" -while : -do - case "$1" in - -t | --type) deployment_system="$2" ; shift 2 ;; - -p | --parameterfile) parameterfile="$2" ; shift 2 ;; - -o | --storageaccountname) REMOTE_STATE_SA="$2" ; shift 2 ;; - -s | --state_subscription) STATE_SUBSCRIPTION="$2" ; shift 2 ;; - -d | --deployer_tfstate_key) deployer_tfstate_key="$2" ; shift 2 ;; - -l | --landscape_tfstate_key) landscape_tfstate_key="$2" ; shift 2 ;; - -a | --ado) called_from_ado=1 ; shift ;; - -f | --force) force=1 ; shift ;; - -i | --auto-approve) approve="--auto-approve" ; shift ;; - -h | --help) showhelp - exit 3 ; shift ;; - --) shift; break ;; - esac +while :; do + case "$1" in + -t | --type) + deployment_system="$2" + shift 2 + ;; + -p | --parameterfile) + parameterfile="$2" + shift 2 + ;; + -o | --storageaccountname) + REMOTE_STATE_SA="$2" + shift 2 + ;; + -s | --state_subscription) + STATE_SUBSCRIPTION="$2" + shift 2 + ;; + -d | --deployer_tfstate_key) + deployer_tfstate_key="$2" + shift 2 + ;; + -l | --landscape_tfstate_key) + landscape_tfstate_key="$2" + shift 2 + ;; + -a | --ado) + called_from_ado=1 + shift + ;; + -f | --force) + force=1 + shift + ;; + -i | --auto-approve) + approve="--auto-approve" + shift + ;; + -h | --help) + showhelp + exit 3 + shift + ;; + --) + shift + break + ;; + esac done - -echo "Parameter file: $parameterfile" -echo "Current directory: $(pwd)" +echo "Parameter file: $parameterfile" +echo "Current directory: $(pwd)" +echo "Terraform state subscription_id: ${STATE_SUBSCRIPTION}" +echo "Terraform state storage account name:${REMOTE_STATE_SA}" tfstate_resource_id="" tfstate_parameter="" @@ -64,88 +98,85 @@ parameterfile_name=$(basename "${parameterfile}") param_dirname=$(dirname "${parameterfile}") if [ "${param_dirname}" != '.' ]; then - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldred Please run this command from the folder containing the parameter file $resetformatting #" - echo "# #" - echo "#########################################################################################" - exit 3 + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldred Please run this command from the folder containing the parameter file $resetformatting #" + echo "# #" + echo "#########################################################################################" + exit 3 fi -if [ ! -f "${parameterfile}" ] -then - printf -v val %-35.35s "$parameterfile" - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldred Parameter file does not exist: ${val} $resetformatting #" - echo "# #" - echo "#########################################################################################" +if [ ! -f "${parameterfile}" ]; then + printf -v val %-35.35s "$parameterfile" + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldred Parameter file does not exist: ${val} $resetformatting #" + echo "# #" + echo "#########################################################################################" - echo "Parameter file does not exist: ${val}" > "${system_config_information}".err + echo "Parameter file does not exist: ${val}" >"${system_config_information}".err - exit 2 #No such file or directory + exit 2 #No such file or directory fi -if [ -z "${deployment_system}" ] -then - printf -v val %-40.40s "$deployment_system" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldred Incorrect system deployment type specified: ${val}$resetformatting#" - echo "# #" - echo "# Valid options are: #" - echo "# sap_deployer #" - echo "# sap_library #" - echo "# sap_landscape #" - echo "# sap_system #" - echo "# #" - echo "#########################################################################################" - echo "" - exit 64 #script usage wrong +if [ -z "${deployment_system}" ]; then + printf -v val %-40.40s "$deployment_system" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldred Incorrect system deployment type specified: ${val}$resetformatting#" + echo "# #" + echo "# Valid options are: #" + echo "# sap_deployer #" + echo "# sap_library #" + echo "# sap_landscape #" + echo "# sap_system #" + echo "# #" + echo "#########################################################################################" + echo "" + exit 64 #script usage wrong fi # Check that the exports ARM_SUBSCRIPTION_ID and SAP_AUTOMATION_REPO_PATH are defined validate_exports return_code=$? if [ 0 != $return_code ]; then - echo "Missing exports" > "${system_config_information}".err - exit $return_code + echo "Missing exports" >"${system_config_information}".err + exit $return_code fi # Check that Terraform and Azure CLI is installed validate_dependencies return_code=$? if [ 0 != $return_code ]; then - echo "Missing software" > "${system_config_information}".err - exit $return_code + echo "Missing software" >"${system_config_information}".err + exit $return_code fi # Check that parameter files have environment and location defined validate_key_parameters "$parameterfile_name" return_code=$? if [ 0 != $return_code ]; then - echo "Missing parameters in $parameterfile_name" > "${system_config_information}".err - exit $return_code + echo "Missing parameters in $parameterfile_name" >"${system_config_information}".err + exit $return_code fi region=$(echo "${region}" | tr "[:upper:]" "[:lower:]") -if valid_region_name "${region}" ; then - # Convert the region to the correct code - get_region_code ${region} +if valid_region_name "${region}"; then + # Convert the region to the correct code + get_region_code ${region} else - echo "Invalid region: $region" - exit 2 + echo "Invalid region: $region" + exit 2 fi key=$(echo "${parameterfile_name}" | cut -d. -f1) network_logical_name="" -if [ "${deployment_system}" == sap_system ] -then - load_config_vars "$parameterfile_name" "network_logical_name" - network_logical_name=$(echo "${network_logical_name}" | tr "[:lower:]" "[:upper:]") +if [ "${deployment_system}" == sap_system ]; then + load_config_vars "$parameterfile_name" "network_logical_name" + network_logical_name=$(echo "${network_logical_name}" | tr "[:lower:]" "[:upper:]") fi #Persisting the parameters across executions @@ -154,34 +185,39 @@ automation_config_directory=$CONFIG_REPO_PATH/.sap_deployment_automation/ generic_config_information="${automation_config_directory}"config system_config_information="${automation_config_directory}""${environment}""${region_code}""${network_logical_name}" -echo "Configuration file: $system_config_information" -echo "Deployment region: $region" -echo "Deployment region code: $region_code" -if [ 1 == $called_from_ado ] ; then - this_ip=$(curl -s ipinfo.io/ip) >/dev/null 2>&1 - export TF_VAR_Agent_IP=$this_ip - echo "Agent IP: $this_ip" -fi +echo "Configuration file: $system_config_information" +echo "Deployment region: $region" +echo "Deployment region code: $region_code" +if [ 1 == $called_from_ado ]; then + this_ip=$(curl -s ipinfo.io/ip) >/dev/null 2>&1 + export TF_VAR_Agent_IP=$this_ip + echo "Agent IP: $this_ip" -#Plugins -if [ ! -d /opt/terraform/.terraform.d/plugin-cache ] -then - mkdir -p /opt/terraform/.terraform.d/plugin-cache fi -sudo chown -R $USER:$USER /opt/terraform -export TF_PLUGIN_CACHE_DIR=/opt/terraform/.terraform.d/plugin-cache +#Plugins +isInCloudShellCheck=$(checkIfCloudShell) +if checkIfCloudShell; then + mkdir -p "${HOME}/.terraform.d/plugin-cache" + export TF_PLUGIN_CACHE_DIR="${HOME}/.terraform.d/plugin-cache" +else + if [ ! -d /opt/terraform/.terraform.d/plugin-cache ]; then + mkdir -p /opt/terraform/.terraform.d/plugin-cache + sudo chown -R "$USER" /opt/terraform + fi + export TF_PLUGIN_CACHE_DIR=/opt/terraform/.terraform.d/plugin-cache +fi parallelism=10 #Provide a way to limit the number of parallell tasks for Terraform if [[ -n "${TF_PARALLELLISM}" ]]; then - parallelism=$TF_PARALLELLISM + parallelism=$TF_PARALLELLISM fi -echo "Parallelism count $parallelism" +echo "Parallelism count: $parallelism" param_dirname=$(pwd) @@ -192,138 +228,157 @@ var_file="${param_dirname}"/"${parameterfile}" extra_vars="" if [ -f terraform.tfvars ]; then - extra_vars=" -var-file=${param_dirname}/terraform.tfvars " + extra_vars=" -var-file=${param_dirname}/terraform.tfvars " fi -if [ "${deployment_system}" == sap_deployer ] -then - deployer_tfstate_key=${key}.terraform.tfstate - STATE_SUBSCRIPTION=$ARM_SUBSCRIPTION_ID +if [ "${deployment_system}" == sap_deployer ]; then + deployer_tfstate_key=${key}.terraform.tfstate + ARM_SUBSCRIPTION_ID=$STATE_SUBSCRIPTION + export ARM_SUBSCRIPTION_ID fi -if [[ -z $STATE_SUBSCRIPTION ]]; -then +if [[ -z $STATE_SUBSCRIPTION ]]; then STATE_SUBSCRIPTION=$ARM_SUBSCRIPTION_ID fi -if [[ -z $REMOTE_STATE_SA ]]; -then - echo "Loading the State file information" - load_config_vars "${system_config_information}" "REMOTE_STATE_SA" - load_config_vars "${system_config_information}" "REMOTE_STATE_RG" - load_config_vars "${system_config_information}" "tfstate_resource_id" - load_config_vars "${system_config_information}" "STATE_SUBSCRIPTION" -else - save_config_vars "${system_config_information}" REMOTE_STATE_SA +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 -echo "Terraform state file storage:" "${REMOTE_STATE_SA}" -echo "Terraform state subscription:" "${STATE_SUBSCRIPTION}" +if [[ -z $REMOTE_STATE_SA ]]; then + load_config_vars "${system_config_information}" "REMOTE_STATE_SA" + load_config_vars "${system_config_information}" "REMOTE_STATE_RG" + load_config_vars "${system_config_information}" "tfstate_resource_id" + load_config_vars "${system_config_information}" "STATE_SUBSCRIPTION" + load_config_vars "${system_config_information}" "ARM_SUBSCRIPTION_ID" +else + save_config_vars "${system_config_information}" REMOTE_STATE_SA +fi deployer_tfstate_key_parameter='' -if [[ -z $deployer_tfstate_key ]]; -then - load_config_vars "${system_config_information}" "deployer_tfstate_key" +if [[ -z $deployer_tfstate_key ]]; then + load_config_vars "${system_config_information}" "deployer_tfstate_key" else - echo "Deployer state file name:" "${deployer_tfstate_key}" - save_config_vars "${system_config_information}" deployer_tfstate_key + echo "Deployer state file name: ${deployer_tfstate_key}" + echo "Target subscription: $ARM_SUBSCRIPTION_ID" fi -if [ "${deployment_system}" != sap_deployer ] -then - if [ -z ${deployer_tfstate_key} ]; then - if [ 1 != $called_from_ado ]; then - read -p "Deployer terraform statefile name :" landscape_tfstate_key - deployer_tfstate_key_parameter=" -var deployer_tfstate_key=${deployer_tfstate_key}" - save_config_var "deployer_tfstate_key" "${system_config_information}" - else - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldreduscore!Deployer state file name is missing!$resetformatting #" - echo "# #" - echo "#########################################################################################" - echo "" - - echo "Deployer terraform statefile name is missing" > "${system_config_information}".err - unset TF_DATA_DIR - exit 2 - fi +if [ "${deployment_system}" != sap_deployer ]; then + if [ -z ${deployer_tfstate_key} ]; then + if [ 1 != $called_from_ado ]; then + read -p "Deployer terraform statefile name :" landscape_tfstate_key + deployer_tfstate_key_parameter=" -var deployer_tfstate_key=${deployer_tfstate_key}" + save_config_var "deployer_tfstate_key" "${system_config_information}" else - deployer_tfstate_key_parameter=" -var deployer_tfstate_key=${deployer_tfstate_key}" + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldreduscore!Deployer state file name is missing!$resetformatting #" + echo "# #" + echo "#########################################################################################" + echo "" + + echo "Deployer terraform statefile name is missing" >"${system_config_information}".err + unset TF_DATA_DIR + exit 2 fi + else + deployer_tfstate_key_parameter=" -var deployer_tfstate_key=${deployer_tfstate_key}" + echo "Deployer state file name: ${deployer_tfstate_key}" + fi else load_config_vars "${system_config_information}" "keyvault" export TF_VAR_deployer_kv_user_arm_id=$(az resource list --name "${keyvault}" --subscription ${STATE_SUBSCRIPTION} --resource-type Microsoft.KeyVault/vaults --query "[].id | [0]" -o tsv) - echo "Deployer Keyvault: $TF_VAR_deployer_kv_user_arm_id" + echo "Deployer Keyvault ID: $TF_VAR_deployer_kv_user_arm_id" + deployer_parameter=" -var subscription_id=${STATE_SUBSCRIPTION} " + export ARM_SUBSCRIPTION_ID=$STATE_SUBSCRIPTION fi -useSAS=$(az storage account show --name "${REMOTE_STATE_SA}" --query allowSharedKeyAccess --subscription "${STATE_SUBSCRIPTION}" --out tsv) +useSAS=$(az storage account show --name "${REMOTE_STATE_SA}" --query allowSharedKeyAccess --subscription ${STATE_SUBSCRIPTION} --out tsv) -if [ "$useSAS" = "true" ] ; then - echo "Authenticate storage using SAS" +if [ "$useSAS" = "true" ]; then + echo "Storage Account Authentication: Key" export ARM_USE_AZUREAD=false else - echo "Authenticate storage using Entra ID" + echo "Storage Account Authentication: Entra ID" export ARM_USE_AZUREAD=true fi - landscape_tfstate_key_parameter='' -if [[ -z $landscape_tfstate_key ]]; -then - load_config_vars "${system_config_information}" "landscape_tfstate_key" +if [[ -z $landscape_tfstate_key ]]; then + load_config_vars "${system_config_information}" "landscape_tfstate_key" else - echo "Workload zone file name:" "${landscape_tfstate_key}" - save_config_vars "${system_config_information}" landscape_tfstate_key + echo "Workload zone state file: ${landscape_tfstate_key}" + save_config_vars "${system_config_information}" landscape_tfstate_key fi -if [ "${deployment_system}" == sap_system ] -then - if [ -z ${landscape_tfstate_key} ]; then - if [ 1 != $called_from_ado ]; then - read -p "Workload terraform statefile name :" landscape_tfstate_key - landscape_tfstate_key_parameter=" -var landscape_tfstate_key=${landscape_tfstate_key}" - save_config_var "landscape_tfstate_key" "${system_config_information}" - else - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldred Workload zone terraform statefile name is missing $resetformatting #" - echo "# #" - echo "#########################################################################################" - echo "" - - echo "Workload zone terraform statefile name is missing" > "${system_config_information}".err - - unset TF_DATA_DIR - exit 2 - fi +if [ "${deployment_system}" == sap_system ]; then + if [ -z ${landscape_tfstate_key} ]; then + if [ 1 != $called_from_ado ]; then + read -p "Workload terraform statefile name :" landscape_tfstate_key + landscape_tfstate_key_parameter=" -var landscape_tfstate_key=${landscape_tfstate_key}" + save_config_var "landscape_tfstate_key" "${system_config_information}" else - landscape_tfstate_key_parameter=" -var landscape_tfstate_key=${landscape_tfstate_key}" + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldred Workload zone terraform statefile name is missing $resetformatting #" + echo "# #" + echo "#########################################################################################" + echo "" + + echo "Workload zone terraform statefile name is missing" >"${system_config_information}".err + + unset TF_DATA_DIR + exit 2 fi + else + landscape_tfstate_key_parameter=" -var landscape_tfstate_key=${landscape_tfstate_key}" + fi fi -if [[ -z $STATE_SUBSCRIPTION ]]; -then - load_config_vars "${system_config_information}" "STATE_SUBSCRIPTION" +if [[ -z $STATE_SUBSCRIPTION ]]; then + load_config_vars "${system_config_information}" "STATE_SUBSCRIPTION" else - echo "Saving the state subscription" - if is_valid_guid "$STATE_SUBSCRIPTION" ; then - save_config_var "STATE_SUBSCRIPTION" "${system_config_information}" - else - printf -v val %-40.40s "$STATE_SUBSCRIPTION" - echo "#########################################################################################" - echo "# #" - echo -e "# The provided state_subscription is not valid:$boldred ${val}$resetformatting#" - echo "# #" - echo "#########################################################################################" - echo "The provided subscription for Terraform remote state is not valid:${val}" > "${system_config_information}".err - exit 65 - fi + + if is_valid_guid "$STATE_SUBSCRIPTION"; then + save_config_var "STATE_SUBSCRIPTION" "${system_config_information}" + else + printf -v val %-40.40s "$STATE_SUBSCRIPTION" + echo "#########################################################################################" + echo "# #" + echo -e "# The provided state_subscription is not valid:$boldred ${val}$resetformatting#" + echo "# #" + echo "#########################################################################################" + echo "The provided subscription for Terraform remote state is not valid:${val}" >"${system_config_information}".err + exit 65 + fi fi @@ -333,47 +388,19 @@ account_set=0 set_executing_user_environment_variables "none" if [[ -n ${subscription} ]]; then - if is_valid_guid "${subscription}" ; then - echo "Valid subscription format" - else - printf -v val %-40.40s "$subscription" - echo "#########################################################################################" - echo "# #" - echo -e "# The provided subscription is not valid:$boldred ${val} $resetformatting# " - echo "# #" - echo "#########################################################################################" - echo "The provided subscription is not valid:${val}" > "${system_config_information}".err - exit 65 - fi - export ARM_SUBSCRIPTION_ID="${subscription}" -fi - -if [[ -n $STATE_SUBSCRIPTION ]]; -then - echo "" + if is_valid_guid "${subscription}"; then + echo "Valid subscription format" + else + printf -v val %-40.40s "$subscription" echo "#########################################################################################" echo "# #" - echo -e "# $cyan Changing the subscription to: $STATE_SUBSCRIPTION $resetformatting #" + echo -e "# The provided subscription is not valid:$boldred ${val} $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 + echo "The provided subscription is not valid:${val}" >"${system_config_information}".err + exit 65 + fi + export ARM_SUBSCRIPTION_ID="${subscription}" fi load_config_vars "${system_config_information}" "STATE_SUBSCRIPTION" @@ -381,36 +408,34 @@ load_config_vars "${system_config_information}" "REMOTE_STATE_RG" load_config_vars "${system_config_information}" "tfstate_resource_id" if [[ -z ${REMOTE_STATE_SA} ]]; then - if [ 1 != $called_from_ado ]; then - read -p "Terraform state storage account name:" REMOTE_STATE_SA + if [ 1 != $called_from_ado ]; then + read -p "Terraform state storage account name:" REMOTE_STATE_SA - get_and_store_sa_details "${REMOTE_STATE_SA}" "${system_config_information}" - load_config_vars "${system_config_information}" "STATE_SUBSCRIPTION" - load_config_vars "${system_config_information}" "REMOTE_STATE_RG" - load_config_vars "${system_config_information}" "tfstate_resource_id" - fi + get_and_store_sa_details "${REMOTE_STATE_SA}" "${system_config_information}" + load_config_vars "${system_config_information}" "STATE_SUBSCRIPTION" + load_config_vars "${system_config_information}" "REMOTE_STATE_RG" + load_config_vars "${system_config_information}" "tfstate_resource_id" + fi fi -echo "Terraform state storage " "${REMOTE_STATE_SA}" - if [ -z ${REMOTE_STATE_SA} ]; then - option="REMOTE_STATE_SA" - missing - exit 1 + option="REMOTE_STATE_SA" + missing + exit 1 fi if [[ -z ${REMOTE_STATE_RG} ]]; then - get_and_store_sa_details "${REMOTE_STATE_SA}" "${system_config_information}" - load_config_vars "${system_config_information}" "STATE_SUBSCRIPTION" - load_config_vars "${system_config_information}" "REMOTE_STATE_RG" - load_config_vars "${system_config_information}" "tfstate_resource_id" + get_and_store_sa_details "${REMOTE_STATE_SA}" "${system_config_information}" + load_config_vars "${system_config_information}" "STATE_SUBSCRIPTION" + load_config_vars "${system_config_information}" "REMOTE_STATE_RG" + load_config_vars "${system_config_information}" "tfstate_resource_id" fi if [[ -z ${tfstate_resource_id} ]]; then - get_and_store_sa_details "${REMOTE_STATE_SA}" "${system_config_information}" - load_config_vars "${system_config_information}" "STATE_SUBSCRIPTION" - load_config_vars "${system_config_information}" "REMOTE_STATE_RG" - load_config_vars "${system_config_information}" "tfstate_resource_id" + get_and_store_sa_details "${REMOTE_STATE_SA}" "${system_config_information}" + load_config_vars "${system_config_information}" "STATE_SUBSCRIPTION" + load_config_vars "${system_config_information}" "REMOTE_STATE_RG" + load_config_vars "${system_config_information}" "tfstate_resource_id" fi @@ -420,30 +445,25 @@ terraform_module_directory="$SAP_AUTOMATION_REPO_PATH"/deploy/terraform/run/"${d export TF_DATA_DIR="${param_dirname}/.terraform" cd ${param_dirname} -if [ ! -d "${terraform_module_directory}" ] -then - printf -v val %-40.40s "$deployment_system" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldred Incorrect system deployment type specified: ${val}$resetformatting#" - echo "# #" - echo "# Valid options are: #" - echo "# sap_deployer #" - echo "# sap_library #" - echo "# sap_landscape #" - echo "# sap_system #" - echo "# #" - echo "#########################################################################################" - echo "" - exit 1 +if [ ! -d "${terraform_module_directory}" ]; then + printf -v val %-40.40s "$deployment_system" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldred Incorrect system deployment type specified: ${val}$resetformatting#" + echo "# #" + echo "# Valid options are: #" + echo "# sap_deployer #" + echo "# sap_library #" + echo "# sap_landscape #" + echo "# sap_system #" + echo "# #" + echo "#########################################################################################" + echo "" + exit 1 fi ok_to_proceed=false -echo "Terraform state subscription_id = ${STATE_SUBSCRIPTION}" -echo "Terraform state resource group name = ${REMOTE_STATE_RG}" -echo "Terraform state storage account name = ${REMOTE_STATE_SA}" - # This is used to tell Terraform if this is a new deployment or an update deployment_parameter="" # This is used to tell Terraform the version information from the state file @@ -452,164 +472,170 @@ version_parameter="" export TF_DATA_DIR="${param_dirname}/.terraform" terraform --version +echo "" +echo "Terraform details" +echo "-------------------------------------------------------------------------" +echo "Subscription: ${STATE_SUBSCRIPTION}" +echo "Storage Account: ${REMOTE_STATE_SA}" +echo "Resource Group: ${REMOTE_STATE_RG}" +echo "State file: ${key}.terraform.tfstate" +echo "Target subscription: ${ARM_SUBSCRIPTION_ID}" +echo "" check_output=0 if [ -f terraform.tfstate ]; then + if [ -f ./.terraform/terraform.tfstate ]; then + if grep "\"type\": \"azurerm\"" .terraform/terraform.tfstate; then + echo "" + else - if [ "${deployment_system}" == sap_deployer ] - then - echo "" - echo -e "$cyan Reinitializing deployer in case of on a new deployer $resetformatting" - - terraform_module_directory="${SAP_AUTOMATION_REPO_PATH}"/deploy/terraform/bootstrap/"${deployment_system}"/ - terraform -chdir="${terraform_module_directory}" init -backend-config "path=${param_dirname}/terraform.tfstate" -reconfigure - echo "" - key_vault_id=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw deployer_kv_user_arm_id | tr -d \") + if [ "${deployment_system}" == sap_deployer ]; then - if [ -n "${key_vault_id}" ] - then - export TF_VAR_deployer_kv_user_arm_id="${key_vault_id}" ; echo $TF_VAR_deployer_kv_user_arm_id - fi + echo "" + echo -e "$cyan Reinitializing deployer in case of on a new deployer $resetformatting" + terraform_module_directory="${SAP_AUTOMATION_REPO_PATH}"/deploy/terraform/bootstrap/"${deployment_system}"/ + terraform -chdir="${terraform_module_directory}" init -backend-config "path=${param_dirname}/terraform.tfstate" -reconfigure + echo "" + key_vault_id=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw deployer_kv_user_arm_id | tr -d \") - fi + if [ -n "${key_vault_id}" ]; then + export TF_VAR_deployer_kv_user_arm_id="${key_vault_id}" + echo $TF_VAR_deployer_kv_user_arm_id + fi + fi - if [ "${deployment_system}" == sap_library ] - then - echo "Reinitializing library in case of on a new deployer" - terraform_module_directory="${SAP_AUTOMATION_REPO_PATH}"/deploy/terraform/bootstrap/"${deployment_system}"/ + if [ "${deployment_system}" == sap_library ]; then + echo "Reinitializing library in case of on a new deployer" + terraform_module_directory="${SAP_AUTOMATION_REPO_PATH}"/deploy/terraform/bootstrap/"${deployment_system}"/ - terraform -chdir="${terraform_module_directory}" init -backend-config "path=${param_dirname}/terraform.tfstate" -reconfigure + terraform -chdir="${terraform_module_directory}" init -backend-config "path=${param_dirname}/terraform.tfstate" -reconfigure + fi + fi fi - fi - terraform_module_directory="${SAP_AUTOMATION_REPO_PATH}"/deploy/terraform/run/"${deployment_system}"/ export TF_DATA_DIR="${param_dirname}/.terraform" -if [ ! -d ./.terraform/ ]; -then - echo "New deployment" - deployment_parameter=" -var deployment=new " +if [ ! -d ./.terraform/ ]; then + echo "New deployment" + deployment_parameter=" -var deployment=new " - terraform -chdir="${terraform_module_directory}" init -upgrade=true \ - --backend-config "subscription_id=${STATE_SUBSCRIPTION}" \ - --backend-config "resource_group_name=${REMOTE_STATE_RG}" \ - --backend-config "storage_account_name=${REMOTE_STATE_SA}" \ - --backend-config "container_name=tfstate" \ + terraform -chdir="${terraform_module_directory}" init -upgrade=true \ + --backend-config "subscription_id=${STATE_SUBSCRIPTION}" \ + --backend-config "resource_group_name=${REMOTE_STATE_RG}" \ + --backend-config "storage_account_name=${REMOTE_STATE_SA}" \ + --backend-config "container_name=tfstate" \ --backend-config "key=${key}.terraform.tfstate" - return_value=$? + return_value=$? else - temp=$(grep "\"type\": \"local\"" .terraform/terraform.tfstate) - if [ -n "${temp}" ] - then - terraform -chdir="${terraform_module_directory}" init -upgrade=true -force-copy \ - --backend-config "subscription_id=${STATE_SUBSCRIPTION}" \ - --backend-config "resource_group_name=${REMOTE_STATE_RG}" \ - --backend-config "storage_account_name=${REMOTE_STATE_SA}" \ - --backend-config "container_name=tfstate" \ - --backend-config "key=${key}.terraform.tfstate" - return_value=$? + temp=$(grep "\"type\": \"local\"" .terraform/terraform.tfstate) + if [ -n "${temp}" ]; then + terraform -chdir="${terraform_module_directory}" init -upgrade=true -force-copy \ + --backend-config "subscription_id=${STATE_SUBSCRIPTION}" \ + --backend-config "resource_group_name=${REMOTE_STATE_RG}" \ + --backend-config "storage_account_name=${REMOTE_STATE_SA}" \ + --backend-config "container_name=tfstate" \ + --backend-config "key=${key}.terraform.tfstate" + return_value=$? - else - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $cyan The system has already been deployed and the statefile is in Azure $resetformatting #" - echo "# #" - echo "#########################################################################################" - echo "" + else + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $cyan The system has already been deployed and the statefile is in Azure $resetformatting #" + echo "# #" + echo "#########################################################################################" + echo "" - check_output=1 - terraform -chdir="${terraform_module_directory}" init -upgrade=true -reconfigure \ - --backend-config "subscription_id=${STATE_SUBSCRIPTION}" \ - --backend-config "resource_group_name=${REMOTE_STATE_RG}" \ - --backend-config "storage_account_name=${REMOTE_STATE_SA}" \ - --backend-config "container_name=tfstate" \ - --backend-config "key=${key}.terraform.tfstate" - return_value=$? + check_output=1 + terraform -chdir="${terraform_module_directory}" init -upgrade=true -reconfigure \ + --backend-config "subscription_id=${STATE_SUBSCRIPTION}" \ + --backend-config "resource_group_name=${REMOTE_STATE_RG}" \ + --backend-config "storage_account_name=${REMOTE_STATE_SA}" \ + --backend-config "container_name=tfstate" \ + --backend-config "key=${key}.terraform.tfstate" + return_value=$? - fi + fi +fi +if [ 0 != $return_value ]; then + echo "#########################################################################################" + echo "# #" + echo -e "# $boldreduscore!!! Error when Initializing !!!$resetformatting #" + echo "# #" + echo "#########################################################################################" + echo "" + echo "Error when initializing Terraform" >"${system_config_information}".err + exit $return_value fi -if [ 0 != $return_value ] -then +if [ 1 == $check_output ]; then + outputs=$(terraform -chdir="${terraform_module_directory}" output) + if echo "${outputs}" | grep "No outputs"; then + ok_to_proceed=true echo "#########################################################################################" echo "# #" - echo -e "# $boldreduscore!!! Error when Initializing !!!$resetformatting #" + echo -e "# $cyan New deployment $resetformatting #" echo "# #" echo "#########################################################################################" + + deployment_parameter=" -var deployment=new " + + else echo "" - echo "Error when initializing Terraform" > "${system_config_information}".err - exit $return_value -fi -if [ 1 == $check_output ] -then - outputs=$(terraform -chdir="${terraform_module_directory}" output ) - if echo "${outputs}" | grep "No outputs"; then - ok_to_proceed=true - echo "#########################################################################################" - echo "# #" - echo -e "# $cyan New deployment $resetformatting #" - echo "# #" - echo "#########################################################################################" + echo "#########################################################################################" + echo "# #" + echo -e "# $cyan Existing deployment was detected$resetformatting #" + echo "# #" + echo "#########################################################################################" + echo "" + # allParams=$(printf " -var-file=%s %s %s %s %s %s %s" "${var_file}" "${extra_vars}" "${tfstate_parameter}" "${landscape_tfstate_key_parameter}" "${deployer_tfstate_key_parameter}" "${deployment_parameter}" "${version_parameter}" ) + # terraform -chdir="${terraform_module_directory}" refresh $allParams + + deployment_parameter=" " - deployment_parameter=" -var deployment=new " + deployed_using_version=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw automation_version | tr -d \") + + if [ -z "${deployed_using_version}" ]; then + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldred The environment was deployed using an older version of the Terrafrom templates$resetformatting #" + echo "# #" + echo "# !!! Risk for Data loss !!! #" + echo "# #" + echo "# Please inspect the output of Terraform plan carefully before proceeding #" + echo "# #" + echo "#########################################################################################" + if [ 1 == $called_from_ado ]; then + unset TF_DATA_DIR + exit 1 + fi + read -p "Do you want to continue Y/N?" ans + answer=${ans^^} + if [ $answer == 'Y' ]; then + ok_to_proceed=true + else + unset TF_DATA_DIR + exit 1 + fi else - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $cyan Existing deployment was detected$resetformatting #" - echo "# #" - echo "#########################################################################################" - echo "" - # allParams=$(printf " -var-file=%s %s %s %s %s %s %s" "${var_file}" "${extra_vars}" "${tfstate_parameter}" "${landscape_tfstate_key_parameter}" "${deployer_tfstate_key_parameter}" "${deployment_parameter}" "${version_parameter}" ) - # terraform -chdir="${terraform_module_directory}" refresh $allParams - - deployment_parameter=" " - - deployed_using_version=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw automation_version | tr -d \") - - if [ -z "${deployed_using_version}" ]; then - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldred The environment was deployed using an older version of the Terrafrom templates$resetformatting #" - echo "# #" - echo "# !!! Risk for Data loss !!! #" - echo "# #" - echo "# Please inspect the output of Terraform plan carefully before proceeding #" - echo "# #" - echo "#########################################################################################" - - if [ 1 == $called_from_ado ] ; then - unset TF_DATA_DIR - exit 1 - fi - read -p "Do you want to continue Y/N?" ans - answer=${ans^^} - if [ $answer == 'Y' ]; then - ok_to_proceed=true - else - unset TF_DATA_DIR - exit 1 - fi - else - version_parameter=" -var terraform_template_version=${deployed_using_version} " - - printf -v val %-.20s "$deployed_using_version" - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $cyan Deployed using the Terraform templates version: $val $resetformatting #" - echo "# #" - echo "#########################################################################################" - echo "" - #Add version logic here - fi + version_parameter=" -var terraform_template_version=${deployed_using_version} " + + printf -v val %-.20s "$deployed_using_version" + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $cyan Deployed using the Terraform templates version: $val $resetformatting #" + echo "# #" + echo "#########################################################################################" + echo "" + #Add version logic here fi + fi fi echo "" @@ -620,785 +646,789 @@ echo "# echo "#########################################################################################" echo "" -if [ -f plan_output.log ] -then - rm plan_output.log +if [ -f plan_output.log ]; then + rm plan_output.log fi -allParams=$(printf " -var-file=%s %s %s %s %s %s %s" "${var_file}" "${extra_vars}" "${tfstate_parameter}" "${landscape_tfstate_key_parameter}" "${deployer_tfstate_key_parameter}" "${deployment_parameter}" "${version_parameter}" ) +allParams=$(printf " -var-file=%s %s %s %s %s %s %s %s" "${var_file}" "${extra_vars}" "${tfstate_parameter}" "${landscape_tfstate_key_parameter}" "${deployer_tfstate_key_parameter}" "${deployment_parameter}" "${version_parameter}" "${deployer_parameter}") terraform -chdir="$terraform_module_directory" plan -no-color -detailed-exitcode $allParams | tee -a plan_output.log return_value=$? -echo "Terraform Plan return code: " $return_value - -if [ 1 == $return_value ] ; then - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldreduscore Errors during the plan phase $resetformatting #" - echo "# #" - echo "#########################################################################################" - echo "" - echo "Error when running Terraform plan" > "${system_config_information}".err - - unset TF_DATA_DIR - rm plan_output.log - exit $return_value +echo "Terraform Plan return code: $return_value" + +if [ 1 == $return_value ]; then + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldreduscore Errors during the plan phase $resetformatting #" + echo "# #" + echo "#########################################################################################" + echo "" + echo "Error when running Terraform plan" >"${system_config_information}".err + + unset TF_DATA_DIR + rm plan_output.log + exit $return_value fi state_path="SYSTEM" -if [ 1 != $return_value ] ; then - - if [ "${deployment_system}" == sap_deployer ] - then - state_path="DEPLOYER" - - deployer_public_ip_address=$(terraform -chdir="${terraform_module_directory}" output deployer_public_ip_address | tr -d \") - save_config_var "deployer_public_ip_address" "${system_config_information}" - - keyvault=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw deployer_kv_user_name | tr -d \") - save_config_var "keyvault" "${system_config_information}" - if [ 1 == $called_from_ado ] ; then +if [ 1 != $return_value ]; then - if [[ "${TF_VAR_use_webapp}" == "true" && $IS_PIPELINE_DEPLOYMENT = "true" ]]; then - webapp_url_base=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw webapp_url_base | tr -d \") + if [ "${deployment_system}" == sap_deployer ]; then + state_path="DEPLOYER" - if [ -n "${webapp_url_base}" ] ; then - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WEBAPP_URL_BASE.value") - if [ -z ${az_var} ]; then - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_URL_BASE --value $webapp_url_base --output none --only-show-errors - else - az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_URL_BASE --value $webapp_url_base --output none --only-show-errors - fi - fi + deployer_public_ip_address=$(terraform -chdir="${terraform_module_directory}" output deployer_public_ip_address | tr -d \") + save_config_var "deployer_public_ip_address" "${system_config_information}" - webapp_id=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw webapp_id | tr -d \") - if [ -n "${webapp_id}" ] ; then - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WEBAPP_ID.value") - if [ -z ${az_var} ]; then - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_ID --value $webapp_id --output none --only-show-errors - else - az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_ID --value $webapp_id --output none --only-show-errors - fi - fi + keyvault=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw deployer_kv_user_name | tr -d \") + save_config_var "keyvault" "${system_config_information}" + if [ 1 == $called_from_ado ]; then - msi_object_id=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw deployer_user_assigned_identity | tr -d \") + if [[ "${TF_VAR_use_webapp}" == "true" && $IS_PIPELINE_DEPLOYMENT = "true" ]]; then + webapp_url_base=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw webapp_url_base | tr -d \") - if [ -n "${msi_object_id}" ] ; then - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "MSI_ID.value") - if [ -z ${az_var} ]; then - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name MSI_ID --value $msi_object_id --output none --only-show-errors - else - az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name MSI_ID --value $msi_object_id --output none --only-show-errors - fi - fi + if [ -n "${webapp_url_base}" ]; then + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WEBAPP_URL_BASE.value") + if [ -z ${az_var} ]; then + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_URL_BASE --value $webapp_url_base --output none --only-show-errors + else + az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_URL_BASE --value $webapp_url_base --output none --only-show-errors + fi + fi + webapp_id=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw webapp_id | tr -d \") + if [ -n "${webapp_id}" ]; then + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WEBAPP_ID.value") + if [ -z ${az_var} ]; then + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_ID --value $webapp_id --output none --only-show-errors + else + az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_ID --value $webapp_id --output none --only-show-errors + fi + fi - fi + msi_object_id=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw deployer_user_assigned_identity | tr -d \") + if [ -n "${msi_object_id}" ]; then + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "MSI_ID.value") + if [ -z ${az_var} ]; then + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name MSI_ID --value $msi_object_id --output none --only-show-errors + else + az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name MSI_ID --value $msi_object_id --output none --only-show-errors + fi fi + fi fi - if [ "${deployment_system}" == sap_landscape ] + fi - then - state_path="LANDSCAPE" - if [ $landscape_tfstate_key_exists == false ] - then - save_config_vars "${system_config_information}" \ - landscape_tfstate_key - fi + if [ "${deployment_system}" == sap_landscape ]; then + state_path="LANDSCAPE" + if [ $landscape_tfstate_key_exists == false ]; then + save_config_vars "${system_config_information}" \ + landscape_tfstate_key fi + fi - if [ "${deployment_system}" == sap_library ] - then - state_path="LIBRARY" - if [ "$deployment_parameter" == " " ] - then # This is not a new deployment. Reusing variable previously declared in the shell script above. - tfstate_resource_id=$(terraform -chdir="${terraform_module_directory}" output tfstate_resource_id| tr -d \") - STATE_SUBSCRIPTION=$(echo "$tfstate_resource_id" | cut -d/ -f3 | tr -d \" | xargs) + if [ "${deployment_system}" == sap_library ]; then + state_path="LIBRARY" + if [ "$deployment_parameter" == " " ]; then # This is not a new deployment. Reusing variable previously declared in the shell script above. + tfstate_resource_id=$(terraform -chdir="${terraform_module_directory}" output tfstate_resource_id | tr -d \") + STATE_SUBSCRIPTION=$(echo "$tfstate_resource_id" | cut -d/ -f3 | tr -d \" | xargs) - az account set --sub "${STATE_SUBSCRIPTION}" + az account set --sub "${STATE_SUBSCRIPTION}" - REMOTE_STATE_SA=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw remote_state_storage_account_name| tr -d \") + REMOTE_STATE_SA=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw remote_state_storage_account_name | tr -d \") - get_and_store_sa_details "${REMOTE_STATE_SA}" "${system_config_information}" + get_and_store_sa_details "${REMOTE_STATE_SA}" "${system_config_information}" - if [ 1 == "$called_from_ado" ]; then - SAPBITS=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw sapbits_storage_account_name| tr -d \") - if [ -n "${SAPBITS}" ] ; then - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "INSTALLATION_MEDIA_ACCOUNT.value") - if [ -z ${az_var} ]; then - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name INSTALLATION_MEDIA_ACCOUNT --value $SAPBITS --output none --only-show-errors - else - az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name INSTALLATION_MEDIA_ACCOUNT --value $SAPBITS --output none --only-show-errors - fi - fi + if [ 1 == "$called_from_ado" ]; then + SAPBITS=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw sapbits_storage_account_name | tr -d \") + if [ -n "${SAPBITS}" ]; then + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "INSTALLATION_MEDIA_ACCOUNT.value") + if [ -z ${az_var} ]; then + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name INSTALLATION_MEDIA_ACCOUNT --value $SAPBITS --output none --only-show-errors + else + az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name INSTALLATION_MEDIA_ACCOUNT --value $SAPBITS --output none --only-show-errors fi - - + fi fi fi + fi - ok_to_proceed=true + ok_to_proceed=true fi -container_exists=$(az storage container exists --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --name tfvars --only-show-errors --query exists) +useSAS=$(az storage account show --name "${REMOTE_STATE_SA}" --query allowSharedKeyAccess --subscription "${STATE_SUBSCRIPTION}" --out tsv) -if [ "${container_exists}" == "false" ]; then - az storage container create --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --name tfvars --only-show-errors -fi +if [ "$useSAS" = "true" ]; then + echo "Storage Account authentication: key" + export ARM_USE_AZUREAD=false +else + echo "Storage Account authentication: Entra ID" + export ARM_USE_AZUREAD=true +fi +if [ "$useSAS" = "true" ]; then + container_exists=$(az storage container exists --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --name tfvars --only-show-errors --query exists) +else + container_exists=$(az storage container exists --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --name tfvars --only-show-errors --query exists --auth-mode login) +fi + +if [ "${container_exists}" == "false" ]; then + if [ "$useSAS" = "true" ]; then + az storage container create --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --name tfvars --only-show-errors + else + az storage container create --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --name tfvars --auth-mode login --only-show-errors + fi +fi + +if [ "$useSAS" = "true" ]; then + az storage blob upload --file "${parameterfile}" --container-name tfvars/LANDSCAPE/"${key}" --name "${parameterfile_name}" --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --no-progress --overwrite --only-show-errors --output none +else + az storage blob upload --file "${parameterfile}" --container-name tfvars/LANDSCAPE/"${key}" --name "${parameterfile_name}" --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --no-progress --overwrite --auth-mode login --only-show-errors --output none +fi fatal_errors=0 # HANA VM test=$(grep vm_dbnode plan_output.log | grep -m1 replaced) -if [ -n "${test}" ] ; then - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldreduscore!!! Risk for Data loss !!!$resetformatting #" - echo "# #" - echo "# Database server(s) will be replaced #" - echo "# #" - echo "#########################################################################################" - echo "" - echo "" - echo "##vso[task.logissue type=error]${test}" - fatal_errors=1 +if [ -n "${test}" ]; then + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldreduscore!!! Risk for Data loss !!!$resetformatting #" + echo "# #" + echo "# Database server(s) will be replaced #" + echo "# #" + echo "#########################################################################################" + echo "" + echo "" + echo "##vso[task.logissue type=error]${test}" + fatal_errors=1 fi # HANA VM disks -test=$(grep azurerm_managed_disk.data_disk plan_output.log | grep -m1 replaced) -if [ -n "${test}" ] ; then - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldreduscore!!! Risk for Data loss !!!$resetformatting #" - echo "# #" - echo "# Database server disks will be replaced #" - echo "# #" - echo "#########################################################################################" - echo "" - echo "" - fatal_errors=1 +test=$(grep azurerm_managed_disk.data_disk plan_output.log | grep -m1 replaced) +if [ -n "${test}" ]; then + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldreduscore!!! Risk for Data loss !!!$resetformatting #" + echo "# #" + echo "# Database server disks will be replaced #" + echo "# #" + echo "#########################################################################################" + echo "" + echo "" + fatal_errors=1 fi # AnyDB server test=$(grep dbserver plan_output.log | grep -m1 replaced) -if [ -n "${test}" ] ; then - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldreduscore!!! Risk for Data loss !!!$resetformatting #" - echo "# #" - echo "# Database server(s) will be replaced #" - echo "# #" - echo "#########################################################################################" - echo "" - echo "" - echo "##vso[task.logissue type=error]${test}" - fatal_errors=1 +if [ -n "${test}" ]; then + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldreduscore!!! Risk for Data loss !!!$resetformatting #" + echo "# #" + echo "# Database server(s) will be replaced #" + echo "# #" + echo "#########################################################################################" + echo "" + echo "" + echo "##vso[task.logissue type=error]${test}" + fatal_errors=1 fi # AnyDB disks test=$(grep azurerm_managed_disk.disks plan_output.log | grep -m1 replaced) -if [ -n "${test}" ] ; then - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldreduscore!!! Risk for Data loss !!!$resetformatting #" - echo "# #" - echo "# Database server disks will be replaced #" - echo "# #" - echo "#########################################################################################" - echo "" - echo "" - echo "##vso[task.logissue type=error]${test}" - fatal_errors=1 +if [ -n "${test}" ]; then + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldreduscore!!! Risk for Data loss !!!$resetformatting #" + echo "# #" + echo "# Database server disks will be replaced #" + echo "# #" + echo "#########################################################################################" + echo "" + echo "" + echo "##vso[task.logissue type=error]${test}" + fatal_errors=1 fi # App server test=$(grep virtual_machine.app plan_output.log | grep -m1 replaced) -if [ -n "${test}" ] ; then - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldreduscore!!! Risk for Data loss !!!$resetformatting #" - echo "# #" - echo "# Application server will be replaced #" - echo "# #" - echo "#########################################################################################" - echo "" - echo "" - echo "##vso[task.logissue type=error]${test}" - fatal_errors=1 +if [ -n "${test}" ]; then + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldreduscore!!! Risk for Data loss !!!$resetformatting #" + echo "# #" + echo "# Application server will be replaced #" + echo "# #" + echo "#########################################################################################" + echo "" + echo "" + echo "##vso[task.logissue type=error]${test}" + fatal_errors=1 fi # App server disks test=$(grep azurerm_managed_disk.app plan_output.log | grep -m1 replaced) -if [ -n "${test}" ] ; then - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldreduscore!!! Risk for Data loss !!!$resetformatting #" - echo "# #" - echo "# Application server disks will be replaced #" - echo "# #" - echo "#########################################################################################" - echo "" - echo "" - echo "##vso[task.logissue type=error]${test}" - fatal_errors=1 +if [ -n "${test}" ]; then + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldreduscore!!! Risk for Data loss !!!$resetformatting #" + echo "# #" + echo "# Application server disks will be replaced #" + echo "# #" + echo "#########################################################################################" + echo "" + echo "" + echo "##vso[task.logissue type=error]${test}" + fatal_errors=1 fi # SCS server test=$(grep virtual_machine.scs plan_output.log | grep -m1 replaced) -if [ -n "${test}" ] ; then - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldreduscore!!! Risk for Data loss !!!$resetformatting #" - echo "# #" - echo "# SCS server(s) disks will be replaced #" - echo "# #" - echo "#########################################################################################" - echo "" - echo "" - echo "##vso[task.logissue type=error]${test}" - fatal_errors=1 +if [ -n "${test}" ]; then + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldreduscore!!! Risk for Data loss !!!$resetformatting #" + echo "# #" + echo "# SCS server(s) disks will be replaced #" + echo "# #" + echo "#########################################################################################" + echo "" + echo "" + echo "##vso[task.logissue type=error]${test}" + fatal_errors=1 fi # SCS server disks test=$(grep azurerm_managed_disk.scs plan_output.log | grep -m1 replaced) -if [ -n "${test}" ] ; then - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldreduscore!!! Risk for Data loss !!!$resetformatting #" - echo "# #" - echo "# SCS server disks will be replaced #" - echo "# #" - echo "#########################################################################################" - echo "" - echo "" - echo "##vso[task.logissue type=error]${test}" - fatal_errors=1 +if [ -n "${test}" ]; then + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldreduscore!!! Risk for Data loss !!!$resetformatting #" + echo "# #" + echo "# SCS server disks will be replaced #" + echo "# #" + echo "#########################################################################################" + echo "" + echo "" + echo "##vso[task.logissue type=error]${test}" + fatal_errors=1 fi # Web server test=$(grep virtual_machine.web plan_output.log | grep -m1 replaced) -if [ -n "${test}" ] ; then - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldreduscore!!! Risk for Data loss !!!$resetformatting #" - echo "# #" - echo "# Web Dispatcher server(s) will be replaced #" - echo "# #" - echo "#########################################################################################" - echo "" - echo "" - echo "##vso[task.logissue type=error]${test}" - fatal_errors=1 +if [ -n "${test}" ]; then + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldreduscore!!! Risk for Data loss !!!$resetformatting #" + echo "# #" + echo "# Web Dispatcher server(s) will be replaced #" + echo "# #" + echo "#########################################################################################" + echo "" + echo "" + echo "##vso[task.logissue type=error]${test}" + fatal_errors=1 fi # Web dispatcher server disks test=$(grep azurerm_managed_disk.web plan_output.log | grep -m1 "must be replaced") -if [ -n "${test}" ] ; then - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldreduscore!!! Risk for Data loss !!!$resetformatting #" - echo "# #" - echo "# Web Dispatcher server disks will be replaced #" - echo "# #" - echo "#########################################################################################" - echo "" - - echo "" - echo "##vso[task.logissue type=error]${test}" - fatal_errors=1 +if [ -n "${test}" ]; then + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldreduscore!!! Risk for Data loss !!!$resetformatting #" + echo "# #" + echo "# Web Dispatcher server disks will be replaced #" + echo "# #" + echo "#########################################################################################" + echo "" + + echo "" + echo "##vso[task.logissue type=error]${test}" + fatal_errors=1 fi echo "TEST_ONLY: " $TEST_ONLY if [ "${TEST_ONLY}" == "True" ]; then - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $cyan Running plan only. $resetformatting #" - echo "# #" - echo "# No deployment performed. #" - echo "# #" - echo "#########################################################################################" - echo "" - exit 0 + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $cyan Running plan only. $resetformatting #" + echo "# #" + echo "# No deployment performed. #" + echo "# #" + echo "#########################################################################################" + echo "" + exit 0 fi ok_to_proceed=1 -if [ $fatal_errors == 1 ] ; then - ok_to_proceed=0 - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldreduscore!!! Risk for Data loss !!!$resetformatting #" - echo "# #" - echo "# Please inspect the output of Terraform plan carefully before proceeding #" - echo "# #" - echo "#########################################################################################" - echo "" - if [ 1 == "$called_from_ado" ]; then - unset TF_DATA_DIR - echo "Risk for data loss, Please inspect the output of Terraform plan carefully. Run manually from deployer" > "${system_config_information}".err - echo ##vso[task.logissue type=error]Risk for data loss, Please inspect the output of Terraform plan carefully. Run manually from deployer - exit 1 - fi +if [ $fatal_errors == 1 ]; then + ok_to_proceed=0 + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldreduscore!!! Risk for Data loss !!!$resetformatting #" + echo "# #" + echo "# Please inspect the output of Terraform plan carefully before proceeding #" + echo "# #" + echo "#########################################################################################" + echo "" + if [ 1 == "$called_from_ado" ]; then + unset TF_DATA_DIR + echo "Risk for data loss, Please inspect the output of Terraform plan carefully. Run manually from deployer" >"${system_config_information}".err + echo ##vso[task.logissue type=error]Risk for data loss, Please inspect the output of Terraform plan carefully. Run manually from deployer + exit 1 + fi - if [ 1 == $force ]; then - ok_to_proceed=1 + if [ 1 == $force ]; then + ok_to_proceed=1 + else + read -p "Do you want to continue with the deployment Y/N?" ans + answer=${ans^^} + if [ $answer == 'Y' ]; then + ok_to_proceed=true else - read -p "Do you want to continue with the deployment Y/N?" ans - answer=${ans^^} - if [ $answer == 'Y' ]; then - ok_to_proceed=true - else - unset TF_DATA_DIR - exit 1 - fi + unset TF_DATA_DIR + exit 1 fi + fi fi rerun_apply=0 if [ 1 == $ok_to_proceed ]; then - if [ -f error.log ] - then - rm error.log - fi - if [ -f plan_output.log ] - then - rm plan_output.log - fi + if [ -f error.log ]; then + rm error.log + fi + if [ -f plan_output.log ]; then + rm plan_output.log + fi - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $cyan Running Terraform apply$resetformatting #" - echo "# #" - echo "#########################################################################################" - echo "" + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $cyan Running Terraform apply$resetformatting #" + echo "# #" + echo "#########################################################################################" + echo "" - allParams=$(printf " -var-file=%s %s %s %s %s %s %s %s " "${var_file}" "${extra_vars}" "${tfstate_parameter}" "${landscape_tfstate_key_parameter}" "${deployer_tfstate_key_parameter}" "${deployment_parameter}" "${version_parameter}" "${approve}" ) + allParams=$(printf " -var-file=%s %s %s %s %s %s %s %s " "${var_file}" "${extra_vars}" "${tfstate_parameter}" "${landscape_tfstate_key_parameter}" "${deployer_tfstate_key_parameter}" "${deployment_parameter}" "${version_parameter}" "${approve}") - if [ 1 == $called_from_ado ] ; then - terraform -chdir="${terraform_module_directory}" apply -parallelism="${parallelism}" -no-color -compact-warnings -json $allParams | tee -a apply_output.json + if [ 1 == $called_from_ado ]; then + terraform -chdir="${terraform_module_directory}" apply -parallelism="${parallelism}" -no-color -compact-warnings -json $allParams | tee -a apply_output.json + else + if [ -n "${approve}" ]; then + terraform -chdir="${terraform_module_directory}" apply -parallelism="${parallelism}" -json $allParams | tee -a apply_output.json else - if [ -n "${approve}" ] - then - terraform -chdir="${terraform_module_directory}" apply -parallelism="${parallelism}" -json $allParams | tee -a apply_output.json - else - terraform -chdir="${terraform_module_directory}" apply -parallelism="${parallelism}" $allParams - fi + terraform -chdir="${terraform_module_directory}" apply -parallelism="${parallelism}" $allParams fi - return_value=$? + fi + return_value=$? - if [ -f apply_output.json ] - then - errors_occurred=$(jq 'select(."@level" == "error") | length' apply_output.json) - - # Check for resource that can be imported - existing=$(jq 'select(."@level" == "error") | {address: .diagnostic.address, summary: .diagnostic.summary} | select(.summary | startswith("A resource with the ID"))' apply_output.json) - if [[ -n ${existing} ]] - then - - readarray -t existing_resources < <(echo ${existing} | jq -c '.' ) - for item in "${existing_resources[@]}"; do - moduleID=$(jq -c -r '.address ' <<< "$item") - resourceID=$(jq -c -r '.summary' <<< "$item" | awk -F'\"' '{print $2}') - echo "Trying to import" $resourceID "into" $moduleID - allParamsforImport=$(printf " -var-file=%s %s %s %s %s %s %s " "${var_file}" "${extra_vars}" "${tfstate_parameter}" "${landscape_tfstate_key_parameter}" "${deployer_tfstate_key_parameter}" "${deployment_parameter}" "${version_parameter} " ) - echo terraform -chdir="${terraform_module_directory}" import $allParamsforImport $moduleID $resourceID - terraform -chdir="${terraform_module_directory}" import $allParamsforImport $moduleID $resourceID - done - rm apply_output.json - - if [ $rerun_apply == 1 ] ; then - rerun_apply=0 - - echo "" - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $cyan Re running Terraform apply$resetformatting #" - echo "# #" - echo "#########################################################################################" - echo "" - echo "" - if [ 1 == $called_from_ado ] ; then - terraform -chdir="${terraform_module_directory}" apply -parallelism="${parallelism}" -no-color -compact-warnings -json $allParams | tee -a apply_output.json - else - terraform -chdir="${terraform_module_directory}" apply -parallelism="${parallelism}" -json $allParams | tee -a apply_output.json - fi - return_value=$? - fi - fi + if [ -f apply_output.json ]; then + errors_occurred=$(jq 'select(."@level" == "error") | length' apply_output.json) - if [ -f apply_output.json ] - then - # Check for resource that can be imported - existing=$(jq 'select(."@level" == "error") | {address: .diagnostic.address, summary: .diagnostic.summary} | select(.summary | startswith("A resource with the ID"))' apply_output.json) - if [[ -n ${existing} ]] - then - - readarray -t existing_resources < <(echo ${existing} | jq -c '.' ) - for item in "${existing_resources[@]}"; do - moduleID=$(jq -c -r '.address ' <<< "$item") - resourceID=$(jq -c -r '.summary' <<< "$item" | awk -F'\"' '{print $2}') - echo "Trying to import" $resourceID "into" $moduleID - allParamsforImport=$(printf " -var-file=%s %s %s %s %s %s %s " "${var_file}" "${extra_vars}" "${tfstate_parameter}" "${landscape_tfstate_key_parameter}" "${deployer_tfstate_key_parameter}" "${deployment_parameter}" "${version_parameter} " ) - echo terraform -chdir="${terraform_module_directory}" import $allParamsforImport $moduleID $resourceID - terraform -chdir="${terraform_module_directory}" import $allParamsforImport $moduleID $resourceID - done - - rm apply_output.json - - echo "" - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $cyan Re running Terraform apply$resetformatting #" - echo "# #" - echo "#########################################################################################" - echo "" - echo "" - if [ 1 == $called_from_ado ] ; then - terraform -chdir="${terraform_module_directory}" apply -parallelism="${parallelism}" -no-color -compact-warnings -json $allParams | tee -a apply_output.json - else - terraform -chdir="${terraform_module_directory}" apply -parallelism="${parallelism}" -json $allParams | tee -a apply_output.json - fi - return_value=$? - fi + # Check for resource that can be imported + existing=$(jq 'select(."@level" == "error") | {address: .diagnostic.address, summary: .diagnostic.summary} | select(.summary | startswith("A resource with the ID"))' apply_output.json) + if [[ -n ${existing} ]]; then - fi + readarray -t existing_resources < <(echo ${existing} | jq -c '.') + for item in "${existing_resources[@]}"; do + moduleID=$(jq -c -r '.address ' <<<"$item") + resourceID=$(jq -c -r '.summary' <<<"$item" | awk -F'\"' '{print $2}') + echo "Trying to import" $resourceID "into" $moduleID + allParamsforImport=$(printf " -var-file=%s %s %s %s %s %s %s " "${var_file}" "${extra_vars}" "${tfstate_parameter}" "${landscape_tfstate_key_parameter}" "${deployer_tfstate_key_parameter}" "${deployment_parameter}" "${version_parameter} ") + echo terraform -chdir="${terraform_module_directory}" import $allParamsforImport $moduleID $resourceID + terraform -chdir="${terraform_module_directory}" import $allParamsforImport $moduleID $resourceID + done + rm apply_output.json - if [ -f apply_output.json ] - then - - if [[ -n $errors_occurred ]] - then - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldreduscore!Errors during the apply phase!$resetformatting #" - - return_value=2 - all_errors=$(jq 'select(."@level" == "error") | {summary: .diagnostic.summary, detail: .diagnostic.detail} ' apply_output.json) - if [[ -n ${all_errors} ]] - then - readarray -t errors_strings < <(echo ${all_errors} | jq -c '.' ) - for errors_string in "${errors_strings[@]}"; do - string_to_report=$(jq -c -r '.detail ' <<< "$errors_string" ) - if [[ -z ${string_to_report} ]] - then - string_to_report=$(jq -c -r '.summary ' <<< "$errors_string" ) - fi - report=$(echo $string_to_report | grep -m1 "Message=" "${var_file}" | cut -d'=' -f2- | tr -d ' ' | tr -d '"') - if [[ -n ${report} ]] ; then - echo -e "# $boldreduscore $report $resetformatting" - if [ 1 == $called_from_ado ] ; then - - roleAssignmentExists=$(echo ${report} | grep -m1 "RoleAssignmentExists") - if [ -z ${roleAssignmentExists} ] ; then - echo "##vso[task.logissue type=error]${report}" - fi - fi - else - echo -e "# $boldreduscore $string_to_report $resetformatting" - if [ 1 == $called_from_ado ] ; then - roleAssignmentExists=$(echo ${string_to_report} | grep -m1 "RoleAssignmentExists") - if [ -z ${roleAssignmentExists} ] - then - echo "##vso[task.logissue type=error]${string_to_report}" - fi - fi - fi - echo -e "# $boldreduscore $string_to_report $resetformatting" - - done - fi - echo "# #" - echo "#########################################################################################" - echo "" + if [ $rerun_apply == 1 ]; then + rerun_apply=0 - fi + echo "" + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $cyan Re running Terraform apply$resetformatting #" + echo "# #" + echo "#########################################################################################" + echo "" + echo "" + if [ 1 == $called_from_ado ]; then + terraform -chdir="${terraform_module_directory}" apply -parallelism="${parallelism}" -no-color -compact-warnings -json $allParams | tee -a apply_output.json + else + terraform -chdir="${terraform_module_directory}" apply -parallelism="${parallelism}" -json $allParams | tee -a apply_output.json fi - + return_value=$? + fi fi - if [ -f apply_output.json ] - then + if [ -f apply_output.json ]; then + # Check for resource that can be imported + existing=$(jq 'select(."@level" == "error") | {address: .diagnostic.address, summary: .diagnostic.summary} | select(.summary | startswith("A resource with the ID"))' apply_output.json) + if [[ -n ${existing} ]]; then + + readarray -t existing_resources < <(echo ${existing} | jq -c '.') + for item in "${existing_resources[@]}"; do + moduleID=$(jq -c -r '.address ' <<<"$item") + resourceID=$(jq -c -r '.summary' <<<"$item" | awk -F'\"' '{print $2}') + echo "Trying to import" $resourceID "into" $moduleID + allParamsforImport=$(printf " -var-file=%s %s %s %s %s %s %s " "${var_file}" "${extra_vars}" "${tfstate_parameter}" "${landscape_tfstate_key_parameter}" "${deployer_tfstate_key_parameter}" "${deployment_parameter}" "${version_parameter} ") + echo terraform -chdir="${terraform_module_directory}" import $allParamsforImport $moduleID $resourceID + terraform -chdir="${terraform_module_directory}" import $allParamsforImport $moduleID $resourceID + done + rm apply_output.json - fi - if [ 0 != $return_value ] ; then + echo "" echo "" echo "#########################################################################################" echo "# #" - echo -e "# $boldreduscore!Errors during the apply phase!$resetformatting #" + echo -e "# $cyan Re running Terraform apply$resetformatting #" echo "# #" echo "#########################################################################################" echo "" - unset TF_DATA_DIR - exit $return_value - fi - -fi - -if [ "${deployment_system}" == sap_deployer ] -then - deployer_public_ip_address=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw deployer_public_ip_address | tr -d \") - keyvault=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw deployer_kv_user_name | tr -d \") - - random_id=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw random_id_b64 | tr -d \") - temp=$(echo "${random_id}" | grep -m1 "Warning") - if [ -z "${temp}" ] - then - temp=$(echo "${random_id}" | grep "Backend reinitialization required") - if [ -z "${temp}" ] - then - save_config_var "deployer_random_id" "${random_id}" - return_value=0 + echo "" + if [ 1 == $called_from_ado ]; then + terraform -chdir="${terraform_module_directory}" apply -parallelism="${parallelism}" -no-color -compact-warnings -json $allParams | tee -a apply_output.json + else + terraform -chdir="${terraform_module_directory}" apply -parallelism="${parallelism}" -json $allParams | tee -a apply_output.json fi - fi - - created_resource_group_name=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw created_resource_group_name | tr -d \") - echo "" - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $cyan Capturing telemetry $resetformatting #" - echo "# #" - echo "#########################################################################################" - echo "" - echo "" + return_value=$? + fi - if [ -n "${ARM_CLIENT_SECRET}" ] ; then - az login --service-principal --username "${ARM_CLIENT_ID}" --password=$ARM_CLIENT_SECRET --tenant "${ARM_TENANT_ID}" --output none - else - az login --identity --output none fi - az deployment group create --resource-group ${created_resource_group_name} --name "ControlPlane_Deployer_${created_resource_group_name}" --template-file "${script_directory}/templates/empty-deployment.json" --output none - return_value=0 - if [ 1 == $called_from_ado ] ; then + if [ -f apply_output.json ]; then - terraform -chdir="${terraform_module_directory}" output -json -no-color deployer_uai - - if [ -n "${created_resource_group_name}" ] ; then - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WEBAPP_RESOURCE_GROUP.value") - if [ -z ${az_var} ]; then - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_RESOURCE_GROUP --value $created_resource_group_name --output none --only-show-errors - else - az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_RESOURCE_GROUP --value $created_resource_group_name --output none --only-show-errors - fi - fi - - if [[ "${TF_VAR_use_webapp}" == "true" && $IS_PIPELINE_DEPLOYMENT = "true" ]]; then - webapp_url_base=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw webapp_url_base | tr -d \") - if [ -n "${webapp_url_base}" ] ; then - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WEBAPP_URL_BASE.value") - if [ -z ${az_var} ]; then - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_URL_BASE --value $webapp_url_base --output none --only-show-errors - else - az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_URL_BASE --value $webapp_url_base --output none --only-show-errors - fi - fi + if [[ -n $errors_occurred ]]; then + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldreduscore!Errors during the apply phase!$resetformatting #" - webapp_identity=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw webapp_identity | tr -d \") - if [ -n "${webapp_identity}" ] ; then - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WEBAPP_IDENTITY.value") - if [ -z ${az_var} ]; then - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_IDENTITY --value $webapp_identity --output none --only-show-errors - else - az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_IDENTITY --value $webapp_identity --output none --only-show-errors - fi + return_value=2 + all_errors=$(jq 'select(."@level" == "error") | {summary: .diagnostic.summary, detail: .diagnostic.detail} ' apply_output.json) + if [[ -n ${all_errors} ]]; then + readarray -t errors_strings < <(echo ${all_errors} | jq -c '.') + for errors_string in "${errors_strings[@]}"; do + string_to_report=$(jq -c -r '.detail ' <<<"$errors_string") + if [[ -z ${string_to_report} ]]; then + string_to_report=$(jq -c -r '.summary ' <<<"$errors_string") fi - - webapp_id=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw webapp_id | tr -d \") - if [ -n "${webapp_id}" ] ; then - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WEBAPP_ID.value") - if [ -z ${az_var} ]; then - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_ID --value $webapp_id --output none --only-show-errors - else - az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_ID --value $webapp_id --output none --only-show-errors + report=$(echo $string_to_report | grep -m1 "Message=" "${var_file}" | cut -d'=' -f2- | tr -d ' ' | tr -d '"') + if [[ -n ${report} ]]; then + echo -e "# $boldreduscore $report $resetformatting" + if [ 1 == $called_from_ado ]; then + + roleAssignmentExists=$(echo ${report} | grep -m1 "RoleAssignmentExists") + if [ -z ${roleAssignmentExists} ]; then + echo "##vso[task.logissue type=error]${report}" + fi fi - fi - if [ -n "${random_id}" ] ; then - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "DEPLOYER_RANDOM_ID_SEED.value") - if [ -z ${az_var} ]; then - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name DEPLOYER_RANDOM_ID_SEED --value "${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 "${random_id}" --output none --only-show-errors + else + echo -e "# $boldreduscore $string_to_report $resetformatting" + if [ 1 == $called_from_ado ]; then + roleAssignmentExists=$(echo ${string_to_report} | grep -m1 "RoleAssignmentExists") + if [ -z ${roleAssignmentExists} ]; then + echo "##vso[task.logissue type=error]${string_to_report}" fi + fi fi - fi + echo -e "# $boldreduscore $string_to_report $resetformatting" - fi - - if valid_kv_name "$keyvault" ; then - save_config_var "keyvault" "${system_config_information}" - else - printf -v val %-40.40s "$keyvault" - echo "#########################################################################################" - echo "# #" - echo -e "# The provided keyvault is not valid:$boldred ${val} $resetformatting #" + done + fi echo "# #" echo "#########################################################################################" - echo "The provided keyvault is not valid " "${val}" > secret.err + echo "" + if [ 1 == $called_from_ado ]; then + terraform -chdir="${terraform_module_directory}" apply -parallelism="${parallelism}" -no-color -compact-warnings -json $allParams | tee -a apply_output.json + else + terraform -chdir="${terraform_module_directory}" apply -parallelism="${parallelism}" -json $allParams | tee -a apply_output.json + fi + return_value=$? + + fi fi - save_config_var "deployer_public_ip_address" "${system_config_information}" -fi + fi -if [ "${deployment_system}" == sap_system ] -then - # re_run=0 - # database_loadbalancer_public_ip_address=$(terraform -chdir="${terraform_module_directory}" output -no-color database_loadbalancer_ip | tr -d "\n" | tr -d "(" | tr -d ")" | tr -d " ") - # database_loadbalancer_public_ip_address=$(echo ${database_loadbalancer_public_ip_address/tolist/}) - # database_loadbalancer_public_ip_address=$(echo ${database_loadbalancer_public_ip_address/,]/]}) - # echo "Database Load Balancer IP: $database_loadbalancer_public_ip_address" - - # load_config_vars "${parameterfile_name}" "database_loadbalancer_ips" - # database_loadbalancer_ips=$(echo ${database_loadbalancer_ips} | xargs) - - # if [[ "${database_loadbalancer_public_ip_address}" != "${database_loadbalancer_ips}" ]]; - # then - # database_loadbalancer_ips=${database_loadbalancer_public_ip_address} - # if [ -n "${database_loadbalancer_ips}" ]; then - # save_config_var "database_loadbalancer_ips" "${parameterfile_name}" - # re_run=1 - # fi - # fi - - # scs_loadbalancer_public_ip_address=$(terraform -chdir="${terraform_module_directory}" output -no-color scs_loadbalancer_ips | tr -d "\n" | tr -d "(" | tr -d ")" | tr -d " ") - # scs_loadbalancer_public_ip_address=$(echo ${scs_loadbalancer_public_ip_address/tolist/}) - # scs_loadbalancer_public_ip_address=$(echo ${scs_loadbalancer_public_ip_address/,]/]}) - # echo "SCS Load Balancer IP: $scs_loadbalancer_public_ip_address" - - # load_config_vars "${parameterfile_name}" "scs_server_loadbalancer_ips" - # scs_server_loadbalancer_ips=$(echo ${scs_server_loadbalancer_ips} | xargs) - - # if [[ "${scs_loadbalancer_public_ip_address}" != "${scs_server_loadbalancer_ips}" ]]; - # then - # scs_server_loadbalancer_ips=${scs_loadbalancer_public_ip_address} - # if [ -n "${scs_server_loadbalancer_ips}" ]; then - # save_config_var "scs_server_loadbalancer_ips" "${parameterfile_name}" - # re_run=1 - # fi - # fi - - # if [ 1 == $re_run ] ; then - # if [ 1 == $called_from_ado ] ; then - # terraform -chdir="${terraform_module_directory}" apply -parallelism="${parallelism}" -no-color -compact-warnings $allParams 2>error.log - # else - # terraform -chdir="${terraform_module_directory}" apply -parallelism="${parallelism}" $allParams 2>error.log - # fi - # fi - - rg_name=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw created_resource_group_name | tr -d \") + if [ -f apply_output.json ]; then + rm apply_output.json + fi - echo "" + if [ 0 != $return_value ]; then echo "" echo "#########################################################################################" echo "# #" - echo -e "# $cyan Capturing telemetry $resetformatting #" + echo -e "# $boldreduscore!Errors during the apply phase!$resetformatting #" echo "# #" echo "#########################################################################################" echo "" - echo "" - - az deployment group create --resource-group ${rg_name} --name "SAP_${rg_name}" --subscription $ARM_SUBSCRIPTION_ID --template-file "${script_directory}/templates/empty-deployment.json" --output none + unset TF_DATA_DIR + exit $return_value + fi fi +if [ "${deployment_system}" == sap_deployer ]; then -if [ "${deployment_system}" == sap_landscape ] -then - save_config_vars "${system_config_information}" \ - landscape_tfstate_key + # terraform -chdir="${terraform_module_directory}" output - rg_name=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw created_resource_group_name | tr -d \") - echo "" - echo "" - echo "#########################################################################################" - echo "# #" - echo -e "# $cyan Capturing telemetry $resetformatting #" - echo "# #" - echo "#########################################################################################" - echo "" - echo "" + deployer_public_ip_address=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw deployer_public_ip_address | tr -d \") + keyvault=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw deployer_kv_user_name | tr -d \") - az deployment group create --resource-group ${rg_name} --name "SAP-WORKLOAD-ZONE_${rg_name}" --template-file "${script_directory}/templates/empty-deployment.json" --output none -fi + random_id=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw random_id_b64 | tr -d \") + temp=$(echo "${random_id}" | grep -m1 "Warning") + if [ -z "${temp}" ]; then + temp=$(echo "${random_id}" | grep "Backend reinitialization required") + if [ -z "${temp}" ]; then + save_config_var "deployer_random_id" "${random_id}" + return_value=0 + fi + fi -if [ "${deployment_system}" == sap_library ] -then - REMOTE_STATE_SA=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw remote_state_storage_account_name | tr -d \") - sapbits_storage_account_name=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw sapbits_storage_account_name | tr -d \") - random_id_b64=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw random_id_b64 | tr -d \") - temp=$(echo "${random_id_b64}" | grep -m1 "Warning") - if [ -z "${temp}" ] - then - temp=$(echo "${random_id_b64}" | grep "Backend reinitialization required") - if [ -z "${temp}" ] - then - save_config_var "library_random_id" "${random_id_b64}" - return_value=0 - fi + created_resource_group_name=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw created_resource_group_name | tr -d \") + echo "" + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $cyan Capturing telemetry $resetformatting #" + echo "# #" + echo "#########################################################################################" + echo "" + echo "" + + if [ -n "${ARM_CLIENT_SECRET}" ]; then + az login --service-principal --username "${ARM_CLIENT_ID}" --password=$ARM_CLIENT_SECRET --tenant "${ARM_TENANT_ID}" --output none + else + az login --identity --output none + fi + full_script_path="$(realpath "${BASH_SOURCE[0]}")" + script_directory="$(dirname "${full_script_path}")" + az deployment group create --resource-group ${created_resource_group_name} --name "ControlPlane_Deployer_${created_resource_group_name}" --template-file "${script_directory}/templates/empty-deployment.json" --output none + return_value=0 + if [ 1 == $called_from_ado ]; then + + terraform -chdir="${terraform_module_directory}" output -json -no-color deployer_uai + + if [ -n "${created_resource_group_name}" ]; then + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WEBAPP_RESOURCE_GROUP.value") + if [ -z ${az_var} ]; then + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_RESOURCE_GROUP --value $created_resource_group_name --output none --only-show-errors + else + az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_RESOURCE_GROUP --value $created_resource_group_name --output none --only-show-errors + fi fi + if [[ "${TF_VAR_use_webapp}" == "true" && $IS_PIPELINE_DEPLOYMENT = "true" ]]; then + webapp_url_base=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw webapp_url_base | tr -d \") + if [ -n "${webapp_url_base}" ]; then + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WEBAPP_URL_BASE.value") + if [ -z ${az_var} ]; then + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_URL_BASE --value $webapp_url_base --output none --only-show-errors + else + az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_URL_BASE --value $webapp_url_base --output none --only-show-errors + fi + fi - if [ 1 == $called_from_ado ] ; then + webapp_identity=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw webapp_identity | tr -d \") + if [ -n "${webapp_identity}" ]; then + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WEBAPP_IDENTITY.value") + if [ -z ${az_var} ]; then + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_IDENTITY --value $webapp_identity --output none --only-show-errors + else + az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_IDENTITY --value $webapp_identity --output none --only-show-errors + fi + fi - if [ -n "${sapbits_storage_account_name}" ] ; then - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "INSTALLATION_MEDIA_ACCOUNT.value") - if [ -z ${az_var} ]; then - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name INSTALLATION_MEDIA_ACCOUNT --value "${sapbits_storage_account_name}" --output none --only-show-errors - else - az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name INSTALLATION_MEDIA_ACCOUNT --value "${sapbits_storage_account_name}" --output none --only-show-errors - fi + webapp_id=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw webapp_id | tr -d \") + if [ -n "${webapp_id}" ]; then + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "WEBAPP_ID.value") + if [ -z ${az_var} ]; then + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_ID --value $webapp_id --output none --only-show-errors + else + az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name WEBAPP_ID --value $webapp_id --output none --only-show-errors fi - if [ -n "${random_id_b64}" ] ; then - az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "LIBRARY_RANDOM_ID_SEED.value") - if [ -z ${az_var} ]; then - az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name LIBRARY_RANDOM_ID_SEED --value "${random_id_b64}" --output none --only-show-errors - else - az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name LIBRARY_RANDOM_ID_SEED --value "${random_id_b64}" --output none --only-show-errors - fi + fi + if [ -n "${random_id}" ]; then + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "DEPLOYER_RANDOM_ID_SEED.value") + if [ -z ${az_var} ]; then + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name DEPLOYER_RANDOM_ID_SEED --value "${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 "${random_id}" --output none --only-show-errors fi - + fi fi - get_and_store_sa_details "${REMOTE_STATE_SA}" "${system_config_information}" - rg_name=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw created_resource_group_name | tr -d \") + fi - echo "" - echo "" + if valid_kv_name "$keyvault"; then + save_config_var "keyvault" "${system_config_information}" + else + printf -v val %-40.40s "$keyvault" echo "#########################################################################################" echo "# #" - echo -e "# $cyan Capturing telemetry $resetformatting #" + echo -e "# The provided keyvault is not valid:$boldred ${val} $resetformatting #" echo "# #" echo "#########################################################################################" - echo "" - echo "" + echo "The provided keyvault is not valid " "${val}" >secret.err + fi + + save_config_var "deployer_public_ip_address" "${system_config_information}" +fi + +if [ "${deployment_system}" == sap_system ]; then + # re_run=0 + # database_loadbalancer_public_ip_address=$(terraform -chdir="${terraform_module_directory}" output -no-color database_loadbalancer_ip | tr -d "\n" | tr -d "(" | tr -d ")" | tr -d " ") + # database_loadbalancer_public_ip_address=$(echo ${database_loadbalancer_public_ip_address/tolist/}) + # database_loadbalancer_public_ip_address=$(echo ${database_loadbalancer_public_ip_address/,]/]}) + # echo "Database Load Balancer IP: $database_loadbalancer_public_ip_address" + + # load_config_vars "${parameterfile_name}" "database_loadbalancer_ips" + # database_loadbalancer_ips=$(echo ${database_loadbalancer_ips} | xargs) + + # if [[ "${database_loadbalancer_public_ip_address}" != "${database_loadbalancer_ips}" ]]; + # then + # database_loadbalancer_ips=${database_loadbalancer_public_ip_address} + # if [ -n "${database_loadbalancer_ips}" ]; then + # save_config_var "database_loadbalancer_ips" "${parameterfile_name}" + # re_run=1 + # fi + # fi + + # scs_loadbalancer_public_ip_address=$(terraform -chdir="${terraform_module_directory}" output -no-color scs_loadbalancer_ips | tr -d "\n" | tr -d "(" | tr -d ")" | tr -d " ") + # scs_loadbalancer_public_ip_address=$(echo ${scs_loadbalancer_public_ip_address/tolist/}) + # scs_loadbalancer_public_ip_address=$(echo ${scs_loadbalancer_public_ip_address/,]/]}) + # echo "SCS Load Balancer IP: $scs_loadbalancer_public_ip_address" + + # load_config_vars "${parameterfile_name}" "scs_server_loadbalancer_ips" + # scs_server_loadbalancer_ips=$(echo ${scs_server_loadbalancer_ips} | xargs) + + # if [[ "${scs_loadbalancer_public_ip_address}" != "${scs_server_loadbalancer_ips}" ]]; + # then + # scs_server_loadbalancer_ips=${scs_loadbalancer_public_ip_address} + # if [ -n "${scs_server_loadbalancer_ips}" ]; then + # save_config_var "scs_server_loadbalancer_ips" "${parameterfile_name}" + # re_run=1 + # fi + # fi + + # if [ 1 == $re_run ] ; then + # if [ 1 == $called_from_ado ] ; then + # terraform -chdir="${terraform_module_directory}" apply -parallelism="${parallelism}" -no-color -compact-warnings $allParams 2>error.log + # else + # terraform -chdir="${terraform_module_directory}" apply -parallelism="${parallelism}" $allParams 2>error.log + # fi + # fi + + rg_name=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw created_resource_group_name | tr -d \") + + echo "" + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $cyan Capturing telemetry $resetformatting #" + echo "# #" + echo "#########################################################################################" + echo "" + echo "" + full_script_path="$(realpath "${BASH_SOURCE[0]}")" + script_directory="$(dirname "${full_script_path}")" + az deployment group create --resource-group ${rg_name} --name "SAP_${rg_name}" --subscription $ARM_SUBSCRIPTION_ID --template-file "${script_directory}/templates/empty-deployment.json" --output none + +fi + +if [ "${deployment_system}" == sap_landscape ]; then + save_config_vars "${system_config_information}" \ + landscape_tfstate_key + + rg_name=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw created_resource_group_name | tr -d \") + echo "" + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $cyan Capturing telemetry $resetformatting #" + echo "# #" + echo "#########################################################################################" + echo "" + echo "" + full_script_path="$(realpath "${BASH_SOURCE[0]}")" + script_directory="$(dirname "${full_script_path}")" + az deployment group create --resource-group ${rg_name} --name "SAP-WORKLOAD-ZONE_${rg_name}" --template-file "${script_directory}/templates/empty-deployment.json" --output none +fi + +if [ "${deployment_system}" == sap_library ]; then + REMOTE_STATE_SA=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw remote_state_storage_account_name | tr -d \") + sapbits_storage_account_name=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw sapbits_storage_account_name | tr -d \") + random_id_b64=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw random_id_b64 | tr -d \") + temp=$(echo "${random_id_b64}" | grep -m1 "Warning") + if [ -z "${temp}" ]; then + temp=$(echo "${random_id_b64}" | grep "Backend reinitialization required") + if [ -z "${temp}" ]; then + save_config_var "library_random_id" "${random_id_b64}" + return_value=0 + fi + fi + + if [ 1 == $called_from_ado ]; then + + if [ -n "${sapbits_storage_account_name}" ]; then + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "INSTALLATION_MEDIA_ACCOUNT.value") + if [ -z ${az_var} ]; then + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name INSTALLATION_MEDIA_ACCOUNT --value "${sapbits_storage_account_name}" --output none --only-show-errors + else + az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name INSTALLATION_MEDIA_ACCOUNT --value "${sapbits_storage_account_name}" --output none --only-show-errors + fi + fi + if [ -n "${random_id_b64}" ]; then + az_var=$(az pipelines variable-group variable list --group-id ${VARIABLE_GROUP_ID} --query "LIBRARY_RANDOM_ID_SEED.value") + if [ -z ${az_var} ]; then + az pipelines variable-group variable create --group-id ${VARIABLE_GROUP_ID} --name LIBRARY_RANDOM_ID_SEED --value "${random_id_b64}" --output none --only-show-errors + else + az pipelines variable-group variable update --group-id ${VARIABLE_GROUP_ID} --name LIBRARY_RANDOM_ID_SEED --value "${random_id_b64}" --output none --only-show-errors + fi + fi + + fi - az deployment group create --resource-group ${rg_name} --name "SAP-LIBRARY_${rg_name}" --template-file "${script_directory}/templates/empty-deployment.json" --output none + get_and_store_sa_details "${REMOTE_STATE_SA}" "${system_config_information}" + rg_name=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw created_resource_group_name | tr -d \") + + echo "" + echo "" + echo "#########################################################################################" + echo "# #" + echo -e "# $cyan Capturing telemetry $resetformatting #" + echo "# #" + echo "#########################################################################################" + echo "" + echo "" + + full_script_path="$(realpath "${BASH_SOURCE[0]}")" + script_directory="$(dirname "${full_script_path}")" + az deployment group create --resource-group ${rg_name} --name "SAP-LIBRARY_${rg_name}" --template-file "${script_directory}/templates/empty-deployment.json" --output none fi if [ -f "${system_config_information}".err ]; then - cat "${system_config_information}".err + cat "${system_config_information}".err + rm "${system_config_information}".err fi unset TF_DATA_DIR @@ -1407,47 +1437,53 @@ unset TF_DATA_DIR # # # Copy tfvars to storage account # # # -# # ################################################################################# -useSAS=$(az storage account show --name "${REMOTE_STATE_SA}" --query allowSharedKeyAccess --subscription "${STATE_SUBSCRIPTION}" --out tsv) +useSAS=$(az storage account show --name "${REMOTE_STATE_SA}" --query allowSharedKeyAccess --subscription "${STATE_SUBSCRIPTION}" --out tsv) -if [ "$useSAS" = "true" ] ; then - az storage blob upload --file "${parameterfile}" --container-name tfvars/"${state_path}"/"${key}" --name "${parameterfile_name}" --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --no-progress --overwrite --only-show-errors --output none +if [ "$useSAS" = "true" ]; then + az storage blob upload --file "${parameterfile}" --container-name tfvars/"${state_path}"/"${key}" --name "${parameterfile_name}" --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --no-progress --overwrite --only-show-errors --output none else - az storage blob upload --file "${parameterfile}" --container-name tfvars/"${state_path}"/"${key}" --name "${parameterfile_name}" --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --auth-mode login --no-progress --overwrite --only-show-errors --output none + az storage blob upload --file "${parameterfile}" --container-name tfvars/"${state_path}"/"${key}" --name "${parameterfile_name}" --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --auth-mode login --no-progress --overwrite --only-show-errors --output none fi -if [ "${deployment_system}" == sap_system ] ; then +if [ "${deployment_system}" == sap_system ]; then echo "Uploading the yaml files from ${param_dirname} to the storage account" - if [ "$useSAS" = "true" ] ; then - az storage blob upload --file sap-parameters.yaml --container-name tfvars/"${state_path}"/"${key}" --name sap-parameters.yaml --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --no-progress --overwrite --only-show-errors --output none + if [ "$useSAS" = "true" ]; then + az storage blob upload --file sap-parameters.yaml --container-name tfvars/"${state_path}"/"${key}" --name sap-parameters.yaml --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --no-progress --overwrite --only-show-errors --output none else - az storage blob upload --file sap-parameters.yaml --container-name tfvars/"${state_path}"/"${key}" --name sap-parameters.yaml --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --auth-mode login --no-progress --overwrite --only-show-errors --output none + az storage blob upload --file sap-parameters.yaml --container-name tfvars/"${state_path}"/"${key}" --name sap-parameters.yaml --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --auth-mode login --no-progress --overwrite --only-show-errors --output none fi hosts_file=$(ls *_hosts.yaml) - if [ "$useSAS" = "true" ] ; then - az storage blob upload --file "${hosts_file}" --container-name tfvars/"${state_path}"/"${key}" --name "${hosts_file}" --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --no-progress --overwrite --only-show-errors --output none + if [ "$useSAS" = "true" ]; then + az storage blob upload --file "${hosts_file}" --container-name tfvars/"${state_path}"/"${key}" --name "${hosts_file}" --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --no-progress --overwrite --only-show-errors --output none else - az storage blob upload --file "${hosts_file}" --container-name tfvars/"${state_path}"/"${key}" --name "${hosts_file}" --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --auth-mode login --no-progress --overwrite --only-show-errors --output none + az storage blob upload --file "${hosts_file}" --container-name tfvars/"${state_path}"/"${key}" --name "${hosts_file}" --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --auth-mode login --no-progress --overwrite --only-show-errors --output none fi fi -if [ "${deployment_system}" == sap_landscape ] ; then - if [ "$useSAS" = "true" ] ; then - az storage blob upload --file "${system_config_information}" --container-name tfvars/.sap_deployment_automation --name "${environment}${region_code}${network_logical_name}" --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --no-progress --overwrite --only-show-errors --output none +if [ "${deployment_system}" == sap_landscape ]; then + if [ "$useSAS" = "true" ]; then + az storage blob upload --file "${system_config_information}" --container-name tfvars/.sap_deployment_automation --name "${environment}${region_code}${network_logical_name}" --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --no-progress --overwrite --only-show-errors --output none else - az storage blob upload --file "${system_config_information}" --container-name tfvars/.sap_deployment_automation --name "${environment}${region_code}${network_logical_name}" --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --auth-mode login --no-progress --overwrite --only-show-errors --output none + az storage blob upload --file "${system_config_information}" --container-name tfvars/.sap_deployment_automation --name "${environment}${region_code}${network_logical_name}" --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --auth-mode login --no-progress --overwrite --only-show-errors --output none fi fi -if [ "${deployment_system}" == sap_library ] ; then +if [ "${deployment_system}" == sap_library ]; then deployer_config_information="${automation_config_directory}"/"${environment}""${region_code}" - if [ "$useSAS" = "true" ] ; then - az storage blob upload --file "${deployer_config_information}" --container-name tfvars/.sap_deployment_automation --name "${environment}${region_code}" --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --no-progress --overwrite --only-show-errors --output none + if [ "$useSAS" = "true" ]; then + az storage blob upload --file "${deployer_config_information}" --container-name tfvars/.sap_deployment_automation --name "${environment}${region_code}" --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --no-progress --overwrite --only-show-errors --output none else - az storage blob upload --file "${deployer_config_information}" --container-name tfvars/.sap_deployment_automation --name "${environment}${region_code}" --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --auth-mode login --no-progress --overwrite --only-show-errors --output none + az storage blob upload --file "${deployer_config_information}" --container-name tfvars/.sap_deployment_automation --name "${environment}${region_code}" --subscription "${STATE_SUBSCRIPTION}" --account-name "${REMOTE_STATE_SA}" --auth-mode login --no-progress --overwrite --only-show-errors --output none fi fi +echo "" +echo "#########################################################################################" +echo "# #" +echo -e "# $green Deployment completed $resetformatting #" +echo "# #" +echo "#########################################################################################" +echo "" exit $return_value diff --git a/deploy/scripts/remove_controlplane.sh b/deploy/scripts/remove_controlplane.sh index 630452b8ec..292d34037f 100755 --- a/deploy/scripts/remove_controlplane.sh +++ b/deploy/scripts/remove_controlplane.sh @@ -39,34 +39,34 @@ keep_agent=0 function showhelp { echo "" - echo "#################################################################################################################" - echo "# #" - echo "# #" - echo "# This file contains the logic to remove the deployer and library from an Azure region #" - echo "# #" - echo "# The script experts the following exports: #" - echo "# #" - echo "# SAP_AUTOMATION_REPO_PATH the path to the folder containing the cloned sap-automation #" - echo "# #" - echo "# The script is to be run from a parent folder to the folders containing the json parameter files for #" - echo "# the deployer and the library and the environment. #" - echo "# #" - echo "# The script will persist the parameters needed between the executions in the #" - echo "# [CONFIG_REPO_PATH]/.sap_deployment_automation folder #" - echo "# #" - echo "# #" - echo "# Usage: remove_region.sh #" - echo "# -d or --deployer_parameter_file deployer parameter file #" - echo "# -l or --library_parameter_file library parameter file #" - echo "# #" - echo "# #" - echo "# Example: #" - echo "# #" - echo "# SAP_AUTOMATION_REPO_PATH/scripts/remove_controlplane.sh \ #" - echo "# --deployer_parameter_file DEPLOYER/PROD-WEEU-DEP00-INFRASTRUCTURE/PROD-WEEU-DEP00-INFRASTRUCTURE.json \ #" - echo "# --library_parameter_file LIBRARY/PROD-WEEU-SAP_LIBRARY/PROD-WEEU-SAP_LIBRARY.json \ #" - echo "# #" - echo "#################################################################################################################" + echo "##################################################################################################################" + echo "# #" + echo "# #" + echo "# This file contains the logic to remove the deployer and library from an Azure region #" + echo "# #" + echo "# The script experts the following exports: #" + echo "# #" + echo "# SAP_AUTOMATION_REPO_PATH the path to the folder containing the cloned sap-automation #" + echo "# #" + echo "# The script is to be run from a parent folder to the folders containing the json parameter files for #" + echo "# the deployer and the library and the environment. #" + echo "# #" + echo "# The script will persist the parameters needed between the executions in the #" + echo "# [CONFIG_REPO_PATH]/.sap_deployment_automation folder #" + echo "# #" + echo "# #" + echo "# Usage: remove_region.sh #" + echo "# -d or --deployer_parameter_file deployer parameter file #" + echo "# -l or --library_parameter_file library parameter file #" + echo "# #" + echo "# #" + echo "# Example: #" + echo "# #" + echo "# SAP_AUTOMATION_REPO_PATH/scripts/remove_controlplane.sh \ #" + echo "# --deployer_parameter_file DEPLOYER/PROD-WEEU-DEP00-INFRASTRUCTURE/PROD-WEEU-DEP00-INFRASTRUCTURE.tfvars \ #" + echo "# --library_parameter_file LIBRARY/PROD-WEEU-SAP_LIBRARY/PROD-WEEU-SAP_LIBRARY.tfvars \ #" + echo "# #" + echo "##################################################################################################################" } function missing { @@ -177,11 +177,11 @@ init "${automation_config_directory}" "${generic_config_information}" "${deploye this_ip=$(curl -s ipinfo.io/ip) >/dev/null 2>&1 export TF_IN_AUTOMATION="true" -echo "Deployer environment: $deployer_environment" +echo "Deployer environment: $deployer_environment" this_ip=$(curl -s ipinfo.io/ip) >/dev/null 2>&1 export TF_VAR_Agent_IP=$this_ip -echo "Agent IP: $this_ip" +echo "Agent IP: $this_ip" if [ -n "${subscription}" ] then @@ -244,10 +244,10 @@ key=$(echo "${deployer_file_parametername}" | cut -d. -f1) useSAS=$(az storage account show --name "${REMOTE_STATE_SA}" --query allowSharedKeyAccess --subscription "${STATE_SUBSCRIPTION}" --out tsv) if [ "$useSAS" = "true" ] ; then - echo "Authenticate storage using SAS" + echo "Storage Account Authentication: Key" export ARM_USE_AZUREAD=false else - echo "Authenticate storage using Entra ID" + echo "Storage Account Authentication: Entra ID" export ARM_USE_AZUREAD=true fi diff --git a/deploy/scripts/remove_deployer.sh b/deploy/scripts/remove_deployer.sh index 3aa3129ef5..6ef413741b 100755 --- a/deploy/scripts/remove_deployer.sh +++ b/deploy/scripts/remove_deployer.sh @@ -75,7 +75,7 @@ deployment_system=sap_deployer param_dirname=$(dirname "${parameterfile}") -echo "Parameter file: "${parameterfile}"" +echo "Parameter file: ${parameterfile}" if [ ! -f "${parameterfile}" ] then diff --git a/deploy/scripts/remover.sh b/deploy/scripts/remover.sh index 8dc14b1896..83a3ada06f 100755 --- a/deploy/scripts/remover.sh +++ b/deploy/scripts/remover.sh @@ -29,13 +29,13 @@ function showhelp { echo "# This file contains the logic to remove the different systems #" echo "# The script expects the following exports: #" echo "# #" - echo "# SAP_AUTOMATION_REPO_PATH (path to the repo folder (sap-automation)) #" + echo "# SAP_AUTOMATION_REPO_PATH (path to the repo folder (sap-automation)) #" echo "# ARM_SUBSCRIPTION_ID (subscription containing the state file storage account) #" echo "# REMOTE_STATE_RG (resource group name for storage account containing state files) #" echo "# REMOTE_STATE_SA (storage account for state file) #" echo "# #" echo "# The script will persist the parameters needed between the executions in the #" - echo "# [CONFIG_REPO_PATH]/.sap_deployment_automation folder. #" + echo "# [CONFIG_REPO_PATH]/.sap_deployment_automation folder. #" echo "# #" echo "# #" echo "# Usage: remover.sh #" @@ -56,7 +56,7 @@ function showhelp { echo "# Example: #" echo "# #" echo "# [REPO-ROOT]deploy/scripts/remover.sh \ #" - echo "# --parameterfile DEV-WEEU-SAP01-X00.json \ #" + echo "# --parameterfile DEV-WEEU-SAP01-X00.tfvars \ #" echo "# --type sap_system #" echo "# #" echo "#########################################################################################" @@ -105,16 +105,15 @@ done #variables tfstate_resource_id="" tfstate_parameter="" -deployer_tfstate_key="" + deployer_tfstate_key_parameter="" -landscape_tfstate_key="" landscape_tfstate_key_parameter="" # unused variables #show_help=false #deployer_tfstate_key_exists=false #landscape_tfstate_key_exists=false -echo "parameterfile: $parameterfile" +echo "parameterfile: $parameterfile" working_directory=$(pwd) @@ -193,11 +192,9 @@ fi this_ip=$(curl -s ipinfo.io/ip) >/dev/null 2>&1 -echo "Deployer environment: $deployer_environment" - this_ip=$(curl -s ipinfo.io/ip) >/dev/null 2>&1 export TF_VAR_Agent_IP=$this_ip -echo "Agent IP: $this_ip" +echo "Agent IP: $this_ip" automation_config_directory=$CONFIG_REPO_PATH/.sap_deployment_automation generic_config_information="${automation_config_directory}"/config @@ -218,19 +215,36 @@ if [ "${deployment_system}" == sap_system ]; then system_config_information="${automation_config_directory}"/"${environment}""${region_code}""${network_logical_name}" fi -echo "Configuration file: $system_config_information" -echo "Deployment region: $region" -echo "Deployment region code: $region_code" +echo "Configuration file: $system_config_information" +echo "Deployment region: $region" +echo "Deployment region code: $region_code" key=$(echo "${parameterfile_name}" | cut -d. -f1) +echo "" +echo "Terraform details" +echo "-------------------------------------------------------------------------" +echo "Subscription: ${STATE_SUBSCRIPTION}" +echo "Storage Account: ${REMOTE_STATE_SA}" +echo "Resource Group: ${REMOTE_STATE_RG}" +echo "State file: ${key}.terraform.tfstate" +echo "Target subscription: ${ARM_SUBSCRIPTION_ID}" +echo "Deployer State file: ${deployer_tfstate_key}" +echo "Landscape State file: ${landscape_tfstate_key}" + #Plugins -if [ ! -d /opt/terraform/.terraform.d/plugin-cache ] -then - mkdir -p /opt/terraform/.terraform.d/plugin-cache -fi -export TF_PLUGIN_CACHE_DIR=/opt/terraform/.terraform.d/plugin-cache +isInCloudShellCheck=$(checkIfCloudShell) +if checkIfCloudShell; then + mkdir -p "${HOME}/.terraform.d/plugin-cache" + export TF_PLUGIN_CACHE_DIR="${HOME}/.terraform.d/plugin-cache" +else + if [ ! -d /opt/terraform/.terraform.d/plugin-cache ]; then + mkdir -p /opt/terraform/.terraform.d/plugin-cache + sudo chown -R "$USER" /opt/terraform + fi + export TF_PLUGIN_CACHE_DIR=/opt/terraform/.terraform.d/plugin-cache +fi init "${automation_config_directory}" "${generic_config_information}" "${system_config_information}" var_file="${parameterfile_dirname}"/"${parameterfile}" @@ -254,15 +268,15 @@ load_config_vars "${system_config_information}" "ARM_SUBSCRIPTION_ID" deployer_tfstate_key_parameter='' if [ "${deployment_system}" != sap_deployer ]; then - deployer_tfstate_key_parameter=" -var deployer_tfstate_key=${deployer_tfstate_key}" + deployer_tfstate_key_parameter=" -var deployer_tfstate_key=${deployer_tfstate_key} " fi landscape_tfstate_key_parameter='' if [ "${deployment_system}" == sap_system ]; then - landscape_tfstate_key_parameter=" -var landscape_tfstate_key=${landscape_tfstate_key}" + landscape_tfstate_key_parameter=" -var landscape_tfstate_key=${landscape_tfstate_key} " fi -tfstate_parameter=" -var tfstate_resource_id=${tfstate_resource_id}" +tfstate_parameter=" -var tfstate_resource_id=${tfstate_resource_id} " #setting the user environment variables set_executing_user_environment_variables "none" @@ -302,14 +316,14 @@ fi useSAS=$(az storage account show --name "${REMOTE_STATE_SA}" --query allowSharedKeyAccess --subscription "${STATE_SUBSCRIPTION}" --out tsv) if [ "$useSAS" = "true" ] ; then - echo "Authenticate storage using SAS" + echo "Storage Account Authentication: Key" export ARM_USE_AZUREAD=false else - echo "Authenticate storage using Entra ID" + echo "Storage Account Authentication: Entra ID" + export ARM_USE_AZUREAD=true fi - echo "" echo "#########################################################################################" echo "# #" @@ -328,7 +342,7 @@ terraform -chdir="${terraform_module_directory}" init -reconfigure \ exit 1 } - +export TF_VAR_tfstate_resource_id=$(az storage account show --name "${REMOTE_STATE_SA}" --query id --subscription "${STATE_SUBSCRIPTION}" --out tsv) created_resource_group_id=$(terraform -chdir="${terraform_module_directory}" output -no-color -raw created_resource_group_id | tr -d \") created_resource_group_id_length=$(expr length "$created_resource_group_id") @@ -341,7 +355,7 @@ else resource_group_exist=true fi -if [ $resource_group_exist ]; +if [ "$resource_group_exist" ]; then echo "" echo "#########################################################################################" @@ -353,11 +367,11 @@ then if [ "$deployment_system" == "sap_deployer" ]; then terraform -chdir="${terraform_bootstrap_directory}" refresh -var-file="${var_file}" \ - $deployer_tfstate_key_parameter + "$deployer_tfstate_key_parameter" echo -e "#$cyan processing $deployment_system removal as defined in $parameterfile_name $resetformatting" terraform -chdir="${terraform_module_directory}" destroy -var-file="${var_file}" \ - $deployer_tfstate_key_parameter + "$deployer_tfstate_key_parameter" elif [ "$deployment_system" == "sap_library" ]; then echo -e "#$cyan processing $deployment_system removal as defined in $parameterfile_name $resetformatting" @@ -376,28 +390,22 @@ then terraform -chdir="${terraform_bootstrap_directory}" init -upgrade=true -force-copy terraform -chdir="${terraform_bootstrap_directory}" refresh -var-file="${var_file}" \ - $landscape_tfstate_key_parameter \ - $deployer_tfstate_key_parameter + "$landscape_tfstate_key_parameter" \ + "$deployer_tfstate_key_parameter" - terraform -chdir="${terraform_bootstrap_directory}" destroy -var-file="${var_file}" ${approve} \ - $landscape_tfstate_key_parameter \ - $deployer_tfstate_key_parameter + terraform -chdir="${terraform_bootstrap_directory}" destroy -var-file="${var_file}" "${approve}" \ + "$landscape_tfstate_key_parameter" \ + "$deployer_tfstate_key_parameter" else echo -e "#$cyan processing $deployment_system removal as defined in $parameterfile_name $resetformatting" - echo $tfstate_parameter $landscape_tfstate_key_parameter $deployer_tfstate_key_parameter + echo "Calling destroy with: -var-file=${var_file} $approve $tfstate_parameter $landscape_tfstate_key_parameter $deployer_tfstate_key_parameter" + if [ -n "${approve}" ] then - - terraform -chdir="${terraform_module_directory}" destroy -var-file="${var_file}" ${approve} \ - $tfstate_parameter \ - $landscape_tfstate_key_parameter \ - $deployer_tfstate_key_parameter -json | tee -a destroy_output.json + terraform -chdir="${terraform_module_directory}" destroy -var-file="${var_file}" $approve $tfstate_parameter $landscape_tfstate_key_parameter $deployer_tfstate_key_parameter -json | tee -a destroy_output.json else - terraform -chdir="${terraform_module_directory}" destroy -var-file="${var_file}" ${approve} \ - $tfstate_parameter \ - $landscape_tfstate_key_parameter \ - $deployer_tfstate_key_parameter + terraform -chdir="${terraform_module_directory}" destroy -var-file="${var_file}" $approve $tfstate_parameter $landscape_tfstate_key_parameter $deployer_tfstate_key_parameter fi diff --git a/deploy/scripts/set_secrets.sh b/deploy/scripts/set_secrets.sh index 046929bedf..51cd63b91f 100755 --- a/deploy/scripts/set_secrets.sh +++ b/deploy/scripts/set_secrets.sh @@ -60,54 +60,54 @@ fi eval set -- "$INPUT_ARGUMENTS" while :; do case "$1" in - -e | --environment) - environment="$2" - shift 2 + -e | --environment) + environment="$2" + shift 2 ;; - -r | --region) - region_code="$2" - shift 2 + -r | --region) + region_code="$2" + shift 2 ;; - -v | --vault) - keyvault="$2" - shift 2 + -v | --vault) + keyvault="$2" + shift 2 ;; - -s | --subscription) - subscription="$2" - shift 2 + -s | --subscription) + subscription="$2" + shift 2 ;; - -c | --spn_id) - client_id="$2" - shift 2 + -c | --spn_id) + client_id="$2" + shift 2 ;; - -p | --spn_secret) - client_secret="$2" - shift 2 + -p | --spn_secret) + client_secret="$2" + shift 2 ;; - -t | --tenant_id) - tenant_id="$2" - shift 2 + -t | --tenant_id) + tenant_id="$2" + shift 2 ;; - -b | --keyvault_subscription) - STATE_SUBSCRIPTION="$2" - shift 2 + -b | --keyvault_subscription) + STATE_SUBSCRIPTION="$2" + shift 2 ;; - -w | --workload) - workload=1 - shift + -w | --workload) + workload=1 + shift ;; - -m | --msi) - deploy_using_msi_only=1 - shift + -m | --msi) + deploy_using_msi_only=1 + shift ;; - -h | --help) - showhelp - exit 3 - shift + -h | --help) + showhelp + exit 3 + shift ;; - --) - shift - break + --) + shift + break ;; esac done @@ -121,8 +121,8 @@ while [ -z "${region_code}" ]; do done if [ -z "${region_code}" ]; then - # Convert the region to the correct code - get_region_code $region + # Convert the region to the correct code + get_region_code $region fi # if ! valid_environment "${environment}"; then @@ -194,85 +194,85 @@ fi if [ 0 = "${deploy_using_msi_only:-}" ]; then - if [ -z "${client_id}" ]; then - load_config_vars "${environment_config_information}" "client_id" - if [ -z "$client_id" ]; then - read -r -p "SPN App ID: " client_id - fi - else - if is_valid_guid "${client_id}" ; then - echo "Valid client_id specified" - else - printf -v val %-40.40s "$client_id" - echo "#########################################################################################" - echo "# #" - echo -e "# The provided client_id is not valid:$boldred ${val} $resetformatting #" - echo "# #" - echo "#########################################################################################" - return_code=65 - echo "The provided client_id is not valid " "${val}" > secret.err - exit $return_code - fi - fi - - if [ ! -n "$client_secret" ]; then - #do not output the secret to screen - read -rs -p " -> Kindly provide SPN Password: " client_secret - echo "********" - fi - - if [ -z "${tenant_id}" ]; then - load_config_vars "${environment_config_information}" "tenant_id" - if [ -z "${tenant_id}" ]; then - read -r -p "SPN Tenant ID: " tenant_id - fi - else - if is_valid_guid "${tenant_id}" ; then - echo "Valid tenant_id specified" - else - printf -v val %-40.40s "$tenant_id" - echo "#########################################################################################" - echo "# #" - echo -e "# The provided tenant_id is not valid:$boldred ${val} $resetformatting #" - echo "# #" - echo "#########################################################################################" - return_code=65 - echo "The provided tenant_id is not valid " "${val}" > secret.err - exit $return_code - fi - fi - if [ -z "${client_id}" ]; then - echo "Missing client_id" - echo "No client_id specified" > secret.err - showhelp - return_code=65 #/* data format error */ - echo $return_code - exit $return_code - fi - - if [ -z "$client_secret" ]; then - echo "Missing client_secret" - echo "No client_secret specified" > secret.err - showhelp - return_code=65 #/* data format error */ - echo $return_code - exit $return_code - fi - - if [ -z "${tenant_id}" ]; then - echo "Missing tenant_id" - echo "No tenant_id specified" > secret.err - showhelp - return_code=65 #/* data format error */ - echo $return_code - exit $return_code - fi + if [ -z "${client_id}" ]; then + load_config_vars "${environment_config_information}" "client_id" + if [ -z "$client_id" ]; then + read -r -p "SPN App ID: " client_id + fi + else + if is_valid_guid "${client_id}" ; then + echo "" + else + printf -v val %-40.40s "$client_id" + echo "#########################################################################################" + echo "# #" + echo -e "# The provided client_id is not valid:$boldred ${val} $resetformatting #" + echo "# #" + echo "#########################################################################################" + return_code=65 + echo "The provided client_id is not valid " "${val}" > secret.err + exit $return_code + fi + fi + + if [ ! -n "$client_secret" ]; then + #do not output the secret to screen + read -rs -p " -> Kindly provide SPN Password: " client_secret + echo "********" + fi + + if [ -z "${tenant_id}" ]; then + load_config_vars "${environment_config_information}" "tenant_id" + if [ -z "${tenant_id}" ]; then + read -r -p "SPN Tenant ID: " tenant_id + fi + else + if is_valid_guid "${tenant_id}" ; then + echo "" + else + printf -v val %-40.40s "$tenant_id" + echo "#########################################################################################" + echo "# #" + echo -e "# The provided tenant_id is not valid:$boldred ${val} $resetformatting #" + echo "# #" + echo "#########################################################################################" + return_code=65 + echo "The provided tenant_id is not valid " "${val}" > secret.err + exit $return_code + fi + fi + if [ -z "${client_id}" ]; then + echo "Missing client_id" + echo "No client_id specified" > secret.err + showhelp + return_code=65 #/* data format error */ + echo $return_code + exit $return_code + fi + + if [ -z "$client_secret" ]; then + echo "Missing client_secret" + echo "No client_secret specified" > secret.err + showhelp + return_code=65 #/* data format error */ + echo $return_code + exit $return_code + fi + + if [ -z "${tenant_id}" ]; then + echo "Missing tenant_id" + echo "No tenant_id specified" > secret.err + showhelp + return_code=65 #/* data format error */ + echo $return_code + exit $return_code + fi fi if [ -z "${subscription}" ]; then read -r -p "SPN Subscription: " subscription else if is_valid_guid "${subscription}" ; then - echo "Valid subscription specified" + echo "" else printf -v val %-40.40s "${subscription}" echo "#########################################################################################" @@ -294,13 +294,16 @@ echo "# echo "#########################################################################################" echo "" +echo "Key vault: ${keyvault}" +echo "Subscription: ${STATE_SUBSCRIPTION}" + save_config_vars "${environment_config_information}" \ - keyvault \ - environment \ - subscription \ - client_id \ - tenant_id \ - STATE_SUBSCRIPTION +keyvault \ +environment \ +subscription \ +client_id \ +tenant_id \ +STATE_SUBSCRIPTION secretname="${environment}"-subscription-id @@ -325,110 +328,110 @@ if [ "${deleted}" == "${secretname}" ]; then else exists=$(az keyvault secret list --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --query "[].{Name:name} | [? contains(Name,'${secretname}')] | [0]" -o tsv) if [ "${exists}" == "${secretname}" ]; then - v=$(az keyvault secret show --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --query value -o tsv) - if [ "${v}" != "${subscription}" ] ; then - echo -e "\t $cyan Setting secret ${secretname} in keyvault ${keyvault} $resetformatting \n" - az keyvault secret set --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --value "${subscription}" --expires "$(date -d '+1 year' -u +%Y-%m-%dT%H:%M:%SZ)" >stdout.az 2>&1 - fi + v=$(az keyvault secret show --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --query value -o tsv) + if [ "${v}" != "${subscription}" ] ; then + echo -e "\t $cyan Setting secret ${secretname} in keyvault ${keyvault} $resetformatting \n" + az keyvault secret set --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --value "${subscription}" --expires "$(date -d '+1 year' -u +%Y-%m-%dT%H:%M:%SZ)" >stdout.az 2>&1 + fi else - az keyvault secret set --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --value "${subscription}" --expires "$(date -d '+1 year' -u +%Y-%m-%dT%H:%M:%SZ)" >stdout.az 2>&1 + az keyvault secret set --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --value "${subscription}" --expires "$(date -d '+1 year' -u +%Y-%m-%dT%H:%M:%SZ)" >stdout.az 2>&1 fi fi if [ -f stdout.az ]; then - result=$(grep "ERROR: The user, group or application" stdout.az) - - if [ -n "${result}" ]; then - printf -v val "%-20.20s" "$keyvault" - echo "#########################################################################################" - echo "# #" - echo -e "# No access to add the secrets in the$boldred" "${val}" "$resetformatting keyvault #" - echo "# Please add an access policy for the account you use #" - echo "# #" - echo "#########################################################################################" - echo "" - rm stdout.az - echo "No access to add the secrets in the " "${val}" "keyvault" > secret.err - return_code=77 - exit $return_code - fi - - result=$(grep "The Vault may not exist" stdout.az) - if [ -n "${result}" ]; then - printf -v val "%-20.20s could not be found!" "$keyvault" - echo "#########################################################################################" - echo "# #" - echo -e "# $boldred Keyvault" "${val}" "$resetformatting #" - echo "# #" - echo "#########################################################################################" - echo "" - rm stdout.az - return_code=65 #/* name unknown */ - echo "Keyvault" "${val}" > secret.err - exit $return_code - - fi + result=$(grep "ERROR: The user, group or application" stdout.az) + + if [ -n "${result}" ]; then + printf -v val "%-20.20s" "$keyvault" + echo "#########################################################################################" + echo "# #" + echo -e "# No access to add the secrets in the$boldred" "${val}" "$resetformatting keyvault #" + echo "# Please add an access policy for the account you use #" + echo "# #" + echo "#########################################################################################" + echo "" + rm stdout.az + echo "No access to add the secrets in the " "${val}" "keyvault" > secret.err + return_code=77 + exit $return_code + fi + + result=$(grep "The Vault may not exist" stdout.az) + if [ -n "${result}" ]; then + printf -v val "%-20.20s could not be found!" "$keyvault" + echo "#########################################################################################" + echo "# #" + echo -e "# $boldred Keyvault" "${val}" "$resetformatting #" + echo "# #" + echo "#########################################################################################" + echo "" + rm stdout.az + return_code=65 #/* name unknown */ + echo "Keyvault" "${val}" > secret.err + exit $return_code + + fi fi if [ 0 = "${deploy_using_msi_only:-}" ]; then - #turn off output, we do not want to show the details being uploaded to keyvault - secretname="${environment}"-client-id - deleted=$(az keyvault secret list-deleted --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --query "[].{Name:name} | [? contains(Name,'${secretname}')] | [0]" -o tsv) - if [ "${deleted}" == "${secretname}" ]; then - echo -e "\t $cyan Recovering secret ${secretname} in keyvault ${keyvault} $resetformatting \n" - az keyvault secret recover --name "${secretname}" --vault-name "${keyvault}" --subscription $STATE_SUBSCRIPTION - sleep 10 - fi - - v="" - secret=$(az keyvault secret list --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --query "[].{Name:name} | [? contains(Name,'${secretname}')] | [0]" -o tsv) - if [ "${secret}" == "${secretname}" ]; - then - v=$(az keyvault secret show --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --query value -o tsv) - if [ "${v}" != "${client_id}" ] ; then - az keyvault secret set --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --value "${client_id}" --expires "$(date -d '+1 year' -u +%Y-%m-%dT%H:%M:%SZ)" --only-show-errors --output none - fi - else - az keyvault secret set --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --value "${client_id}" --expires "$(date -d '+1 year' -u +%Y-%m-%dT%H:%M:%SZ)" --only-show-errors --output none - fi - - secretname="${environment}"-tenant-id - deleted=$(az keyvault secret list-deleted --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --query "[].{Name:name} | [? contains(Name,'${secretname}')] | [0]" -o tsv) - if [ "${deleted}" == "${secretname}" ]; then - echo -e "\t $cyan Recovering secret ${secretname} in keyvault ${keyvault} $resetformatting \n" - az keyvault secret recover --name "${secretname}" --vault-name "${keyvault}" --subscription $STATE_SUBSCRIPTION - sleep 10 - fi - v="" - secret=$(az keyvault secret list --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --query "[].{Name:name} | [? contains(Name,'${secretname}')] | [0]" -o tsv) - if [ "${secret}" == "${secretname}" ]; - then - v=$(az keyvault secret show --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --query value -o tsv) - if [ "${v}" != "${tenant_id}" ] ; then - az keyvault secret set --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --value "${tenant_id}" --expires "$(date -d '+1 year' -u +%Y-%m-%dT%H:%M:%SZ)" --only-show-errors --output none - fi - else - az keyvault secret set --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --value "${tenant_id}" --expires "$(date -d '+1 year' -u +%Y-%m-%dT%H:%M:%SZ)" --only-show-errors --output none - fi - - secretname="${environment}"-client-secret - deleted=$(az keyvault secret list-deleted --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --query "[].{Name:name} | [? contains(Name,'${secretname}')] | [0]" -o tsv) - if [ "${deleted}" == "${secretname}" ]; then - echo -e "\t $cyan Recovering secret ${secretname} in keyvault ${keyvault} $resetformatting \n" - az keyvault secret recover --name "${secretname}" --vault-name "${keyvault}" --subscription $STATE_SUBSCRIPTION - sleep 10 - fi - - v="" - secret=$(az keyvault secret list --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --query "[].{Name:name} | [? contains(Name,'${secretname}')] | [0]" -o tsv) - if [ "${secret}" == "${secretname}" ]; - then - v=$(az keyvault secret show --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --query value -o tsv) - if [ "${v}" != "${client_secret}" ] ; then - az keyvault secret set --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --value="${client_secret}" --expires "$(date -d '+1 year' -u +%Y-%m-%dT%H:%M:%SZ)" --only-show-errors --output none - fi - else - az keyvault secret set --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --value="${client_secret}" --expires "$(date -d '+1 year' -u +%Y-%m-%dT%H:%M:%SZ)" --only-show-errors --output none - fi + #turn off output, we do not want to show the details being uploaded to keyvault + secretname="${environment}"-client-id + deleted=$(az keyvault secret list-deleted --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --query "[].{Name:name} | [? contains(Name,'${secretname}')] | [0]" -o tsv) + if [ "${deleted}" == "${secretname}" ]; then + echo -e "\t $cyan Recovering secret ${secretname} in keyvault ${keyvault} $resetformatting \n" + az keyvault secret recover --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" + sleep 10 + fi + + v="" + secret=$(az keyvault secret list --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --query "[].{Name:name} | [? contains(Name,'${secretname}')] | [0]" -o tsv) + if [ "${secret}" == "${secretname}" ]; + then + v=$(az keyvault secret show --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --query value -o tsv) + if [ "${v}" != "${client_id}" ] ; then + az keyvault secret set --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --value "${client_id}" --expires "$(date -d '+1 year' -u +%Y-%m-%dT%H:%M:%SZ)" --only-show-errors --output none + fi + else + az keyvault secret set --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --value "${client_id}" --expires "$(date -d '+1 year' -u +%Y-%m-%dT%H:%M:%SZ)" --only-show-errors --output none + fi + + secretname="${environment}"-tenant-id + deleted=$(az keyvault secret list-deleted --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --query "[].{Name:name} | [? contains(Name,'${secretname}')] | [0]" -o tsv) + if [ "${deleted}" == "${secretname}" ]; then + echo -e "\t $cyan Recovering secret ${secretname} in keyvault ${keyvault} $resetformatting \n" + az keyvault secret recover --name "${secretname}" --vault-name "${keyvault}" --subscription $STATE_SUBSCRIPTION + sleep 10 + fi + v="" + secret=$(az keyvault secret list --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --query "[].{Name:name} | [? contains(Name,'${secretname}')] | [0]" -o tsv) + if [ "${secret}" == "${secretname}" ]; + then + v=$(az keyvault secret show --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --query value -o tsv) + if [ "${v}" != "${tenant_id}" ] ; then + az keyvault secret set --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --value "${tenant_id}" --expires "$(date -d '+1 year' -u +%Y-%m-%dT%H:%M:%SZ)" --only-show-errors --output none + fi + else + az keyvault secret set --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --value "${tenant_id}" --expires "$(date -d '+1 year' -u +%Y-%m-%dT%H:%M:%SZ)" --only-show-errors --output none + fi + + secretname="${environment}"-client-secret + deleted=$(az keyvault secret list-deleted --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --query "[].{Name:name} | [? contains(Name,'${secretname}')] | [0]" -o tsv) + if [ "${deleted}" == "${secretname}" ]; then + echo -e "\t $cyan Recovering secret ${secretname} in keyvault ${keyvault} $resetformatting \n" + az keyvault secret recover --name "${secretname}" --vault-name "${keyvault}" --subscription $STATE_SUBSCRIPTION + sleep 10 + fi + + v="" + secret=$(az keyvault secret list --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --query "[].{Name:name} | [? contains(Name,'${secretname}')] | [0]" -o tsv) + if [ "${secret}" == "${secretname}" ]; + then + v=$(az keyvault secret show --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --query value -o tsv) + if [ "${v}" != "${client_secret}" ] ; then + az keyvault secret set --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --value="${client_secret}" --expires "$(date -d '+1 year' -u +%Y-%m-%dT%H:%M:%SZ)" --only-show-errors --output none + fi + else + az keyvault secret set --name "${secretname}" --vault-name "${keyvault}" --subscription "${STATE_SUBSCRIPTION}" --value="${client_secret}" --expires "$(date -d '+1 year' -u +%Y-%m-%dT%H:%M:%SZ)" --only-show-errors --output none + fi fi exit $return_code diff --git a/deploy/scripts/validate.sh b/deploy/scripts/validate.sh index 433f7c17db..f2f9e02d5f 100755 --- a/deploy/scripts/validate.sh +++ b/deploy/scripts/validate.sh @@ -9,6 +9,11 @@ boldreduscore="\e[1;4;31m" boldred="\e[1;31m" cyan="\e[1;36m" resetformatting="\e[0m" +full_script_path="$(realpath "${BASH_SOURCE[0]}")" +script_directory="$(dirname "${full_script_path}")" + +#call stack has full scriptname when using source +source "${script_directory}/deploy_utils.sh" min() { printf "%s\n" "${@:2}" | sort "$1" | head -n1 @@ -26,7 +31,7 @@ heading() { echo "----------------------------------------------------------------------------" } -showhelp() +showhelp() { echo "" echo "#########################################################################################" @@ -132,7 +137,7 @@ else fi ############################################################################### -# SAP System # +# SAP System # ############################################################################### if [ "${deployment_system}" == sap_system ] ; then @@ -167,7 +172,7 @@ if [ "${deployment_system}" == sap_system ] ; then # subnet identifier and output prefix string changing. As such # they can be converted into a parameterised function call. - # Admin subnet + # Admin subnet subnet_name=$(jq --raw-output .infrastructure.vnets.sap.subnet_admin.name "${parameterfile}") subnet_arm_id=$(jq --raw-output .infrastructure.vnets.sap.subnet_admin.arm_id "${parameterfile}") @@ -176,7 +181,7 @@ if [ "${deployment_system}" == sap_system ] ; then then subnet_name=$(echo $subnet_arm_id | cut -d/ -f11 | xargs) fi - + subnet_nsg_name=$(jq --raw-output .infrastructure.vnets.sap.subnet_admin.nsg.name "${parameterfile}") subnet_nsg_arm_id=$(jq --raw-output .infrastructure.vnets.sap.subnet_admin.nsg.arm_id "${parameterfile}") @@ -205,9 +210,9 @@ if [ "${deployment_system}" == sap_system ] ; then else echo "Admin nsg: " "Defined by the workload/automation" fi - - # db subnet - + + # db subnet + subnet_name=$(jq --raw-output .infrastructure.vnets.sap.subnet_db.name "${parameterfile}") subnet_arm_id=$(jq --raw-output .infrastructure.vnets.sap.subnet_db.arm_id "${parameterfile}") subnet_prefix=$(jq --raw-output .infrastructure.vnets.sap.subnet_db.prefix "${parameterfile}") @@ -215,7 +220,7 @@ if [ "${deployment_system}" == sap_system ] ; then then subnet_name=$(echo $subnet_arm_id | cut -d/ -f11 | xargs) fi - + subnet_nsg_name=$(jq --raw-output .infrastructure.vnets.sap.subnet_db.nsg.name "${parameterfile}") subnet_nsg_arm_id=$(jq --raw-output .infrastructure.vnets.sap.subnet_db.nsg.arm_id "${parameterfile}") @@ -244,9 +249,9 @@ if [ "${deployment_system}" == sap_system ] ; then else echo "db nsg: " "Defined by the workload/automation" fi - - # app subnet - + + # app subnet + subnet_name=$(jq --raw-output .infrastructure.vnets.sap.subnet_app.name "${parameterfile}") subnet_arm_id=$(jq --raw-output .infrastructure.vnets.sap.subnet_app.arm_id "${parameterfile}") subnet_prefix=$(jq --raw-output .infrastructure.vnets.sap.subnet_app.prefix "${parameterfile}") @@ -265,7 +270,7 @@ if [ "${deployment_system}" == sap_system ] ; then if [ \( -n "${subnet_name}" \) -a \( "${subnet_name}" != "null" \) ] then echo "app subnet: " "${subnet_name}" - else + else echo "app subnet: " "Subnet defined by the workload/automation" fi @@ -282,9 +287,9 @@ if [ "${deployment_system}" == sap_system ] ; then else echo "app nsg: " "Defined by the workload/automation" fi - - # web subnet - + + # web subnet + subnet_name=$(jq --raw-output .infrastructure.vnets.sap.subnet_web.name "${parameterfile}") subnet_arm_id=$(jq --raw-output .infrastructure.vnets.sap.subnet_web.arm_id "${parameterfile}") subnet_prefix=$(jq --raw-output .infrastructure.vnets.sap.subnet_web.prefix "${parameterfile}") @@ -320,9 +325,9 @@ if [ "${deployment_system}" == sap_system ] ; then else echo "web nsg: " "Defined by the workload/automation" fi - + echo "" - + heading "Database tier" platform=$(jq --raw-output '.databases[0].platform' "${parameterfile}") echo "Platform: " "${platform}" @@ -357,7 +362,7 @@ if [ "${deployment_system}" == sap_system ] ; then version=$(jq --raw-output '.databases[0].os.version' "${parameterfile}") echo "Image version: " "${version}" fi - + if jq --exit-status '.databases[0].zones' "${parameterfile}" >/dev/null; then echo "Deployment: " "Zonal" zones=$(jq --compact-output '.databases[0].zones' "${parameterfile}") @@ -381,9 +386,9 @@ if [ "${deployment_system}" == sap_system ] ; then else echo "Authentication: " "key" fi - + echo - + heading "Application tier" if jq --exit-status '.application.authentication.type' "${parameterfile}" >/dev/null; then authentication=$(jq --raw-output '.application.authentication.type' "${parameterfile}") @@ -391,7 +396,7 @@ if [ "${deployment_system}" == sap_system ] ; then else echo "Authentication: " "key" fi - + echo "Application servers" if [ $app_zone_count -gt 1 ] ; then echo " Application avset: " "($app_zone_count) (name defined by automation)" @@ -426,7 +431,7 @@ if [ "${deployment_system}" == sap_system ] ; then else echo " Deployment: " "Regional" fi - + echo "Central Services" echo " SCS load balancer: " "(name defined by automation)" if [ $scs_zone_count -gt 1 ] ; then @@ -487,7 +492,7 @@ if [ "${deployment_system}" == sap_system ] ; then else echo " Deployment: " "Regional" fi - + echo "Web dispatcher" web_server_count=$(jq --raw-output .application.webdispatcher_count "${parameterfile}") echo " Web dispatcher lb: " "(name defined by automation)" @@ -497,7 +502,7 @@ if [ "${deployment_system}" == sap_system ] ; then echo " Web dispatcher avset: " "(name defined by automation)" fi echo " Number of servers: " "${web_server_count}" - + if jq --exit-status '.application.web_os' "${parameterfile}" >/dev/null; then if jq --exit-status '.application.web_os.source_image_id' "${parameterfile}" >/dev/null; then image=$(jq --raw-output .application.web_os.source_image_id "${parameterfile}") @@ -546,7 +551,7 @@ if [ "${deployment_system}" == sap_system ] ; then else echo " Deployment: " "Regional" fi - + echo "" heading "Key Vault" if jq --exit-status '.key_vault.kv_spn_id' "${parameterfile}" >/dev/null; then @@ -555,29 +560,29 @@ if [ "${deployment_system}" == sap_system ] ; then else echo " SPN Key Vault: " "Deployer keyvault" fi - + if jq --exit-status '.key_vault.kv_user_id' "${parameterfile}" >/dev/null; then kv=$(jq --raw-output .key_vault.kv_user_id "${parameterfile}") echo " User Key Vault: " "${kv}" else echo " User Key Vault: " "Workload keyvault" fi - + if jq --exit-status '.key_vault.kv_prvt_id' "${parameterfile}" >/dev/null; then kv=$(jq --raw-output .key_vault.kv_prvt_id "${parameterfile}") echo " Automation Key Vault: " "${kv}" else echo " Automation Key Vault: " "Workload keyvault" fi - + fi ############################################################################### -# SAP Landscape # +# SAP Landscape # ############################################################################### if [ "${deployment_system}" == sap_landscape ] ; then heading "Networking" - + vnet_name=$(jq --raw-output .infrastructure.vnets.sap.name "${parameterfile}") vnet_arm_id=$(jq --raw-output .infrastructure.vnets.sap.arm_id "${parameterfile}") vnet_address_space=$(jq --raw-output .infrastructure.vnets.sap.address_space "${parameterfile}") @@ -588,7 +593,7 @@ if [ "${deployment_system}" == sap_landscape ] ; then echo "VNet Logical name: " "${vnet_name}" echo "Address space: " "${vnet_address_space}" - # Admin subnet + # Admin subnet subnet_name=$(jq --raw-output .infrastructure.vnets.sap.subnet_admin.name "${parameterfile}") subnet_arm_id=$(jq --raw-output .infrastructure.vnets.sap.subnet_admin.arm_id "${parameterfile}") @@ -623,9 +628,9 @@ if [ "${deployment_system}" == sap_landscape ] ; then else echo "Admin nsg: " "Defined by the system/automation" fi - - # db subnet - + + # db subnet + subnet_name=$(jq --raw-output .infrastructure.vnets.sap.subnet_db.name "${parameterfile}") subnet_arm_id=$(jq --raw-output .infrastructure.vnets.sap.subnet_db.arm_id "${parameterfile}") subnet_prefix=$(jq --raw-output .infrastructure.vnets.sap.subnet_db.prefix "${parameterfile}") @@ -633,7 +638,7 @@ if [ "${deployment_system}" == sap_landscape ] ; then then subnet_name=$(echo $subnet_arm_id | cut -d/ -f11 | xargs) fi - + subnet_nsg_name=$(jq --raw-output .infrastructure.vnets.sap.subnet_db.nsg.name "${parameterfile}") subnet_nsg_arm_id=$(jq --raw-output .infrastructure.vnets.sap.subnet_db.nsg.arm_id "${parameterfile}") if [ -z "${subnet_nsg_arm_id}" ] @@ -659,9 +664,9 @@ if [ "${deployment_system}" == sap_landscape ] ; then else echo "db nsg: " "Defined by the system/automation" fi - - # app subnet - + + # app subnet + subnet_name=$(jq --raw-output .infrastructure.vnets.sap.subnet_app.name "${parameterfile}") subnet_arm_id=$(jq --raw-output .infrastructure.vnets.sap.subnet_app.arm_id "${parameterfile}") subnet_prefix=$(jq --raw-output .infrastructure.vnets.sap.subnet_app.prefix "${parameterfile}") @@ -695,9 +700,9 @@ if [ "${deployment_system}" == sap_landscape ] ; then else echo "app nsg: " "Defined by the system/automation" fi - - # web subnet - + + # web subnet + subnet_name=$(jq --raw-output .infrastructure.vnets.sap.subnet_web.name "${parameterfile}") subnet_arm_id=$(jq --raw-output .infrastructure.vnets.sap.subnet_web.arm_id "${parameterfile}") subnet_prefix=$(jq --raw-output .infrastructure.vnets.sap.subnet_web.prefix "${parameterfile}") @@ -716,7 +721,7 @@ if [ "${deployment_system}" == sap_landscape ] ; then if [ -z "${subnet_name}" ] then echo "web subnet: " "${subnet_name}" - else + else echo "web subnet: " "Subnet defined by the system/automation" fi if [ -z "${subnet_prefix}" ] @@ -731,8 +736,8 @@ if [ "${deployment_system}" == sap_landscape ] ; then else echo "web nsg: " "Defined by the system/automation" fi - - + + echo "" heading "Key Vault" if jq --exit-status '.key_vault.kv_spn_id' "${parameterfile}" >/dev/null; then @@ -741,14 +746,14 @@ if [ "${deployment_system}" == sap_landscape ] ; then else echo " SPN Key Vault: " "Deployer keyvault" fi - + if jq --exit-status '.key_vault.kv_user_id' "${parameterfile}" >/dev/null; then kv=$(jq --raw-output .key_vault.kv_user_id "${parameterfile}") echo " User Key Vault: " "${kv}" else echo " User Key Vault: " "Workload keyvault" fi - + if jq --exit-status '.key_vault.kv_prvt_id' "${parameterfile}" >/dev/null; then kv=$(jq --raw-output .key_vault.kv_prvt_id "${parameterfile}") echo " Automation Key Vault: " "${kv}" @@ -758,7 +763,7 @@ if [ "${deployment_system}" == sap_landscape ] ; then fi ############################################################################### -# SAP Library # +# SAP Library # ############################################################################### if [ "${deployment_system}" == sap_library ] ; then @@ -770,29 +775,29 @@ if [ "${deployment_system}" == sap_library ] ; then else echo " SPN Key Vault: " "Deployer keyvault" fi - + if jq --exit-status '.key_vault.kv_user_id' "${parameterfile}" >/dev/null; then kv=$(jq --raw-output .key_vault.kv_user_id "${parameterfile}") echo " User Key Vault: " "${kv}" else echo " User Key Vault: " "Library keyvault" fi - + if jq --exit-status '.key_vault.kv_prvt_id' "${parameterfile}" >/dev/null; then kv=$(jq --raw-output .key_vault.kv_prvt_id "${parameterfile}") echo " Automation Key Vault: " "${kv}" else echo " Automation Key Vault: " "Library keyvault" fi - + fi ############################################################################### -# SAP Deployer # +# SAP Deployer # ############################################################################### if [ "${deployment_system}" == sap_deployer ] ; then - heading "Networking" + heading "Networking" if jq --exit-status '.infrastructure.vnets.management' "${parameterfile}" >/dev/null; then if jq --exit-status '.infrastructure.vnets.management.arm_id' "${parameterfile}" >/dev/null; then arm_id=$(jq --raw-output .infrastructure.vnets.management.arm_id "${parameterfile}") @@ -812,23 +817,23 @@ if [ "${deployment_system}" == sap_deployer ] ; then else error "The Virtual network must be defined" fi - + echo "" - heading "Key Vault" + heading "Key Vault" if jq --exit-status '.key_vault.kv_spn_id' "${parameterfile}" >/dev/null; then kv=$(jq --raw-output .key_vault.kv_spn_id "${parameterfile}") echo " SPN Key Vault: " "${kv}" else echo " SPN Key Vault: " "Deployer keyvault" fi - + if jq --exit-status '.key_vault.kv_user_id' "${parameterfile}" >/dev/null; then kv=$(jq --raw-output .key_vault.kv_user_id "${parameterfile}") echo " User Key Vault: " "${kv}" else echo " User Key Vault: " "Deployer keyvault" fi - + if jq --exit-status '.key_vault.kv_prvt_id' "${parameterfile}" >/dev/null; then kv=$(jq --raw-output .key_vault.kv_prvt_id "${parameterfile}") echo " Automation Key Vault: " "${kv}" diff --git a/deploy/terraform/bootstrap/sap_deployer/providers.tf b/deploy/terraform/bootstrap/sap_deployer/providers.tf index cdc795d5a1..4d427dd2fe 100644 --- a/deploy/terraform/bootstrap/sap_deployer/providers.tf +++ b/deploy/terraform/bootstrap/sap_deployer/providers.tf @@ -20,7 +20,7 @@ data "azurerm_client_config" "current" { provider "azurerm" { features { resource_group { - prevent_deletion_if_contains_resources = true + prevent_deletion_if_contains_resources = var.prevent_deletion_if_contains_resources } key_vault { purge_soft_delete_on_destroy = !var.enable_purge_control_for_keyvaults @@ -86,7 +86,7 @@ terraform { } azurerm = { source = "hashicorp/azurerm" - version = "4.4.0" + version = "4.7.0" } } } diff --git a/deploy/terraform/bootstrap/sap_deployer/tfvar_variables.tf b/deploy/terraform/bootstrap/sap_deployer/tfvar_variables.tf index 68876b134e..2d26d87b37 100644 --- a/deploy/terraform/bootstrap/sap_deployer/tfvar_variables.tf +++ b/deploy/terraform/bootstrap/sap_deployer/tfvar_variables.tf @@ -22,6 +22,11 @@ variable "location" { type = string } +variable "prevent_deletion_if_contains_resources" { + description = "Controls if resource groups are deleted even if they contain resources" + type = bool + default = true + } #######################################4#######################################8 # # # Resource group definitioms # @@ -240,16 +245,6 @@ variable "deployer_image" { } } -variable "plan" { - description = "The plan for the marketplace item" - default = { - use = false - "name" = "" - "publisher" = "" - "product" = "" - } - } - variable "deployer_private_ip_address" { description = "If provides, the value of the deployer Virtual machine IPs" default = [""] @@ -381,7 +376,7 @@ variable "deployer_diagnostics_account_arm_id" { variable "tf_version" { description = "Terraform version to install on deployer" - default = "1.9.5" + default = "1.9.8" } variable "name_override_file" { @@ -411,10 +406,10 @@ variable "subnets_to_add_to_firewall_for_keyvaults_and_storage" { default = [] } -variable "tags" { - description = "If provided, tags for all resources" - default = {} - } +variable "tags" { + description = "If provided, tags for all resources" + default = {} + } ######################################################################################### # # # DNS settings # diff --git a/deploy/terraform/bootstrap/sap_deployer/transform.tf b/deploy/terraform/bootstrap/sap_deployer/transform.tf index c2687ef478..ae37d4b372 100644 --- a/deploy/terraform/bootstrap/sap_deployer/transform.tf +++ b/deploy/terraform/bootstrap/sap_deployer/transform.tf @@ -178,8 +178,6 @@ locals { ), "") } - plan = var.plan - private_ip_address = try(coalesce( var.deployer_private_ip_address, try(var.deployers[0].private_ip_address, "") diff --git a/deploy/terraform/bootstrap/sap_library/imports.tf b/deploy/terraform/bootstrap/sap_library/imports.tf index 02cb5d22ba..2ba1c4a262 100644 --- a/deploy/terraform/bootstrap/sap_library/imports.tf +++ b/deploy/terraform/bootstrap/sap_library/imports.tf @@ -18,28 +18,28 @@ data "azurerm_key_vault_secret" "subscription_id" { provider = azurerm.deployer count = local.use_spn ? 1 : 0 name = format("%s-subscription-id", upper(local.infrastructure.environment)) - key_vault_id = local.spn_key_vault_arm_id + key_vault_id = local.key_vault.kv_spn_id } data "azurerm_key_vault_secret" "client_id" { provider = azurerm.deployer count = local.use_spn ? 1 : 0 name = format("%s-client-id", upper(local.infrastructure.environment)) - key_vault_id = local.spn_key_vault_arm_id + key_vault_id = local.key_vault.kv_spn_id } data "azurerm_key_vault_secret" "client_secret" { provider = azurerm.deployer count = local.use_spn ? 1 : 0 name = format("%s-client-secret", upper(local.infrastructure.environment)) - key_vault_id = local.spn_key_vault_arm_id + key_vault_id = local.key_vault.kv_spn_id } data "azurerm_key_vault_secret" "tenant_id" { provider = azurerm.deployer count = local.use_spn ? 1 : 0 name = format("%s-tenant-id", upper(local.infrastructure.environment)) - key_vault_id = local.spn_key_vault_arm_id + key_vault_id = local.key_vault.kv_spn_id } // Import current service principal diff --git a/deploy/terraform/bootstrap/sap_library/providers.tf b/deploy/terraform/bootstrap/sap_library/providers.tf index 73aecd7152..269dc8ee92 100644 --- a/deploy/terraform/bootstrap/sap_library/providers.tf +++ b/deploy/terraform/bootstrap/sap_library/providers.tf @@ -26,6 +26,8 @@ provider "azurerm" { } storage_use_azuread = true + use_msi = var.use_spn ? false : true + } provider "azurerm" { @@ -44,6 +46,7 @@ provider "azurerm" { alias = "main" storage_use_azuread = true + use_msi = var.use_spn ? false : true } @@ -53,6 +56,8 @@ provider "azurerm" { alias = "deployer" storage_use_azuread = true + use_msi = false + subscription_id = var.use_deployer ? data.terraform_remote_state.deployer[0].outputs.created_resource_group_subscription_id : null } provider "azurerm" { @@ -64,6 +69,7 @@ provider "azurerm" { alias = "dnsmanagement" storage_use_azuread = true + use_msi = var.use_spn ? false : true } provider "azurerm" { @@ -75,6 +81,7 @@ provider "azurerm" { alias = "privatelinkdnsmanagement" storage_use_azuread = true + use_msi = var.use_spn ? false : true } provider "azuread" { @@ -104,7 +111,7 @@ terraform { } azurerm = { source = "hashicorp/azurerm" - version = "4.4.0" + version = "4.7.0" } } } diff --git a/deploy/terraform/bootstrap/sap_library/tfvar_variables.tf b/deploy/terraform/bootstrap/sap_library/tfvar_variables.tf index 2e9efbf7fa..e74f9a63fd 100644 --- a/deploy/terraform/bootstrap/sap_library/tfvar_variables.tf +++ b/deploy/terraform/bootstrap/sap_library/tfvar_variables.tf @@ -42,6 +42,11 @@ variable "use_spn" { default = false } +variable "tags" { + description = "If provided, tags for all resources" + default = {} + } + #######################################4#######################################8 # # # Resource group definitioms # diff --git a/deploy/terraform/bootstrap/sap_library/transform.tf b/deploy/terraform/bootstrap/sap_library/transform.tf index 0f3c93c59a..7cbfc2be08 100644 --- a/deploy/terraform/bootstrap/sap_library/transform.tf +++ b/deploy/terraform/bootstrap/sap_library/transform.tf @@ -1,123 +1,67 @@ locals { infrastructure = { - environment = coalesce(var.environment, try(var.infrastructure.environment, "")) - region = coalesce(var.location, try(var.infrastructure.region, "")) - codename = try(var.codename, try(var.infrastructure.codename, "")) + environment = var.environment + region = var.location + codename = var.codename resource_group = { - name = try(coalesce(var.resourcegroup_name, try(var.infrastructure.resource_group.name, "")), "") - arm_id = try(coalesce(var.resourcegroup_arm_id, try(var.infrastructure.resource_group.arm_id, "")), "") + name = var.resourcegroup_name + arm_id = var.resourcegroup_arm_id } - tags = try(coalesce(var.resourcegroup_tags, try(var.infrastructure.tags, {})), {}) + tags = try(coalesce(var.resourcegroup_tags, var.tags, {}), {}) } deployer = { use = var.use_deployer } key_vault = { - kv_spn_id = try(coalesce(local.spn_key_vault_arm_id, var.spn_keyvault_id, try(var.key_vault.kv_spn_id, "")), "") + kv_spn_id = coalesce(var.spn_keyvault_id, local.spn_key_vault_arm_id) } storage_account_sapbits = { - arm_id = try(coalesce(var.library_sapmedia_arm_id, try(var.storage_account_sapbits.arm_id, "")), "") - name = var.library_sapmedia_name - account_tier = coalesce( - var.library_sapmedia_account_tier, - try(var.storage_account_sapbits.account_tier, "Standard") - ) - account_replication_type = coalesce( - var.library_sapmedia_account_replication_type, - try(var.storage_account_sapbits.account_replication_type, "ZRS") - ) - account_kind = coalesce( - var.library_sapmedia_account_kind, - try(var.storage_account_sapbits.account_kind, "StorageV2") - ) + arm_id = var.library_sapmedia_arm_id + name = var.library_sapmedia_name + account_tier = var.library_sapmedia_account_tier + account_replication_type = var.library_sapmedia_account_replication_type + account_kind = var.library_sapmedia_account_kind file_share = { - enable_deployment = ( - var.library_sapmedia_file_share_enable_deployment || - try(var.storage_account_sapbits.file_share.enable_deployment, true) - ) - is_existing = ( - var.library_sapmedia_file_share_is_existing || - try(var.storage_account_sapbits.file_share.is_existing, false) - ) - name = coalesce( - var.library_sapmedia_file_share_name, - try( - var.storage_account_sapbits.file_share.name, - module.sap_namegenerator.naming.resource_suffixes.sapbits - ) - ) + enable_deployment = var.library_sapmedia_file_share_enable_deployment + is_existing = var.library_sapmedia_file_share_is_existing + name = coalesce(var.library_sapmedia_file_share_name,module.sap_namegenerator.naming.resource_suffixes.sapbits) } sapbits_blob_container = { - enable_deployment = ( - var.library_sapmedia_blob_container_enable_deployment || - try(var.storage_account_sapbits.sapbits_blob_container.enable_deployment, true) - ) - is_existing = ( - var.library_sapmedia_blob_container_is_existing || - try(var.storage_account_sapbits.sapbits_blob_container.is_existing, false) - ) - name = coalesce( - var.library_sapmedia_blob_container_name, - try( - var.storage_account_sapbits.sapbits_blob_container.name, - module.sap_namegenerator.naming.resource_suffixes.sapbits - ) - ) + enable_deployment = var.library_sapmedia_blob_container_enable_deployment + is_existing = var.library_sapmedia_blob_container_is_existing + name = coalesce(var.library_sapmedia_blob_container_name, module.sap_namegenerator.naming.resource_suffixes.sapbits) } shared_access_key_enabled = var.shared_access_key_enabled public_network_access_enabled = var.public_network_access_enabled } + storage_account_tfstate = { - arm_id = try( - coalesce( - var.library_terraform_state_arm_id, - try(var.storage_account_tfstate.arm_id, "")) - , "" - ) - name = var.library_terraform_state_name - account_tier = coalesce( - var.library_terraform_state_account_tier, - try(var.storage_account_tfstate.account_tier, "Standard") - ) - account_replication_type = coalesce( - var.library_terraform_state_account_replication_type, - try(var.storage_account_tfstate.account_replication_type, "ZRS") - ) - account_kind = coalesce( - var.library_terraform_state_account_kind, - try(var.storage_account_tfstate.account_kind, "StorageV2") - ) + arm_id = var.library_terraform_state_arm_id + name = var.library_terraform_state_name + account_tier = var.library_terraform_state_account_tier + account_replication_type = var.library_terraform_state_account_replication_type + account_kind = var.library_terraform_state_account_kind tfstate_blob_container = { - is_existing = ( - var.library_terraform_state_blob_container_is_existing || - try(var.storage_account_tfstate.tfstate_blob_container.is_existing, false) - ) - name = coalesce( - var.library_terraform_state_blob_container_name, - try(var.storage_account_tfstate.tfstate_blob_container.name, "tfstate") - ) + is_existing = var.library_terraform_state_blob_container_is_existing + name = var.library_terraform_state_blob_container_name } tfvars_blob_container = { - is_existing = var.library_terraform_vars_blob_container_is_existing - name = var.library_terraform_vars_blob_container_name + is_existing = var.library_terraform_vars_blob_container_is_existing + name = var.library_terraform_vars_blob_container_name } ansible_blob_container = { - is_existing = ( - var.library_ansible_blob_container_is_existing || - try(var.storage_account_tfstate.ansible_blob_container.is_existing, false) - ) - name = coalesce( - var.library_ansible_blob_container_name, - try(var.storage_account_tfstate.ansible_blob_container.name, "ansible") - ) + is_existing = var.library_ansible_blob_container_is_existing + name = var.library_ansible_blob_container_name } - shared_access_key_enabled = var.shared_access_key_enabled + + shared_access_key_enabled = var.shared_access_key_enabled public_network_access_enabled = var.public_network_access_enabled } + dns_settings = { use_custom_dns_a_registration = var.use_custom_dns_a_registration dns_label = var.dns_label diff --git a/deploy/terraform/run/sap_deployer/providers.tf b/deploy/terraform/run/sap_deployer/providers.tf index 8709f410de..f0e8171d15 100644 --- a/deploy/terraform/run/sap_deployer/providers.tf +++ b/deploy/terraform/run/sap_deployer/providers.tf @@ -16,7 +16,7 @@ Description: provider "azurerm" { features { resource_group { - prevent_deletion_if_contains_resources = true + prevent_deletion_if_contains_resources = var.prevent_deletion_if_contains_resources } key_vault { purge_soft_delete_on_destroy = !var.enable_purge_control_for_keyvaults @@ -27,7 +27,9 @@ provider "azurerm" { } partner_id = "f94f50f2-2539-42f8-9c8e-c65b28c681f7" storage_use_azuread = !var.shared_access_key_enabled - use_msi = var.use_spn ? false : true + subscription_id = var.subscription_id + + use_msi = true } provider "azurerm" { @@ -44,7 +46,7 @@ provider "azurerm" { } partner_id = "f94f50f2-2539-42f8-9c8e-c65b28c681f7" - subscription_id = local.spn.subscription_id + subscription_id = data.azurerm_key_vault_secret.subscription_id[0].value client_id = var.use_spn ? local.spn.client_id : null client_secret = var.use_spn ? local.spn.client_secret: null tenant_id = var.use_spn ? local.spn.tenant_id: null @@ -85,7 +87,7 @@ terraform { } azurerm = { source = "hashicorp/azurerm" - version = "4.4.0" + version = "4.7.0" } } } diff --git a/deploy/terraform/run/sap_deployer/tfvar_variables.tf b/deploy/terraform/run/sap_deployer/tfvar_variables.tf index 5bd696982b..faae59eed2 100644 --- a/deploy/terraform/run/sap_deployer/tfvar_variables.tf +++ b/deploy/terraform/run/sap_deployer/tfvar_variables.tf @@ -22,6 +22,18 @@ variable "location" { type = string } +variable "subscription_id" { + description = "Defines the Azure subscription_id" + type = string + default = null + } + + +variable "prevent_deletion_if_contains_resources" { + description = "Controls if resource groups are deleted even if they contain resources" + type = bool + default = true + } #######################################4#######################################8 # # # Resource group definitioms # @@ -240,16 +252,6 @@ variable "deployer_image" { } } -variable "plan" { - description = "The plan for the marketplace item" - default = { - use = false - "name" = "" - "publisher" = "" - "product" = "" - } - } - variable "deployer_private_ip_address" { description = "If provides, the value of the deployer Virtual machine IPs" default = [""] @@ -378,7 +380,7 @@ variable "deployer_diagnostics_account_arm_id" { variable "tf_version" { description = "Terraform version to install on deployer" - default = "1.9.5" + default = "1.9.8" } variable "name_override_file" { diff --git a/deploy/terraform/run/sap_deployer/transform.tf b/deploy/terraform/run/sap_deployer/transform.tf index 7e65b601e5..eadf3b5215 100644 --- a/deploy/terraform/run/sap_deployer/transform.tf +++ b/deploy/terraform/run/sap_deployer/transform.tf @@ -175,8 +175,6 @@ locals { ), "") } - plan = var.plan - private_ip_address = try(coalesce( var.deployer_private_ip_address, try(var.deployers[0].private_ip_address, "") diff --git a/deploy/terraform/run/sap_deployer/variables_local.tf b/deploy/terraform/run/sap_deployer/variables_local.tf index 6dbb79d863..879de6874d 100644 --- a/deploy/terraform/run/sap_deployer/variables_local.tf +++ b/deploy/terraform/run/sap_deployer/variables_local.tf @@ -36,10 +36,10 @@ locals { ) spn = { - subscription_id = length(var.deployer_kv_user_arm_id) > 0 && var.use_spn ? data.azurerm_key_vault_secret.subscription_id[0].value : null, - client_id = length(var.deployer_kv_user_arm_id) > 0 && var.use_spn ? data.azurerm_key_vault_secret.client_id[0].value : null, - client_secret = length(var.deployer_kv_user_arm_id) > 0 && var.use_spn ? data.azurerm_key_vault_secret.client_secret[0].value : null, - tenant_id = length(var.deployer_kv_user_arm_id) > 0 && var.use_spn ? data.azurerm_key_vault_secret.tenant_id[0].value : null + subscription_id = data.azurerm_key_vault_secret.subscription_id[0].value + client_id = var.use_spn ? data.azurerm_key_vault_secret.client_id[0].value : null, + client_secret = var.use_spn ? data.azurerm_key_vault_secret.client_secret[0].value : null, + tenant_id = var.use_spn ? data.azurerm_key_vault_secret.tenant_id[0].value : null } } diff --git a/deploy/terraform/run/sap_landscape/imports.tf b/deploy/terraform/run/sap_landscape/imports.tf index 6b2010c8f1..4d9ecfda1e 100644 --- a/deploy/terraform/run/sap_landscape/imports.tf +++ b/deploy/terraform/run/sap_landscape/imports.tf @@ -8,15 +8,15 @@ data "azurerm_client_config" "current" {} data "terraform_remote_state" "deployer" { backend = "azurerm" + count = length(try(var.deployer_tfstate_key, "")) > 0 ? 1 : 0 config = { resource_group_name = local.saplib_resource_group_name storage_account_name = local.tfstate_storage_account_name container_name = local.tfstate_container_name - key = var.deployer_tfstate_key + key = trimspace(var.deployer_tfstate_key) subscription_id = local.saplib_subscription_id - use_msi = var.use_spn ? false : true - use_azuread_auth = true + } } @@ -68,8 +68,7 @@ data "azurerm_key_vault_secret" "cp_tenant_id" { } // Import current service principal -data "azuread_service_principal" "sp" { - count = var.use_spn ? 1 : 0 - client_id = local.spn.client_id -} - +data "azuread_service_principal" "sp" { + count = var.use_spn ? 1 : 0 + client_id = local.spn.client_id + } diff --git a/deploy/terraform/run/sap_landscape/providers.tf b/deploy/terraform/run/sap_landscape/providers.tf index 563b3b20f7..97c78be65c 100644 --- a/deploy/terraform/run/sap_landscape/providers.tf +++ b/deploy/terraform/run/sap_landscape/providers.tf @@ -16,13 +16,14 @@ provider "azurerm" { features {} subscription_id = length(local.deployer_subscription_id) > 0 ? local.deployer_subscription_id : null use_msi = var.use_spn ? false : true + storage_use_azuread = true } provider "azurerm" { features { resource_group { - prevent_deletion_if_contains_resources = true + prevent_deletion_if_contains_resources = var.prevent_deletion_if_contains_resources } key_vault { purge_soft_delete_on_destroy = !var.enable_purge_control_for_keyvaults @@ -130,7 +131,7 @@ terraform { } azurerm = { source = "hashicorp/azurerm" - version = "4.4.0" + version = "4.7.0" } azapi = { source = "Azure/azapi" diff --git a/deploy/terraform/run/sap_landscape/tfvar_variables.tf b/deploy/terraform/run/sap_landscape/tfvar_variables.tf index a022608ca3..5e5c64bafd 100644 --- a/deploy/terraform/run/sap_landscape/tfvar_variables.tf +++ b/deploy/terraform/run/sap_landscape/tfvar_variables.tf @@ -33,6 +33,11 @@ variable "place_delete_lock_on_resources" { default = false } +variable "prevent_deletion_if_contains_resources" { + description = "Controls if resource groups are deleted even if they contain resources" + type = bool + default = true + } #######################################4#######################################8 # # # Resource group definitioms # diff --git a/deploy/terraform/run/sap_landscape/variables_local.tf b/deploy/terraform/run/sap_landscape/variables_local.tf index cc0e882808..af4562b762 100644 --- a/deploy/terraform/run/sap_landscape/variables_local.tf +++ b/deploy/terraform/run/sap_landscape/variables_local.tf @@ -22,17 +22,13 @@ locals { tfstate_container_name = module.sap_namegenerator.naming.resource_suffixes.tfstate // Retrieve the arm_id of deployer's Key Vault from deployer's terraform.tfstate - spn_key_vault_arm_id = try(local.key_vault.kv_spn_id, - try(data.terraform_remote_state.deployer[0].outputs.deployer_kv_user_arm_id, - "") - ) + spn_key_vault_arm_id = try(local.key_vault.kv_spn_id,data.terraform_remote_state.deployer[0].outputs.deployer_kv_user_arm_id) deployer_subscription_id = coalesce( try(data.terraform_remote_state.deployer[0].outputs.created_resource_group_subscription_id,""), - length(local.spn_key_vault_arm_id) > 0 ? ( - split("/", local.spn_key_vault_arm_id)[2]) : ( - "" - )) + length(local.spn_key_vault_arm_id) > 0 ? (split("/", local.spn_key_vault_arm_id)[2]) : (""), + local.saplib_subscription_id + ) spn = { subscription_id = data.azurerm_key_vault_secret.subscription_id.value, @@ -51,7 +47,7 @@ locals { service_principal = { subscription_id = local.spn.subscription_id, tenant_id = local.spn.tenant_id, - object_id = var.use_spn ? try(data.azuread_service_principal.sp[0].id, null) : null + object_id = var.use_spn ? data.azuread_service_principal.sp[0].object_id : null } account = { diff --git a/deploy/terraform/run/sap_library/imports.tf b/deploy/terraform/run/sap_library/imports.tf index 2c67219195..c601e7ea02 100644 --- a/deploy/terraform/run/sap_library/imports.tf +++ b/deploy/terraform/run/sap_library/imports.tf @@ -21,28 +21,28 @@ data "azurerm_key_vault_secret" "subscription_id" { provider = azurerm.deployer count = local.use_spn ? 1 : 0 name = format("%s-subscription-id", upper(local.infrastructure.environment)) - key_vault_id = local.spn_key_vault_arm_id + key_vault_id = local.key_vault.kv_spn_id } data "azurerm_key_vault_secret" "client_id" { provider = azurerm.deployer count = local.use_spn ? 1 : 0 name = format("%s-client-id", upper(local.infrastructure.environment)) - key_vault_id = local.spn_key_vault_arm_id + key_vault_id = local.key_vault.kv_spn_id } data "azurerm_key_vault_secret" "client_secret" { provider = azurerm.deployer count = local.use_spn ? 1 : 0 name = format("%s-client-secret", upper(local.infrastructure.environment)) - key_vault_id = local.spn_key_vault_arm_id + key_vault_id = local.key_vault.kv_spn_id } data "azurerm_key_vault_secret" "tenant_id" { provider = azurerm.deployer count = local.use_spn ? 1 : 0 name = format("%s-tenant-id", upper(local.infrastructure.environment)) - key_vault_id = local.spn_key_vault_arm_id + key_vault_id = local.key_vault.kv_spn_id } // Import current service principal diff --git a/deploy/terraform/run/sap_library/providers.tf b/deploy/terraform/run/sap_library/providers.tf index bb2c513d19..626394085c 100644 --- a/deploy/terraform/run/sap_library/providers.tf +++ b/deploy/terraform/run/sap_library/providers.tf @@ -49,8 +49,8 @@ provider "azurerm" { } alias = "deployer" storage_use_azuread = !var.shared_access_key_enabled - use_msi = var.use_spn ? false : true - + use_msi = true + subscription_id = local.saplib_subscription_id } provider "azurerm" { @@ -73,6 +73,7 @@ provider "azurerm" { tenant_id = local.use_spn ? local.spn.tenant_id : null alias = "privatelinkdnsmanagement" storage_use_azuread = true + use_msi = var.use_spn ? false : true } @@ -104,7 +105,7 @@ terraform { } azurerm = { source = "hashicorp/azurerm" - version = "4.4.0" + version = "4.7.0" } } } diff --git a/deploy/terraform/run/sap_library/tfvar_variables.tf b/deploy/terraform/run/sap_library/tfvar_variables.tf index 8627d877de..e0a4878a6a 100644 --- a/deploy/terraform/run/sap_library/tfvar_variables.tf +++ b/deploy/terraform/run/sap_library/tfvar_variables.tf @@ -328,3 +328,8 @@ variable "dns_label" { description = "DNS label" default = "" } + +variable "tags" { + description = "If provided, tags for all resources" + default = {} + } diff --git a/deploy/terraform/run/sap_library/transform.tf b/deploy/terraform/run/sap_library/transform.tf index ede51c324b..1e71d20b52 100644 --- a/deploy/terraform/run/sap_library/transform.tf +++ b/deploy/terraform/run/sap_library/transform.tf @@ -1,122 +1,63 @@ locals { infrastructure = { - environment = coalesce(var.environment, try(var.infrastructure.environment, "")) - region = coalesce(var.location, try(var.infrastructure.region, "")) - codename = try(var.codename, try(var.infrastructure.codename, "")) + environment = var.environment + region = var.location + codename = var.codename resource_group = { - name = try(coalesce(var.resourcegroup_name, try(var.infrastructure.resource_group.name, "")), "") - arm_id = try(coalesce(var.resourcegroup_arm_id, try(var.infrastructure.resource_group.arm_id, "")), "") + name = var.resourcegroup_name + arm_id = var.resourcegroup_arm_id } - tags = try(coalesce(var.resourcegroup_tags, try(var.infrastructure.tags, {})), {}) + tags = try(coalesce(var.resourcegroup_tags, var.tags, {}), {}) } deployer = { use = var.use_deployer } key_vault = { - kv_spn_id = try(coalesce(local.spn_key_vault_arm_id, var.spn_keyvault_id, try(var.key_vault.kv_spn_id, "")), "") + kv_spn_id = coalesce(var.spn_keyvault_id, local.spn_key_vault_arm_id) } storage_account_sapbits = { - arm_id = try(coalesce(var.library_sapmedia_arm_id, try(var.storage_account_sapbits.arm_id, "")), "") - name = var.library_sapmedia_name - account_tier = coalesce( - var.library_sapmedia_account_tier, - try(var.storage_account_sapbits.account_tier, "Standard") - ) - account_replication_type = coalesce( - var.library_sapmedia_account_replication_type, - try(var.storage_account_sapbits.account_replication_type, "ZRS") - ) - account_kind = coalesce( - var.library_sapmedia_account_kind, - try(var.storage_account_sapbits.account_kind, "StorageV2") - ) + arm_id = var.library_sapmedia_arm_id + name = var.library_sapmedia_name + account_tier = var.library_sapmedia_account_tier + account_replication_type = var.library_sapmedia_account_replication_type + account_kind = var.library_sapmedia_account_kind file_share = { - enable_deployment = ( - var.library_sapmedia_file_share_enable_deployment || - try(var.storage_account_sapbits.file_share.enable_deployment, true) - ) - is_existing = ( - var.library_sapmedia_file_share_is_existing || - try(var.storage_account_sapbits.file_share.is_existing, false) - ) - name = coalesce( - var.library_sapmedia_file_share_name, - try( - var.storage_account_sapbits.file_share.name, - module.sap_namegenerator.naming.resource_suffixes.sapbits - ) - ) + enable_deployment = var.library_sapmedia_file_share_enable_deployment + is_existing = var.library_sapmedia_file_share_is_existing + name = coalesce(var.library_sapmedia_file_share_name,module.sap_namegenerator.naming.resource_suffixes.sapbits) } sapbits_blob_container = { - enable_deployment = ( - var.library_sapmedia_blob_container_enable_deployment || - try(var.storage_account_sapbits.sapbits_blob_container.enable_deployment, true) - ) - is_existing = ( - var.library_sapmedia_blob_container_is_existing || - try(var.storage_account_sapbits.sapbits_blob_container.is_existing, false) - ) - name = coalesce( - var.library_sapmedia_blob_container_name, - try( - var.storage_account_sapbits.sapbits_blob_container.name, - module.sap_namegenerator.naming.resource_suffixes.sapbits - ) - ) + enable_deployment = var.library_sapmedia_blob_container_enable_deployment + is_existing = var.library_sapmedia_blob_container_is_existing + name = coalesce(var.library_sapmedia_blob_container_name, module.sap_namegenerator.naming.resource_suffixes.sapbits) } shared_access_key_enabled = var.shared_access_key_enabled public_network_access_enabled = var.public_network_access_enabled } storage_account_tfstate = { - arm_id = try( - coalesce( - var.library_terraform_state_arm_id, - try(var.storage_account_tfstate.arm_id, "")) - , "" - ) - name = var.library_terraform_state_name - account_tier = coalesce( - var.library_terraform_state_account_tier, - try(var.storage_account_tfstate.account_tier, "Standard") - ) - account_replication_type = coalesce( - var.library_terraform_state_account_replication_type, - try(var.storage_account_tfstate.account_replication_type, "ZRS") - ) - account_kind = coalesce( - var.library_terraform_state_account_kind, - try(var.storage_account_tfstate.account_kind, "StorageV2") - ) + arm_id = var.library_terraform_state_arm_id + name = var.library_terraform_state_name + account_tier = var.library_terraform_state_account_tier + account_replication_type = var.library_terraform_state_account_replication_type + account_kind = var.library_terraform_state_account_kind tfstate_blob_container = { - is_existing = ( - var.library_terraform_state_blob_container_is_existing || - try(var.storage_account_tfstate.tfstate_blob_container.is_existing, false) - ) - name = coalesce( - var.library_terraform_state_blob_container_name, - try(var.storage_account_tfstate.tfstate_blob_container.name, "tfstate") - ) + is_existing = var.library_terraform_state_blob_container_is_existing + name = var.library_terraform_state_blob_container_name } tfvars_blob_container = { - is_existing = var.library_terraform_vars_blob_container_is_existing - name = var.library_terraform_vars_blob_container_name + is_existing = var.library_terraform_vars_blob_container_is_existing + name = var.library_terraform_vars_blob_container_name } ansible_blob_container = { - is_existing = ( - var.library_ansible_blob_container_is_existing || - try(var.storage_account_tfstate.ansible_blob_container.is_existing, false) - ) - name = coalesce( - var.library_ansible_blob_container_name, - try(var.storage_account_tfstate.ansible_blob_container.name, "ansible") - ) + is_existing = var.library_ansible_blob_container_is_existing + name = var.library_ansible_blob_container_name } - shared_access_key_enabled = var.shared_access_key_enabled + shared_access_key_enabled = var.shared_access_key_enabled public_network_access_enabled = var.public_network_access_enabled } diff --git a/deploy/terraform/run/sap_library/variables_local.tf b/deploy/terraform/run/sap_library/variables_local.tf index 59798b8039..8360cf4301 100644 --- a/deploy/terraform/run/sap_library/variables_local.tf +++ b/deploy/terraform/run/sap_library/variables_local.tf @@ -31,7 +31,8 @@ locals { ) // Retrieve the arm_id of deployer's Key Vault from deployer's terraform.tfstate - spn_key_vault_arm_id = try(data.terraform_remote_state.deployer[0].outputs.deployer_kv_user_arm_id, "") + spn_key_vault_arm_id = try(data.terraform_remote_state.deployer[0].outputs.deployer_kv_user_arm_id, "") + spn = { subscription_id = local.use_spn ? data.azurerm_key_vault_secret.subscription_id[0].value : null, diff --git a/deploy/terraform/run/sap_system/module.tf b/deploy/terraform/run/sap_system/module.tf index 0a13d0c6d5..93094b8142 100644 --- a/deploy/terraform/run/sap_system/module.tf +++ b/deploy/terraform/run/sap_system/module.tf @@ -93,6 +93,7 @@ module "common_infrastructure" { use_random_id_for_storageaccounts = var.use_random_id_for_storageaccounts use_scalesets_for_deployment = var.use_scalesets_for_deployment dns_settings = local.dns_settings + enable_firewall_for_keyvaults_and_storage = var.enable_firewall_for_keyvaults_and_storage } #------------------------------------------------------------------------------- diff --git a/deploy/terraform/run/sap_system/providers.tf b/deploy/terraform/run/sap_system/providers.tf index f61497c0c7..48d9c77553 100644 --- a/deploy/terraform/run/sap_system/providers.tf +++ b/deploy/terraform/run/sap_system/providers.tf @@ -21,7 +21,7 @@ provider "azurerm" { provider "azurerm" { features { resource_group { - prevent_deletion_if_contains_resources = true + prevent_deletion_if_contains_resources = var.prevent_deletion_if_contains_resources } key_vault { purge_soft_delete_on_destroy = !var.enable_purge_control_for_keyvaults @@ -30,7 +30,6 @@ provider "azurerm" { purge_soft_deleted_certificates_on_destroy = !var.enable_purge_control_for_keyvaults } } - subscription_id = data.azurerm_key_vault_secret.subscription_id.value client_id = try(data.terraform_remote_state.landscape.outputs.use_spn, true) && var.use_spn ? local.spn.client_id : null client_secret = try(data.terraform_remote_state.landscape.outputs.use_spn, true) && var.use_spn ? local.spn.client_secret : null tenant_id = try(data.terraform_remote_state.landscape.outputs.use_spn, true) && var.use_spn ? local.spn.tenant_id : null @@ -99,7 +98,7 @@ terraform { } azurerm = { source = "hashicorp/azurerm" - version = "4.4.0" + version = "4.7.0" } } } diff --git a/deploy/terraform/run/sap_system/tfvar_variables.tf b/deploy/terraform/run/sap_system/tfvar_variables.tf index 3f2b7cab9b..1ce32a9252 100644 --- a/deploy/terraform/run/sap_system/tfvar_variables.tf +++ b/deploy/terraform/run/sap_system/tfvar_variables.tf @@ -61,7 +61,6 @@ variable "scaleset_id" { default = "" } - ######################################################################################### # # # Resource Group variables # @@ -83,6 +82,13 @@ variable "resourcegroup_tags" { default = {} } + +variable "prevent_deletion_if_contains_resources" { + description = "Controls if resource groups are deleted even if they contain resources" + type = bool + default = true + } + ######################################################################################### # # # Infrastructure variables # @@ -135,6 +141,11 @@ variable "shared_access_key_enabled_nfs" { type = bool } +variable "enable_firewall_for_keyvaults_and_storage" { + description = "Boolean value indicating if firewall should be enabled for key vaults and storage" + default = true + type = bool + } ######################################################################################### # # diff --git a/deploy/terraform/terraform-units/modules/sap_deployer/infrastructure.tf b/deploy/terraform/terraform-units/modules/sap_deployer/infrastructure.tf index 1f00c03ccc..82e2c28764 100644 --- a/deploy/terraform/terraform-units/modules/sap_deployer/infrastructure.tf +++ b/deploy/terraform/terraform-units/modules/sap_deployer/infrastructure.tf @@ -78,6 +78,7 @@ data "azurerm_subnet" "subnet_mgmt" { // Creates boot diagnostics storage account for Deployer resource "azurerm_storage_account" "deployer" { + depends_on = [ azurerm_subnet.subnet_mgmt ] count = length(var.deployer.deployer_diagnostics_account_arm_id) > 0 ? 0 : 1 name = local.storageaccount_names resource_group_name = local.resource_group_exists ? data.azurerm_resource_group.deployer[0].name : azurerm_resource_group.deployer[0].name @@ -88,12 +89,14 @@ resource "azurerm_storage_account" "deployer" { min_tls_version = "TLS1_2" allow_nested_items_to_be_public = false shared_access_key_enabled = var.deployer.shared_access_key_enabled - network_rules { - default_action = "Deny" - virtual_network_subnet_ids = [azurerm_subnet.subnet_mgmt[0].id] - } + cross_tenant_replication_enabled = false - depends_on = [ azurerm_subnet.subnet_mgmt ] + + network_rules { + default_action = var.enable_firewall_for_keyvaults_and_storage ? "Deny" : "Allow" + virtual_network_subnet_ids = var.use_service_endpoint ? [(local.management_subnet_exists) ? local.management_subnet_arm_id : azurerm_subnet.subnet_mgmt[0].id] : null + } + } data "azurerm_storage_account" "deployer" { @@ -103,6 +106,15 @@ data "azurerm_storage_account" "deployer" { } +resource "azurerm_role_assignment" "deployer" { + provider = azurerm.main + count = var.assign_subscription_permissions && var.deployer.add_system_assigned_identity ? var.deployer_vm_count : 0 + scope = length(var.deployer.deployer_diagnostics_account_arm_id) > 0 ? var.deployer.deployer_diagnostics_account_arm_id : azurerm_storage_account.deployer[0].id + role_definition_name = "Storage Blob Data Contributor" + principal_id = azurerm_linux_virtual_machine.deployer[count.index].identity[0].principal_id +} + + resource "azurerm_role_assignment" "resource_group_contributor" { provider = azurerm.main count = var.assign_subscription_permissions && var.deployer.add_system_assigned_identity ? var.deployer_vm_count : 0 diff --git a/deploy/terraform/terraform-units/modules/sap_deployer/providers.tf b/deploy/terraform/terraform-units/modules/sap_deployer/providers.tf index e64b177544..8465407ba0 100644 --- a/deploy/terraform/terraform-units/modules/sap_deployer/providers.tf +++ b/deploy/terraform/terraform-units/modules/sap_deployer/providers.tf @@ -3,7 +3,7 @@ terraform { azurerm = { source = "hashicorp/azurerm" configuration_aliases = [azurerm.dnsmanagement, azurerm.main] - version = "4.4.0" + version = "4.7.0" } } } diff --git a/deploy/terraform/terraform-units/modules/sap_deployer/templates/configure_deployer.sh.tmpl b/deploy/terraform/terraform-units/modules/sap_deployer/templates/configure_deployer.sh.tmpl index ead70e2bc2..cd0a5c6f5f 100644 --- a/deploy/terraform/terraform-units/modules/sap_deployer/templates/configure_deployer.sh.tmpl +++ b/deploy/terraform/terraform-units/modules/sap_deployer/templates/configure_deployer.sh.tmpl @@ -271,6 +271,7 @@ export AZADHOME="/home/$${local_user}" if [ -f /etc/profile.d/deploy_server.sh ] ; then echo echo ##vso[task.logissue type=warning]Deployer already configured + sudo chmod 775 /etc/profile.d/deploy_server.sh exit 0 else @@ -456,9 +457,12 @@ else "$${tf_bin}" \ "$${tf_cache}" - wget -nv -O "/tmp/$${tf_zip}" "https://releases.hashicorp.com/terraform/$${tfversion}/$${tf_zip}" - sudo unzip -o "/tmp/$${tf_zip}" -d "$${tf_dir}" + wget -nv -O "/$${asad_home}/$${tf_zip}" "https://releases.hashicorp.com/terraform/$${tfversion}/$${tf_zip}" + sudo unzip -qq -o "/$${asad_home}/$${tf_zip}" -d "$${tf_dir}" sudo ln -vfs "../$(basename "$${tf_dir}")/terraform" "$${tf_bin}/terraform" + sudo chmod 755 "$${tf_bin}/terraform" + + sudo rm "/$${asad_home}/$${tf_zip}" # Uninstall Azure CLI - For some platforms case "$(get_distro_name)" in @@ -758,14 +762,13 @@ else sudo touch "$${agent_home}/no_tok" fi - set -o xtrace if [ -f "$${agent_home}/agent_configured" ]; then echo "Agent already configured" else - set +o xtrace if [[ -n "$${TOKEN}" ]]; then + echo "Configuring Agent" sudo chmod -R 744 "$${agent_home}" - set -o xtrace + cd "$${agent_home}" ./env.sh @@ -775,6 +778,9 @@ else (echo "$${agent_home}/config.sh" --unattended --url "$${DEVURL}" --auth pat --token "$${TOKEN}" --pool "$${POOL}" --agent "$${AGENTNAME}" --replace --acceptTeeEula | sudo tee -a "$${agent_home}/config_fixed_params.sh") > /dev/null 2>&1 sudo chmod +x "$${agent_home}/config_fixed_params.sh" + sudo chown "$${local_user}" "$${agent_home}/config_fixed_params.sh" + + echo "Installing Agent" sudo runuser -l "$${local_user}" -c "$${agent_home}/config_fixed_params.sh" | sudo tee -a "$${agent_home}/log.txt" @@ -790,6 +796,7 @@ else sudo touch "$${agent_home}/agent_configured" echo export "PATH=$${ansible_bin}:$${tf_bin}:"'$${PATH}'::"$${DOTNET_ROOT}" | sudo tee -a /etc/profile.d/deploy_server.sh + sudo chmod 775 /etc/profile.d/deploy_server.sh # Install dotNet case "$(get_distro_name)" in (ubuntu) @@ -813,10 +820,12 @@ else else echo "NO TOKEN specified" echo export "PATH=$${ansible_bin}:$${tf_bin}:"'$${PATH}'::"$${DOTNET_ROOT}":'$${AZADHOME}/Azure_SAP_Automated_Deployment/sap-automation/deploy/scripts' | sudo tee -a /etc/profile.d/deploy_server.sh + sudo chmod 775 /etc/profile.d/deploy_server.sh echo "export SAP_AUTOMATION_REPO_PATH='$${AZADHOME}/Azure_SAP_Automated_Deployment/sap-automation'" | sudo tee -a /etc/profile.d/deploy_server.sh echo "export DEPLOYMENT_REPO_PATH='$${AZADHOME}/Azure_SAP_Automated_Deployment/sap-automation'" | sudo tee -a /etc/profile.d/deploy_server.sh echo "export CONFIG_REPO_PATH='$${AZADHOME}/Azure_SAP_Automated_Deployment/WORKSPACES'" | sudo tee -a /etc/profile.d/deploy_server.sh fi fi + fi diff --git a/deploy/terraform/terraform-units/modules/sap_deployer/vm-deployer.tf b/deploy/terraform/terraform-units/modules/sap_deployer/vm-deployer.tf index 9cfb588d7b..b99a2749b0 100644 --- a/deploy/terraform/terraform-units/modules/sap_deployer/vm-deployer.tf +++ b/deploy/terraform/terraform-units/modules/sap_deployer/vm-deployer.tf @@ -156,13 +156,12 @@ resource "azurerm_linux_virtual_machine" "deployer" { version = var.deployer.os.version } } - dynamic "plan" { for_each = range(var.deployer.os.type == "marketplace_with_plan" ? 1 : 0) content { - name = var.deployer.plan.name - publisher = var.deployer.plan.publisher - product = var.deployer.plan.product + name = var.deployer.os.sku + publisher = var.deployer.os.publisher + product = var.deployer.os.offer } } diff --git a/deploy/terraform/terraform-units/modules/sap_landscape/key_vault_sap_landscape.tf b/deploy/terraform/terraform-units/modules/sap_landscape/key_vault_sap_landscape.tf index 1d2288a86a..7fe898cfaf 100644 --- a/deploy/terraform/terraform-units/modules/sap_landscape/key_vault_sap_landscape.tf +++ b/deploy/terraform/terraform-units/modules/sap_landscape/key_vault_sap_landscape.tf @@ -1,3 +1,6 @@ +data "azuread_client_config" "current" {} + + #######################################4#######################################8 # # # Workload zone key vault # @@ -32,7 +35,7 @@ resource "azurerm_key_vault" "kv_user" { content { bypass = "AzureServices" - default_action = local.management_subnet_exists ? "Deny" : "Allow" + default_action = var.enable_firewall_for_keyvaults_and_storage ? "Deny" : "Allow" ip_rules = compact( [ @@ -85,7 +88,7 @@ resource "azurerm_role_assignment" "role_assignment_msi" { resource "azurerm_role_assignment" "role_assignment_spn" { provider = azurerm.main - count = var.enable_rbac_authorization_for_keyvault && local.service_principal.object_id != "" ? 1 : 0 + count = var.enable_rbac_authorization_for_keyvault && local.service_principal.object_id != "" && !var.options.use_spn ? 1 : 0 scope = local.user_keyvault_exist ? ( local.user_key_vault_id) : ( azurerm_key_vault.kv_user[0].id @@ -95,14 +98,29 @@ resource "azurerm_role_assignment" "role_assignment_spn" { } resource "azurerm_key_vault_access_policy" "kv_user" { - provider = azurerm.main - count = (var.key_vault.exists || var.enable_rbac_authorization_for_keyvault) ? ( - 0) : ( - (length(var.deployer_tfstate) > 0 ? var.deployer_tfstate.deployer_uai.principal_id == local.service_principal.object_id : false) ? 0 : 1 - ) + provider = azurerm.deployer + count = 0 key_vault_id = local.user_keyvault_exist ? local.user_key_vault_id : azurerm_key_vault.kv_user[0].id tenant_id = local.service_principal.tenant_id - object_id = local.service_principal.object_id != "" ? local.service_principal.object_id : "00000000-0000-0000-0000-000000000000" + object_id = var.deployer_tfstate.deployer_uai.principal_id + + secret_permissions = [ + "Get", + "List", + "Set", + "Delete", + "Recover", + "Restore", + "Purge" + ] +} + +resource "azurerm_key_vault_access_policy" "kv_user_spn" { + provider = azurerm.main + count = var.options.use_spn ? 1 : 0 + key_vault_id = local.user_keyvault_exist ? local.user_key_vault_id : azurerm_key_vault.kv_user[0].id + tenant_id = data.azuread_client_config.current.tenant_id + object_id = data.azuread_client_config.current.object_id secret_permissions = [ "Get", @@ -115,6 +133,7 @@ resource "azurerm_key_vault_access_policy" "kv_user" { ] } + ############################################################################### # # # Secrets # @@ -148,7 +167,8 @@ resource "azurerm_key_vault_secret" "sid_ppk" { azurerm_key_vault_access_policy.kv_user, azurerm_role_assignment.role_assignment_spn, azurerm_role_assignment.role_assignment_msi, - azurerm_key_vault_access_policy.kv_user_msi + azurerm_key_vault_access_policy.kv_user_msi, + azurerm_key_vault_access_policy.kv_user_spn ] content_type = "" name = local.sid_ppk_name @@ -174,7 +194,8 @@ resource "azurerm_key_vault_secret" "sid_pk" { azurerm_key_vault_access_policy.kv_user, azurerm_role_assignment.role_assignment_spn, azurerm_role_assignment.role_assignment_msi, - azurerm_key_vault_access_policy.kv_user_msi + azurerm_key_vault_access_policy.kv_user_msi, + azurerm_key_vault_access_policy.kv_user_spn ] content_type = "" name = local.sid_pk_name @@ -205,7 +226,8 @@ resource "azurerm_key_vault_secret" "sid_username" { azurerm_key_vault_access_policy.kv_user, azurerm_role_assignment.role_assignment_spn, azurerm_role_assignment.role_assignment_msi, - azurerm_key_vault_access_policy.kv_user_msi + azurerm_key_vault_access_policy.kv_user_msi, + azurerm_key_vault_access_policy.kv_user_spn ] content_type = "" name = local.sid_username_secret_name @@ -234,7 +256,8 @@ resource "azurerm_key_vault_secret" "sid_password" { azurerm_key_vault_access_policy.kv_user, azurerm_role_assignment.role_assignment_spn, azurerm_role_assignment.role_assignment_msi, - azurerm_key_vault_access_policy.kv_user_msi + azurerm_key_vault_access_policy.kv_user_msi, + azurerm_key_vault_access_policy.kv_user_spn ] name = local.sid_password_secret_name content_type = "" @@ -265,7 +288,8 @@ resource "azurerm_key_vault_secret" "witness_access_key" { azurerm_key_vault_access_policy.kv_user, azurerm_role_assignment.role_assignment_spn, azurerm_role_assignment.role_assignment_msi, - azurerm_key_vault_access_policy.kv_user_msi + azurerm_key_vault_access_policy.kv_user_msi, + azurerm_key_vault_access_policy.kv_user_spn ] content_type = "" name = replace( @@ -302,7 +326,8 @@ resource "azurerm_key_vault_secret" "witness_name" { azurerm_key_vault_access_policy.kv_user, azurerm_role_assignment.role_assignment_spn, azurerm_role_assignment.role_assignment_msi, - azurerm_key_vault_access_policy.kv_user_msi + azurerm_key_vault_access_policy.kv_user_msi, + azurerm_key_vault_access_policy.kv_user_spn ] content_type = "" name = replace( @@ -369,7 +394,8 @@ resource "azurerm_key_vault_secret" "deployer_keyvault_user_name" { azurerm_key_vault_access_policy.kv_user, azurerm_role_assignment.role_assignment_spn, azurerm_role_assignment.role_assignment_msi, - azurerm_key_vault_access_policy.kv_user_msi + azurerm_key_vault_access_policy.kv_user_msi, + azurerm_key_vault_access_policy.kv_user_spn ] content_type = "" name = "deployer-kv-name" diff --git a/deploy/terraform/terraform-units/modules/sap_landscape/providers.tf b/deploy/terraform/terraform-units/modules/sap_landscape/providers.tf index 3704a96e56..7b2823c258 100644 --- a/deploy/terraform/terraform-units/modules/sap_landscape/providers.tf +++ b/deploy/terraform/terraform-units/modules/sap_landscape/providers.tf @@ -3,7 +3,7 @@ terraform { azurerm = { source = "hashicorp/azurerm" configuration_aliases = [azurerm.main, azurerm.deployer, azurerm.dnsmanagement, azurerm.peering, azurerm.privatelinkdnsmanagement] - version = "4.4.0" + version = "4.7.0" } azapi = { diff --git a/deploy/terraform/terraform-units/modules/sap_landscape/storage_accounts.tf b/deploy/terraform/terraform-units/modules/sap_landscape/storage_accounts.tf index cd14c2e1b0..cd5a28f734 100644 --- a/deploy/terraform/terraform-units/modules/sap_landscape/storage_accounts.tf +++ b/deploy/terraform/terraform-units/modules/sap_landscape/storage_accounts.tf @@ -326,7 +326,7 @@ resource "azurerm_storage_account" "transport" { resource "azurerm_private_dns_a_record" "transport" { provider = azurerm.privatelinkdnsmanagement - count = var.create_transport_storage && local.use_Azure_native_DNS && local.use_AFS_for_shared && length(var.transport_private_endpoint_id) == 0 ? 1 : 0 + count = var.use_private_endpoint && var.create_transport_storage && local.use_Azure_native_DNS && local.use_AFS_for_shared && length(var.transport_private_endpoint_id) == 0 ? 1 : 0 name = replace( lower( format("%s", local.landscape_shared_transport_storage_account_name) @@ -525,7 +525,7 @@ resource "azurerm_storage_account" "install" { resource "azurerm_storage_account_network_rules" "install" { provider = azurerm.main - count = local.use_AFS_for_shared && length(var.install_storage_account_id) == 0 ? 1 : 0 + count = local.use_AFS_for_shared && var.enable_firewall_for_keyvaults_and_storage && length(var.install_storage_account_id) == 0 ? 1 : 0 depends_on = [ azurerm_storage_account.install, azurerm_storage_share.install, diff --git a/deploy/terraform/terraform-units/modules/sap_library/key_vault.tf b/deploy/terraform/terraform-units/modules/sap_library/key_vault.tf index 4fbfa3c789..3c3986ec92 100644 --- a/deploy/terraform/terraform-units/modules/sap_library/key_vault.tf +++ b/deploy/terraform/terraform-units/modules/sap_library/key_vault.tf @@ -82,7 +82,7 @@ resource "azurerm_key_vault_secret" "tfstate" { resource "azurerm_private_dns_a_record" "kv_user" { - provider = azurerm.deployer + provider = azurerm.privatelinkdnsmanagement count = var.dns_settings.register_storage_accounts_keyvaults_with_dns ? 1 : 0 name = lower(split("/", var.key_vault.kv_spn_id)[8]) zone_name = var.dns_settings.dns_zone_names.vault_dns_zone_name diff --git a/deploy/terraform/terraform-units/modules/sap_library/providers.tf b/deploy/terraform/terraform-units/modules/sap_library/providers.tf index fb48736d38..abc505c57f 100644 --- a/deploy/terraform/terraform-units/modules/sap_library/providers.tf +++ b/deploy/terraform/terraform-units/modules/sap_library/providers.tf @@ -3,7 +3,7 @@ terraform { azurerm = { source = "hashicorp/azurerm" configuration_aliases = [azurerm.main, azurerm.deployer, azurerm.dnsmanagement, azurerm.privatelinkdnsmanagement] - version = "4.4.0" + version = "4.7.0" } } } diff --git a/deploy/terraform/terraform-units/modules/sap_library/storage_accounts.tf b/deploy/terraform/terraform-units/modules/sap_library/storage_accounts.tf index 0f87cbcaa8..ae12c5ed4f 100644 --- a/deploy/terraform/terraform-units/modules/sap_library/storage_accounts.tf +++ b/deploy/terraform/terraform-units/modules/sap_library/storage_accounts.tf @@ -105,7 +105,7 @@ resource "azurerm_role_assignment" "storage_tfstate_contributor_ssi" { } resource "azurerm_private_dns_a_record" "storage_tfstate_pep_a_record_registry" { - provider = azurerm.dnsmanagement + provider = azurerm.privatelinkdnsmanagement count = var.dns_settings.register_storage_accounts_keyvaults_with_dns && var.use_private_endpoint && var.use_custom_dns_a_registration && !local.sa_tfstate_exists ? 1 : 0 depends_on = [ azurerm_private_dns_zone.blob @@ -218,7 +218,7 @@ resource "azurerm_private_endpoint" "table_tfstate" { subnet_id = var.deployer_tfstate.subnet_mgmt_id - custom_network_interface_name = var.short_named_endpoints_nics ? format("%s%s%s%s", + custom_network_interface_name = var.short_named_endpoints_nics ? format("%s%s%st%s", var.naming.resource_prefixes.storage_private_link_tf, length(local.prefix) > 0 ? ( local.prefix) : ( @@ -343,7 +343,7 @@ resource "azurerm_storage_account_network_rules" "storage_sapbits" { resource "azurerm_private_dns_a_record" "storage_sapbits_pep_a_record_registry" { - provider = azurerm.dnsmanagement + provider = azurerm.privatelinkdnsmanagement count = var.use_private_endpoint && var.use_custom_dns_a_registration && !local.sa_sapbits_exists ? 1 : 0 depends_on = [ azurerm_private_dns_zone.blob @@ -476,7 +476,7 @@ resource "azurerm_role_assignment" "storage_sapbits_contributor" { provider = azurerm.main count = try(var.deployer_tfstate.deployer_uai.principal_id, "") != "" ? 1 : 0 scope = local.sa_sapbits_exists ? var.storage_account_sapbits.arm_id : azurerm_storage_account.storage_sapbits[0].id - role_definition_name = "Storage Account Contributor" + role_definition_name = "Storage Blob Data Contributor" principal_id = var.deployer_tfstate.deployer_uai.principal_id } @@ -484,7 +484,7 @@ resource "azurerm_role_assignment" "storage_sapbits_contributor_ssi" { provider = azurerm.main count = try(var.deployer_tfstate.add_system_assigned_identity, false) ? length(var.deployer_tfstate.deployer_system_assigned_identity) : 0 scope = local.sa_sapbits_exists ? var.storage_account_sapbits.arm_id : azurerm_storage_account.storage_sapbits[0].id - role_definition_name = "Storage Account Contributor" + role_definition_name = "Storage Blob Data Contributor" principal_id = var.deployer_tfstate.deployer_system_assigned_identity[count.index] } diff --git a/deploy/terraform/terraform-units/modules/sap_system/anydb_node/providers.tf b/deploy/terraform/terraform-units/modules/sap_system/anydb_node/providers.tf index 31e19ce0d8..d561a557b6 100644 --- a/deploy/terraform/terraform-units/modules/sap_system/anydb_node/providers.tf +++ b/deploy/terraform/terraform-units/modules/sap_system/anydb_node/providers.tf @@ -3,7 +3,7 @@ terraform { azurerm = { source = "hashicorp/azurerm" configuration_aliases = [azurerm.main, azurerm.deployer, azurerm.dnsmanagement, azurerm.privatelinkdnsmanagement] // - version = "4.4.0" + version = "4.7.0" } } } diff --git a/deploy/terraform/terraform-units/modules/sap_system/app_tier/providers.tf b/deploy/terraform/terraform-units/modules/sap_system/app_tier/providers.tf index 31e19ce0d8..d561a557b6 100644 --- a/deploy/terraform/terraform-units/modules/sap_system/app_tier/providers.tf +++ b/deploy/terraform/terraform-units/modules/sap_system/app_tier/providers.tf @@ -3,7 +3,7 @@ terraform { azurerm = { source = "hashicorp/azurerm" configuration_aliases = [azurerm.main, azurerm.deployer, azurerm.dnsmanagement, azurerm.privatelinkdnsmanagement] // - version = "4.4.0" + version = "4.7.0" } } } diff --git a/deploy/terraform/terraform-units/modules/sap_system/common_infrastructure/providers.tf b/deploy/terraform/terraform-units/modules/sap_system/common_infrastructure/providers.tf index 31e19ce0d8..d561a557b6 100644 --- a/deploy/terraform/terraform-units/modules/sap_system/common_infrastructure/providers.tf +++ b/deploy/terraform/terraform-units/modules/sap_system/common_infrastructure/providers.tf @@ -3,7 +3,7 @@ terraform { azurerm = { source = "hashicorp/azurerm" configuration_aliases = [azurerm.main, azurerm.deployer, azurerm.dnsmanagement, azurerm.privatelinkdnsmanagement] // - version = "4.4.0" + version = "4.7.0" } } } diff --git a/deploy/terraform/terraform-units/modules/sap_system/common_infrastructure/storage_accounts.tf b/deploy/terraform/terraform-units/modules/sap_system/common_infrastructure/storage_accounts.tf index 4785530e08..bab63ad0a1 100644 --- a/deploy/terraform/terraform-units/modules/sap_system/common_infrastructure/storage_accounts.tf +++ b/deploy/terraform/terraform-units/modules/sap_system/common_infrastructure/storage_accounts.tf @@ -44,23 +44,28 @@ resource "azurerm_storage_account" "sapmnt" { public_network_access_enabled = try(var.landscape_tfstate.public_network_access_enabled, true) tags = var.tags - network_rules { - default_action = "Deny" - virtual_network_subnet_ids = compact( - [ - try(var.landscape_tfstate.admin_subnet_id, ""), - try(var.landscape_tfstate.app_subnet_id, ""), - try(var.landscape_tfstate.db_subnet_id, ""), - try(var.landscape_tfstate.web_subnet_id, ""), - try(var.landscape_tfstate.subnet_mgmt_id, "") - ] - ) - ip_rules = compact( - [ - length(var.Agent_IP) > 0 ? var.Agent_IP : "" - ] - ) - } + dynamic "network_rules" { + for_each = range(var.enable_firewall_for_keyvaults_and_storage ? 1 : 0) + content { + + default_action = var.enable_firewall_for_keyvaults_and_storage ? "Deny" : "Allow" + virtual_network_subnet_ids = compact( + [ + try(var.landscape_tfstate.admin_subnet_id, ""), + try(var.landscape_tfstate.app_subnet_id, ""), + try(var.landscape_tfstate.db_subnet_id, ""), + try(var.landscape_tfstate.web_subnet_id, ""), + try(var.landscape_tfstate.subnet_mgmt_id, "") + ] + ) + ip_rules = compact( + [ + length(var.Agent_IP) > 0 ? var.Agent_IP : "" + ] + ) + + } + } } diff --git a/deploy/terraform/terraform-units/modules/sap_system/common_infrastructure/variables_global.tf b/deploy/terraform/terraform-units/modules/sap_system/common_infrastructure/variables_global.tf index 922e45fa16..e1cc5e4826 100644 --- a/deploy/terraform/terraform-units/modules/sap_system/common_infrastructure/variables_global.tf +++ b/deploy/terraform/terraform-units/modules/sap_system/common_infrastructure/variables_global.tf @@ -216,6 +216,10 @@ variable "use_private_endpoint" { default = false type = bool } +variable "enable_firewall_for_keyvaults_and_storage" { + description = "Boolean value indicating if firewall should be enabled for key vaults and storage" + type = bool + } ######################################################################################### # # diff --git a/deploy/terraform/terraform-units/modules/sap_system/hdb_node/providers.tf b/deploy/terraform/terraform-units/modules/sap_system/hdb_node/providers.tf index 48bf4b3735..d576abf342 100644 --- a/deploy/terraform/terraform-units/modules/sap_system/hdb_node/providers.tf +++ b/deploy/terraform/terraform-units/modules/sap_system/hdb_node/providers.tf @@ -3,7 +3,7 @@ terraform { azurerm = { source = "hashicorp/azurerm" configuration_aliases = [azurerm.main, azurerm.deployer, azurerm.dnsmanagement, azurerm.privatelinkdnsmanagement] - version = "4.4.0" + version = "4.7.0" } # azapi = { diff --git a/deploy/terraform/terraform-units/modules/sap_system/output_files/providers.tf b/deploy/terraform/terraform-units/modules/sap_system/output_files/providers.tf index abc9ae403b..693a1266ce 100644 --- a/deploy/terraform/terraform-units/modules/sap_system/output_files/providers.tf +++ b/deploy/terraform/terraform-units/modules/sap_system/output_files/providers.tf @@ -3,7 +3,7 @@ terraform { azurerm = { source = "hashicorp/azurerm" configuration_aliases = [azurerm.main, azurerm.dnsmanagement] - version = "4.4.0" + version = "4.7.0" } } }