diff --git a/.github/workflows/ansible-lint-sap_vm_provision.yml b/.github/workflows/ansible-lint-sap_vm_provision.yml index da65490..10b8e85 100644 --- a/.github/workflows/ansible-lint-sap_vm_provision.yml +++ b/.github/workflows/ansible-lint-sap_vm_provision.yml @@ -41,6 +41,9 @@ jobs: pip3 install ansible-lint==6.22.1 pip3 install jmespath==1.0.1 + - name: Install dependencies for Ansible + run: ansible-galaxy collection install -r /home/runner/work/community.sap_infrastructure/community.sap_infrastructure/requirements.yml + - name: Run ansible-lint working-directory: /home/runner/work/community.sap_infrastructure/community.sap_infrastructure/roles/sap_vm_provision run: ansible-lint diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e60c7a4..2d71d8d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,36 @@ community.sap_infrastructure Release Notes .. contents:: Topics +v1.0.1 +====== + +Release Summary +--------------- + +| Release Date: 2024-04-29 +| collection: Bug fix for GH Action requirements +| collection: Bug fix for Ansible Collection dependencies +| sap_hypervisor_node_preconfigure: Bug fix for when condition typo and trident version update +| sap_vm_provision: Documentation update for AWS IAM +| sap_vm_provision: Documentation update for design assumptions with execution impact +| sap_vm_provision: Feature add for all to ensure short hostname is not longer than 13 characters (SAP Note 611361) +| sap_vm_provision: Feature add for all internal variable names prefix with __sap_vm_provision_ +| sap_vm_provision: Feature add for all with rescue block to output errors without revealing credential secrets +| sap_vm_provision: Feature add for SAP HANA Scale-Out user-defined variable name prefix with sap_vm_provision +| sap_vm_provision: Feature add for all Ansible Tasks calling Infrastructure Platform APIs default to no_log instead of Environment +| sap_vm_provision: Feature add sample Ansible Playbook for blank Virtual Machine provision +| sap_vm_provision: Feature add for MS Azure SSH Key Pair from new dependency Ansible Module +| sap_vm_provision: Feature add for MS Azure and IBM Cloud Private DNS in separate Resource Group +| sap_vm_provision: Feature add for all Cloud vendors with updated regex for OS Image releases +| sap_vm_provision: Feature add for IBM Power VS using newer hardware machine type (Power10) +| sap_vm_provision: Bug fix for OS Package Repository registration task not triggering +| sap_vm_provision: Bug fix for Web Forward Proxy task not triggering +| sap_vm_provision: Bug fix for ignoring undefined variables (e.g. sap_id_user_password) set on hosts +| sap_vm_provision: Bug fix for IBM Power VS using Power Edge Router default instead of legacy cloud connections +| sap_vm_provision: Bug fix for IBM Power VS OS Image clone from stock and provision +| sap_vm_provision: Bug fix for MS Azure Virtual Machine info response changed data path for IP Address migrating from 1.x to 2.x Ansible Collection +| sap_vm_provision: Bug fix for MS Azure Virtual Machine vm_identity syntax changed migrating from 1.x to 2.x Ansible Collection + v1.0.0 ====== diff --git a/galaxy.yml b/galaxy.yml index 7eb8551..afa47b1 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -10,7 +10,7 @@ namespace: community name: sap_infrastructure # The version of the collection. Must be compatible with semantic versioning -version: 1.0.0 +version: 1.0.1 # The path to the Markdown (.md) readme file. This path is relative to the root of the collection readme: README.md diff --git a/playbooks/sample-sap-vm-provision-aws-ec2-vs.yml b/playbooks/sample-sap-vm-provision-aws-ec2-vs.yml new file mode 100644 index 0000000..f060346 --- /dev/null +++ b/playbooks/sample-sap-vm-provision-aws-ec2-vs.yml @@ -0,0 +1,39 @@ +--- + +# This sample Ansible Playbook is not a full example, +# which would pass additional variables onto other +# Ansible Roles such as sap_storage_setup. +# It is only to test the provisioning process +# of a small Virtual Machine. + +- name: Ansible Play to include_vars + hosts: all + become: true + pre_tasks: + + # Alternative to executing ansible-playbook with -e for Ansible Extravars file + - name: Include sample variables for AWS EC2 + ansible.builtin.include_vars: ./vars/sample-variables-sap-vm-provision-aws-ec2-vs.yml + + +- name: Ansible Play to create dynamic inventory group for provisioning + hosts: localhost + gather_facts: false + tasks: + + - name: Create dynamic inventory group for Ansible Role sap_vm_provision + ansible.builtin.add_host: + name: "{{ item }}" + group: sap_vm_provision_target_inventory_group + loop: "{{ sap_vm_provision_ibmcloud_vs_host_specifications_dictionary[sap_vm_provision_host_specification_plan].keys() }}" + + +- name: Ansible Play to provision hosts for SAP + hosts: sap_vm_provision_target_inventory_group # Ansible Play target hosts pattern, use Inventory Group created by previous Ansible Task (add_host) + gather_facts: false + tasks: + + - name: Execute Ansible Role sap_vm_provision + ansible.builtin.include_role: + name: community.sap_infrastructure.sap_vm_provision + when: sap_vm_provision_iac_type == "ansible" or sap_vm_provision_iac_type == "ansible_to_terraform" diff --git a/playbooks/vars/sample-variables-sap-vm-provision-aws-ec2-vs.yml b/playbooks/vars/sample-variables-sap-vm-provision-aws-ec2-vs.yml new file mode 100644 index 0000000..a9752de --- /dev/null +++ b/playbooks/vars/sample-variables-sap-vm-provision-aws-ec2-vs.yml @@ -0,0 +1,70 @@ +--- + +# This sample Ansible Playbook is not a full example, +# which would pass additional variables onto other +# Ansible Roles such as sap_storage_setup. +# It is only to test the provisioning process +# of a small Virtual Machine. + +#### +# Infrastructure Provisioning selection +#### + +sap_vm_provision_iac_type: "ansible" # ansible , ansible_to_terraform , existing_hosts +sap_vm_provision_iac_platform: "aws_ec2_vs" # aws_ec2_vs , gcp_ce_vm , ibmcloud_vs , ibmcloud_powervs , msazure_vm , ibmpowervm_vm , kubevirt_vm , ovirt_vm , vmware_vm + +sap_vm_provision_host_specification_plan: "test_plan_16gb" +sap_vm_provision_dns_root_domain: "poc.cloud" + + +#### +# Infrastructure Provisioning selection +# AWS +# +# Only for use when 'aws_ec2_vs' is value provided for variable sap_vm_provision_iac_platform +#### + +sap_vm_provision_aws_access_key: "ENTER_STRING_VALUE_HERE" +sap_vm_provision_aws_secret_access_key: "ENTER_STRING_VALUE_HERE" +sap_vm_provision_aws_region: "{{ sap_vm_provision_aws_vpc_availability_zone[:-1] }}" +sap_vm_provision_aws_vpc_availability_zone: "eu-west-2c" +sap_vm_provision_aws_vpc_subnet_create_boolean: "{{ true | default(false) if aws_vpc_subnet_id == 'new' else false }}" +sap_vm_provision_aws_vpc_subnet_id: "ENTER_STRING_VALUE_HERE" # if ansible_to_terraform, use "new" +sap_vm_provision_aws_ec2_vs_host_os_image: "ENTER_STRING_VALUE_HERE" +sap_vm_provision_bastion_user: "ENTER_STRING_VALUE_HERE" +sap_vm_provision_bastion_ssh_port: "ENTER_STRING_VALUE_HERE" + +# Only for use when 'ansible' is value provided for variable sap_vm_provision_iac_type +#### +sap_vm_provision_bastion_public_ip: "ENTER_STRING_VALUE_HERE" +sap_vm_provision_ssh_bastion_private_key_file_path: "./bastion_rsa" +sap_vm_provision_ssh_host_private_key_file_path: "./hosts_rsa" +sap_vm_provision_aws_key_pair_name_ssh_host_public_key: "ENTER_STRING_VALUE_HERE" +sap_vm_provision_aws_vpc_sg_names: "ENTER_STRING_VALUE_HERE" + + +#### +# Infrastructure Definitions +# AWS +#### + +sap_vm_provision_aws_ec2_vs_host_os_image_dictionary: + rhel-8-6: "*RHEL-8.6*_HVM*x86_64*" + rhel-8-6-sap-ha: "*RHEL-SAP-8.6.0*" + sles-15-4: "*suse-sles-15-sp4-v202*-hvm-ssd-x86_64*" + sles-15-4-sap-ha: "*suse-sles-sap-15-sp4-v202*-hvm-ssd-x86_64*" + +sap_vm_provision_aws_ec2_vs_host_specifications_dictionary: + test_plan_16gb: + test-ec2-vs: # Hostname, must be 13 characters or less + sap_host_type: hana_primary # hana_primary, hana_secondary, nwas_ascs, nwas_ers, nwas_pas, nwas_aas + virtual_machine_profile: r7i.large + disable_ip_anti_spoofing: true + storage_definition: + - name: hana_data + mountpoint: /hana/data + #disk_count: 1 # default: 1, if more then then LVM logical volume will be striped across the defined disks + disk_size: 384 # size in GB, integer + #disk_type: gp3 # default: gp3, for AWS EBS disk type + #disk_iops: # default: null, for AWS EBS with custom IOPS + filesystem_type: xfs # default: xfs diff --git a/requirements.yml b/requirements.yml index abeb348..03131ca 100644 --- a/requirements.yml +++ b/requirements.yml @@ -6,13 +6,13 @@ collections: version: 1.1.0 - name: amazon.aws type: galaxy - version: 5.4.0 + version: 7.2.0 - name: community.aws type: galaxy - version: 5.4.0 + version: 7.1.0 - name: azure.azcollection type: galaxy - version: 1.15.0 + version: 2.2.0 - name: google.cloud type: galaxy version: 1.1.3 diff --git a/roles/sap_hypervisor_node_preconfigure/tasks/platform/redhat_ocp_virt/main.yml b/roles/sap_hypervisor_node_preconfigure/tasks/platform/redhat_ocp_virt/main.yml index a3dec29..89b67c9 100644 --- a/roles/sap_hypervisor_node_preconfigure/tasks/platform/redhat_ocp_virt/main.yml +++ b/roles/sap_hypervisor_node_preconfigure/tasks/platform/redhat_ocp_virt/main.yml @@ -83,7 +83,7 @@ - name: Include setup worker nodes ansible.builtin.include_tasks: "platform/{{ sap_hypervisor_node_platform }}/setup-worker-nodes.yml" - when: sap_hypervisor_node_preconfigure_setup_workers + when: sap_hypervisor_node_preconfigure_setup_worker_nodes # How to wait for node to be scheduleable? (NodeSchedulable) - name: Wait for all k8s nodes to be ready diff --git a/roles/sap_hypervisor_node_preconfigure/vars/platform_defaults_redhat_ocp_virt.yml b/roles/sap_hypervisor_node_preconfigure/vars/platform_defaults_redhat_ocp_virt.yml index 6bfd827..0d1fedf 100644 --- a/roles/sap_hypervisor_node_preconfigure/vars/platform_defaults_redhat_ocp_virt.yml +++ b/roles/sap_hypervisor_node_preconfigure/vars/platform_defaults_redhat_ocp_virt.yml @@ -9,7 +9,7 @@ sap_hypervisor_node_preconfigure_install_hpp: false sap_hypervisor_node_preconfigure_install_trident: false # URL of the trident installer package to use -sap_hypervisor_node_preconfigure_install_trident_url: https://github.com/NetApp/trident/releases/download/v23.01.0/trident-installer-23.01.0.tar.gz +sap_hypervisor_node_preconfigure_install_trident_url: https://github.com/NetApp/trident/releases/download/v23.10.0/trident-installer-23.10.0.tar.gz # should SRIOV be enabled for unsupported NICs sap_hypervisor_node_preconfigure_sriov_enable_unsupported_nics: true @@ -27,4 +27,4 @@ sap_hypervisor_node_preconfigure_ignore_minimal_memory_check: false sap_hypervisor_node_preconfigure_install_operators: true # Configure the workers? -sap_hypervisor_node_preconfigure_setup_workers: true +sap_hypervisor_node_preconfigure_setup_worker_nodes: true diff --git a/roles/sap_vm_provision/PLATFORM_GUIDANCE.md b/roles/sap_vm_provision/PLATFORM_GUIDANCE.md index 376a1e4..d15427e 100644 --- a/roles/sap_vm_provision/PLATFORM_GUIDANCE.md +++ b/roles/sap_vm_provision/PLATFORM_GUIDANCE.md @@ -148,6 +148,56 @@ aws iam attach-group-policy --group-name 'ag-sap-automation' --policy-arn arn:aw aws iam attach-group-policy --group-name 'ag-sap-automation' --policy-arn arn:aws:iam::aws:policy/AmazonRoute53FullAccess ``` +It is recommended to create new AWS IAM Policy with detailed actions to improve security. +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "VisualEditor0", + "Effect": "Allow", + "Action": [ + "ec2:DescribeImages", + "ec2:DescribeInstances", + "ec2:DescribeTags", + "ec2:DescribeInstanceAttribute", + "ec2:DescribeSubnets", + "ec2:DescribeSecurityGroups", + "ec2:RunInstances", + "ec2:CreateTags", + "ec2:DescribeInstanceStatus", + "ec2:ModifyInstanceAttribute", + "ec2:DescribeRouteTables", + "route53:ListHostedZones", + "route53:ListResourceRecordSets", + "route53:ChangeResourceRecordSets", + "route53:GetChange", + "ec2:DescribeVolumes", + "ec2:CreateVolume", + "ec2:DeleteVolume", + "ec2:AttachVolume", + "ec2:DetachVolume", + "ec2:TerminateInstances", + "ec2:CreateRoute", + "iam:GetRole", + "iam:CreateRole", + "iam:ListInstanceProfilesForRole", + "iam:CreateInstanceProfile", + "iam:AddRoleToInstanceProfile", + "iam:ListAttachedRolePolicies", + "iam:ListRoleTags", + "iam:PutRolePolicy", + "iam:GetInstanceProfile", + "iam:PassRole", + "ec2:AssociateIamInstanceProfile", + "ec2:ReplaceRoute" + ], + "Resource": "*" + } + ] +} +``` +
diff --git a/roles/sap_vm_provision/README.md b/roles/sap_vm_provision/README.md index 3d9871d..4103dc4 100644 --- a/roles/sap_vm_provision/README.md +++ b/roles/sap_vm_provision/README.md @@ -162,6 +162,12 @@ This required structure will: var: groups ``` +### Design assumptions with execution impact + +- For Hyperscaler Cloud Service Providers that use Resource Groups (IBM Cloud, Microsoft Azure): + - Virtual Machine and associated resources (Disks, Network Interfaces, Load Balancer etc.) will be provisioned to the same Resource Group as the targeted network/subnet. + - Optional: Private DNS may be allocated to another Resource Group, and an optional variable is provided for this. + ### Tags to control execution There are no tags used to control the execution of this Ansible Role diff --git a/roles/sap_vm_provision/defaults/main.yml b/roles/sap_vm_provision/defaults/main.yml index b5b633c..9f671fa 100644 --- a/roles/sap_vm_provision/defaults/main.yml +++ b/roles/sap_vm_provision/defaults/main.yml @@ -23,7 +23,7 @@ sap_vm_provision_bastion_user: "" sap_vm_provision_ssh_bastion_private_key_file_path: "" sap_vm_provision_ssh_host_private_key_file_path: "" -sap_vm_provision_ssh_host_public_key_file_path: "{{ sap_vm_provision_ssh_host_private_key_file_path + '.pub' }}" +sap_vm_provision_ssh_host_public_key_file_path: "{{ sap_vm_provision_ssh_host_private_key_file_path + '.pub' }}" # used for gcp_ce_vm, ibmpowervm_vm, kubevirt_vm, vmware_vm #### @@ -84,6 +84,18 @@ sap_vm_provision_nfs_mount_point_type: "" # e.g. nfs, nfs4 sap_vm_provision_nfs_mount_point_opts: "" +#### +# VM Provision - Generic configuration - Calculate for SAP HANA Scale-Out +# Only to be used for SAP HANA Scale-Out, and requires additional changes to +# the Ansible Play that creates the dynamic inventory group before execution +# of the Ansible Role (see documentation) +#### + +# sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator: 1 +# sap_vm_provision_calculate_sap_hana_scaleout_active_worker: 2 +# sap_vm_provision_calculate_sap_hana_scaleout_standby: 1 # Only 0 or 1 + + #### # VM Provision - dynamic inventory variables # Cannot be given a value by end user, the Ansible Role populates the variable @@ -137,6 +149,7 @@ sap_vm_provision_ibmcloud_resource_group_name: "" sap_vm_provision_ibmcloud_region: "{{ sap_vm_provision_ibmcloud_availability_zone | regex_replace('-[0-9]', '') }}" sap_vm_provision_ibmcloud_availability_zone: "" sap_vm_provision_ibmcloud_private_dns_instance_name: "" +# sap_vm_provision_ibmcloud_private_dns_resource_group_name: "" # optional, default use of sap_vm_provision_ibmcloud_resource_group_name sap_vm_provision_ibmcloud_vpc_name: "" sap_vm_provision_ibmcloud_vpc_subnet_name: "" sap_vm_provision_ibmcloud_vpc_sg_names: "" # comma-separated, if ansible_to_terraform then ignore this variable @@ -156,8 +169,10 @@ sap_vm_provision_msazure_app_client_secret: "" sap_vm_provision_msazure_resource_group_name: "" sap_vm_provision_msazure_location_region: "" sap_vm_provision_msazure_location_availability_zone_no: 1 +# sap_vm_provision_msazure_private_dns_resource_group_name: "" # optional, default use of sap_vm_provision_msazure_resource_group_name sap_vm_provision_msazure_vnet_name: "" sap_vm_provision_msazure_vnet_subnet_name: "" +sap_vm_provision_msazure_key_pair_name_ssh_host_public_key: "" #### @@ -238,32 +253,30 @@ sap_vm_provision_aws_ec2_vs_host_os_image_dictionary: rhel-8-2: "*RHEL-8.2*_HVM*x86_64*" rhel-8-4: "*RHEL-8.4*_HVM*x86_64*" rhel-8-6: "*RHEL-8.6*_HVM*x86_64*" - rhel-7-7-sap-ha: "*RHEL-SAP-7.7*" - rhel-7-9-sap-ha: "*RHEL-SAP-7.9*" + rhel-8-8: "*RHEL-8.8*_HVM*x86_64*" rhel-8-1-sap-ha: "*RHEL-SAP-8.1.0*" rhel-8-2-sap-ha: "*RHEL-SAP-8.2.0*" rhel-8-4-sap-ha: "*RHEL-SAP-8.4.0*" rhel-8-6-sap-ha: "*RHEL-SAP-8.6.0*" + rhel-8-8-sap-ha: "*RHEL-SAP-8.8.0*" + rhel-9-0-sap-ha: "*RHEL-SAP-9.0.0*" + rhel-9-2-sap-ha: "*RHEL-SAP-9.2.0*" sles-15-2: "*suse-sles-15-sp2-v202*-hvm-ssd-x86_64*" sles-15-3: "*suse-sles-15-sp3-v202*-hvm-ssd-x86_64*" sles-15-4: "*suse-sles-15-sp4-v202*-hvm-ssd-x86_64*" - sles-12-5-sap: "*suse-sles-sap-12-sp5-v202*-hvm-ssd-x86_64*" - sles-15-1-sap: "*suse-sles-sap-15-sp1-v202*-hvm-ssd-x86_64*" - sles-15-2-sap: "*suse-sles-sap-15-sp2-v202*-hvm-ssd-x86_64*" - sles-15-3-sap: "*suse-sles-sap-15-sp3-v202*-hvm-ssd-x86_64*" - sles-15-4-sap: "*suse-sles-sap-15-sp4-v202*-hvm-ssd-x86_64*" + sles-15-5: "*suse-sles-15-sp5-v202*-hvm-ssd-x86_64*" + sles-12-5-sap-ha: "*suse-sles-sap-12-sp5-v202*-hvm-ssd-x86_64*" + sles-15-1-sap-ha: "*suse-sles-sap-15-sp1-v202*-hvm-ssd-x86_64*" + sles-15-2-sap-ha: "*suse-sles-sap-15-sp2-v202*-hvm-ssd-x86_64*" + sles-15-3-sap-ha: "*suse-sles-sap-15-sp3-v202*-hvm-ssd-x86_64*" + sles-15-4-sap-ha: "*suse-sles-sap-15-sp4-v202*-hvm-ssd-x86_64*" + sles-15-5-sap-ha: "*suse-sles-sap-15-sp5-v202*-hvm-ssd-x86_64*" # OS Images - Google Cloud sap_vm_provision_gcp_ce_vm_host_os_image_dictionary: rhel-8-latest: project: "rhel-cloud" family: "rhel-8" - rhel-7-7-sap-ha: - project: "rhel-sap-cloud" - family: "rhel-7-7-sap-ha" - rhel-7-9-sap-ha: - project: "rhel-sap-cloud" - family: "rhel-7-9-sap-ha" rhel-8-1-sap-ha: project: "rhel-sap-cloud" family: "rhel-8-1-sap-ha" @@ -276,6 +289,9 @@ sap_vm_provision_gcp_ce_vm_host_os_image_dictionary: rhel-8-6-sap-ha: project: "rhel-sap-cloud" family: "rhel-8-6-sap-ha" + rhel-8-8-sap-ha: + project: "rhel-sap-cloud" + family: "rhel-8-8-sap-ha" sles-15-latest: project: "suse-cloud" family: "sles-15" @@ -294,12 +310,15 @@ sap_vm_provision_ibmcloud_vs_host_os_image_dictionary: rhel-8-4: ".*redhat.*8-4.*minimal.*amd64.*" rhel-8-6: ".*redhat.*8-6.*minimal.*amd64.*" rhel-9-0: ".*redhat.*9-0.*minimal.*amd64.*" - rhel-7-9-sap-ha: ".*redhat.*7-9.*amd64.*hana.*" + rhel-9-2: ".*redhat.*9-2.*minimal.*amd64.*" rhel-8-4-sap-ha: ".*redhat.*8-4.*amd64.*hana.*" rhel-8-6-sap-ha: ".*redhat.*8-6.*amd64.*hana.*" + rhel-8-8-sap-ha: ".*redhat.*8-8.*amd64.*hana.*" + rhel-9-0-sap-ha: ".*redhat.*9-0.*amd64.*hana.*" + rhel-9-2-sap-ha: ".*redhat.*9-0.*amd64.*hana.*" sles-15-3-sap-ha: ".*sles.*15-3.*amd64.*hana.*" - sles-15-4-sap: ".*sles.*15-4.*amd64.*hana.*" - sles-15-5-sap: ".*sles.*15-5.*amd64.*hana.*" + sles-15-4-sap-ha: ".*sles.*15-4.*amd64.*hana.*" + sles-15-5-sap-ha: ".*sles.*15-5.*amd64.*hana.*" # OS Images - IBM Cloud, IBM Power VS 'Full Linux subscription' with support and activation keys sap_vm_provision_ibmcloud_powervs_host_os_image_dictionary: @@ -308,11 +327,12 @@ sap_vm_provision_ibmcloud_powervs_host_os_image_dictionary: rhel-9-2: ".*RHEL.*9.*2" sles-15-3: ".*SLES.*15.*3" sles-15-4: ".*SLES.*15.*4" - rhel-8-4-sap-ha: ".*RHEL.*8.*4.*SAP$" # ensure string suffix using $ rhel-8-6-sap-ha: ".*RHEL.*8.*6.*SAP$" # ensure string suffix using $ - sles-15-2-sap: ".*SLES.*15.*2.*SAP$" # ensure string suffix using $ - sles-15-3-sap: ".*SLES.*15.*3.*SAP$" # ensure string suffix using $ - sles-15-4-sap: ".*SLES.*15.*4.*SAP$" # ensure string suffix using $ + rhel-8-8-sap-ha: ".*RHEL.*8.*8.*SAP$" # ensure string suffix using $ + rhel-9-2-sap-ha: ".*RHEL.*9.*2.*SAP$" # ensure string suffix using $ + sles-15-2-sap-ha: ".*SLES.*15.*2.*SAP$" # ensure string suffix using $ + sles-15-3-sap-ha: ".*SLES.*15.*3.*SAP$" # ensure string suffix using $ + sles-15-4-sap-ha: ".*SLES.*15.*4.*SAP$" # ensure string suffix using $ # OS Images - MS Azure sap_vm_provision_msazure_vm_host_os_image_dictionary: @@ -332,6 +352,22 @@ sap_vm_provision_msazure_vm_host_os_image_dictionary: publisher: "RedHat" offer: "RHEL-SAP-HA" sku: "84sapha-gen2" + rhel-8-6-sap-ha: + publisher: "RedHat" + offer: "RHEL-SAP-HA" + sku: "86sapha-gen2" + rhel-8-8-sap-ha: + publisher: "RedHat" + offer: "RHEL-SAP-HA" + sku: "88sapha-gen2" + rhel-9-0-sap-ha: + publisher: "RedHat" + offer: "RHEL-SAP-HA" + sku: "90sapha-gen2" + rhel-9-2-sap-ha: + publisher: "RedHat" + offer: "RHEL-SAP-HA" + sku: "92sapha-gen2" rhel-8-1-sap-applications: publisher: "RedHat" offer: "RHEL-SAP-HA" @@ -344,6 +380,22 @@ sap_vm_provision_msazure_vm_host_os_image_dictionary: publisher: "RedHat" offer: "RHEL-SAP-HA" sku: "84sapapps-gen2" + rhel-8-6-sap-applications: + publisher: "RedHat" + offer: "RHEL-SAP-applications" + sku: "86sapapps-gen2" + rhel-8-8-sap-applications: + publisher: "RedHat" + offer: "RHEL-SAP-applications" + sku: "88sapapps-gen2" + rhel-9-0-sap-applications: + publisher: "RedHat" + offer: "RHEL-SAP-applications" + sku: "90sapapps-gen2" + rhel-9-2-sap-applications: + publisher: "RedHat" + offer: "RHEL-SAP-applications" + sku: "92sapapps-gen2" sles-15-sp3-sap: publisher: "SUSE" offer: "sles-sap-15-sp3" @@ -418,6 +470,7 @@ sap_vm_provision_ibmcloud_powervs_host_specifications_dictionary: example_host_specification_plan: host1: # Hostname, must be 13 characters or less virtual_machine_profile: ush1-4x256 # alt: use custom SAP instance profile sizes using cnp-2x16 (2 Power Cores [16 vCPU] x 16GB) and above + ibmcloud_powervs_hardware_machine_type: e980 # IBM Power hardware machine type (MT) used to host the Virtual Machine disable_ip_anti_spoofing: true #sap_system_type: project_dev # project_dev, project_tst, project_prd sap_host_type: hana_primary # hana_primary, hana_secondary, anydb_primary, anydb_secondary, nwas_ascs, nwas_ers, nwas_pas, nwas_aas @@ -570,3 +623,8 @@ sap_vm_provision_vmware_vm_host_specifications_dictionary: disk_count: 1 # default: 1 disk_size: 512 # size in GB, integer disk_type: scsi # VMware Virtual Disk Node (scsi, ide, sata) + + +# Default to prevent Infrastructure Platform credential secrets leaking +# This should only be amended for debugging +__sap_vm_provision_no_log: true diff --git a/roles/sap_vm_provision/tasks/common/register_os.yml b/roles/sap_vm_provision/tasks/common/register_os.yml index ce5bd58..b63a374 100644 --- a/roles/sap_vm_provision/tasks/common/register_os.yml +++ b/roles/sap_vm_provision/tasks/common/register_os.yml @@ -5,10 +5,9 @@ - name: Ansible Task block for RHEL Package Repositories setup when: - ansible_os_family == 'RedHat' - - sap_vm_provision_os_registration_ca_file_path is defined - - sap_vm_provision_os_registration_script_command is defined - - not sap_vm_provision_os_online_registration_user is defined - - not sap_vm_provision_os_online_registration_passcode is defined + - (sap_vm_provision_os_registration_script_command is defined) and (sap_vm_provision_os_registration_script_command | length > 0) + - (not sap_vm_provision_os_online_registration_user is defined) or (sap_vm_provision_os_online_registration_user | length == 0) + - (not sap_vm_provision_os_online_registration_passcode is defined) or (sap_vm_provision_os_online_registration_passcode | length == 0) block: - name: Red Hat Package Repositories - Clean any existing Red Hat Subscription Manager data @@ -21,6 +20,7 @@ owner: root group: root mode: '0644' + when: (sap_vm_provision_os_registration_ca_file_path is defined) and (sap_vm_provision_os_registration_ca_file_path | length > 0) - name: Red Hat Package Repositories - Update CA trust ansible.builtin.command: update-ca-trust && update-ca-certificates @@ -37,11 +37,9 @@ - name: Ansible Task block for SLES Package Repositories setup when: - ansible_os_family == 'Suse' - - sap_vm_provision_os_registration_ca_file_path is defined - - sap_vm_provision_os_registration_script_command is defined - - not sap_vm_provision_os_online_registration_user is defined - - not sap_vm_provision_os_online_registration_passcode is defined - + - (sap_vm_provision_os_registration_script_command is defined) and (sap_vm_provision_os_registration_script_command | length > 0) + - (not sap_vm_provision_os_online_registration_user is defined) or (sap_vm_provision_os_online_registration_user | length == 0) + - (not sap_vm_provision_os_online_registration_passcode is defined) or (sap_vm_provision_os_online_registration_passcode | length == 0) block: - name: SUSE Package Repositories - Import CA file for SUSE RMT server @@ -51,6 +49,7 @@ owner: root group: root mode: '0644' + when: (sap_vm_provision_os_registration_ca_file_path is defined) and (sap_vm_provision_os_registration_ca_file_path | length > 0) - name: SUSE Package Repositories - Update CA trust ansible.builtin.command: update-ca-trust && update-ca-certificates @@ -66,10 +65,9 @@ - name: Ansible Task block for RHEL Online Package Repositories setup when: - ansible_os_family == 'RedHat' - - not sap_vm_provision_os_registration_ca_file_path is defined - - not sap_vm_provision_os_registration_script_command is defined - - sap_vm_provision_os_online_registration_user is defined - - sap_vm_provision_os_online_registration_passcode is defined + - (not sap_vm_provision_os_registration_script_command is defined) or (sap_vm_provision_os_registration_script_command | length == 0) + - (sap_vm_provision_os_online_registration_user is defined) or (sap_vm_provision_os_online_registration_user | length > 0) + - (sap_vm_provision_os_online_registration_passcode is defined) or (sap_vm_provision_os_online_registration_passcode | length > 0) block: - name: Red Hat Customer Portal (RHCP) Online Package Repositories - Execute @@ -80,10 +78,9 @@ - name: Ansible Task block for SLES Online Package Repositories setup when: - ansible_os_family == 'Suse' - - not sap_vm_provision_os_registration_ca_file_path is defined - - not sap_vm_provision_os_registration_script_command is defined - - sap_vm_provision_os_online_registration_user is defined - - sap_vm_provision_os_online_registration_passcode is defined + - (not sap_vm_provision_os_registration_script_command is defined) or (sap_vm_provision_os_registration_script_command | length == 0) + - (sap_vm_provision_os_online_registration_user is defined) or (sap_vm_provision_os_online_registration_user | length > 0) + - (sap_vm_provision_os_online_registration_passcode is defined) or (sap_vm_provision_os_online_registration_passcode | length > 0) block: - name: SUSE Customer Center (SCC) Online Package Repositories - Execute diff --git a/roles/sap_vm_provision/tasks/common/register_proxy.yml b/roles/sap_vm_provision/tasks/common/register_proxy.yml index 4c89780..40ebddd 100644 --- a/roles/sap_vm_provision/tasks/common/register_proxy.yml +++ b/roles/sap_vm_provision/tasks/common/register_proxy.yml @@ -4,7 +4,7 @@ - name: Ansible Task block for Web Forward Proxy setup when: - - sap_vm_provision_proxy_web_forward_proxy_ip is defined + - (sap_vm_provision_proxy_web_forward_proxy_ip is defined) and (sap_vm_provision_proxy_web_forward_proxy_ip | length > 0) block: - name: Set var for non-interactive login shell on RHEL diff --git a/roles/sap_vm_provision/tasks/common/set_ansible_vars.yml b/roles/sap_vm_provision/tasks/common/set_ansible_vars.yml index db3082f..a6140c6 100644 --- a/roles/sap_vm_provision/tasks/common/set_ansible_vars.yml +++ b/roles/sap_vm_provision/tasks/common/set_ansible_vars.yml @@ -6,24 +6,27 @@ sap_vm_provision_host_specification_plan: "{{ sap_vm_provision_host_specification_plan }}" sap_vm_provision_nfs_mount_point: "{{ sap_vm_provision_nfs_mount_point | default('') }}" sap_vm_provision_nfs_mount_point_separate_sap_transport_dir: "{{ sap_vm_provision_nfs_mount_point_separate_sap_transport_dir | default('') }}" - sap_id_user: "{{ sap_id_user }}" - sap_id_user_password: "{{ sap_id_user_password }}" - sap_software_download_directory: "{{ sap_software_download_directory }}" - sap_install_media_detect_source_directory: "{{ sap_software_download_directory }}" + sap_software_download_directory: "{{ sap_software_download_directory | default('/software') }}" + sap_install_media_detect_source_directory: "{{ sap_software_download_directory | default('/software') }}" -- name: Set facts for all hosts - use facts from localhost - Ansible only +- name: Set facts for all hosts - use facts from localhost - Generic - SAP ID ansible.builtin.set_fact: - sap_vm_provision_ssh_host_private_key_file_path: "{{ sap_vm_provision_ssh_host_private_key_file_path }}" - when: - - sap_vm_provision_iac_type == "ansible" + sap_id_user: "{{ sap_id_user | default('') }}" + sap_id_user_password: "{{ sap_id_user_password | default('') }}" + no_log: "{{ __sap_vm_provision_no_log }}" + +# - name: Set facts for all hosts - use facts from localhost - Ansible only +# ansible.builtin.set_fact: +# when: +# - sap_vm_provision_iac_type == "ansible" - name: Set facts for all hosts - use facts from localhost - SAP HANA ansible.builtin.set_fact: sap_hana_sid: "{{ sap_hana_sid | default(sap_system_hana_db_sid) }}" sap_hana_install_instance_nr: "{{ sap_hana_install_instance_nr | default(sap_system_hana_db_instance_nr) }}" - sap_hana_install_use_master_password: "y" - sap_hana_install_master_password: "{{ sap_hana_install_master_password }}" - sap_hana_install_software_directory: "{{ sap_software_download_directory }}" + sap_hana_install_use_master_password: "{{ sap_hana_install_use_master_password | default('y') }}" + sap_hana_install_master_password: "{{ sap_hana_install_master_password | default('') }}" + sap_hana_install_software_directory: "{{ sap_software_download_directory | default('/software') }}" when: - (sap_hana_sid is defined or sap_system_hana_db_sid is defined) or (hostvars[inventory_hostname].vars['sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary'][sap_vm_provision_host_specification_plan][inventory_hostname].sap_system_hana_db_sid is defined) @@ -48,10 +51,11 @@ sap_ha_pacemaker_cluster_aws_region: "{{ sap_ha_pacemaker_cluster_aws_region }}" sap_ha_pacemaker_cluster_aws_access_key_id: "{{ sap_ha_pacemaker_cluster_aws_access_key_id }}" sap_ha_pacemaker_cluster_aws_secret_access_key: "{{ sap_ha_pacemaker_cluster_aws_secret_access_key }}" - sap_ha_pacemaker_cluster_aws_vip_update_rt: "{{ aws_vpc_subnet_rt_info.route_tables[0].route_table_id }}" + sap_ha_pacemaker_cluster_aws_vip_update_rt: "{{ __sap_vm_provision_task_aws_vpc_subnet_rt_info.route_tables[0].route_table_id }}" when: - sap_ha_pacemaker_cluster_aws_region is defined - sap_vm_provision_iac_platform == "aws_ec2_vs" + no_log: "{{ __sap_vm_provision_no_log }}" # - name: Set facts for all hosts - use facts from localhost - HA/DR - GCP # ansible.builtin.set_fact: @@ -59,15 +63,17 @@ # - sap_ha_pacemaker_cluster_gcp_region_zone is defined # - sap_vm_provision_iac_type == "ansible" # - sap_vm_provision_iac_platform == "gcp_ce_vm" +# no_log: "{{ __sap_vm_provision_no_log }}" - name: Set facts for all hosts - use facts from localhost - HA/DR - IBM Cloud, IBM Power VS ansible.builtin.set_fact: - sap_ha_pacemaker_cluster_ibmcloud_powervs_workspace_crn: "{{ register_ibmcloud_power_iaas_workspace_service_instance.resource.crn }}" + sap_ha_pacemaker_cluster_ibmcloud_powervs_workspace_crn: "{{ __sap_vm_provision_task_ibmcloud_pi_workspace_service_instance.resource.crn }}" sap_ha_pacemaker_cluster_ibmcloud_api_key: "{{ sap_ha_pacemaker_cluster_ibmcloud_api_key }}" sap_ha_pacemaker_cluster_ibmcloud_region: "{{ list_ibmcloud_powervs_location_to_powervs_region[sap_vm_provision_ibmcloud_powervs_location] }}" # Lookup IBM Power VS Region from the given IBM Power VS Location during sap_vm_provision execution when: - sap_ha_pacemaker_cluster_ibmcloud_api_key is defined - sap_vm_provision_iac_platform == "ibmcloud_powervs" + no_log: "{{ __sap_vm_provision_no_log }}" - name: Set facts for all hosts - use facts from localhost - HA/DR - IBM Cloud ansible.builtin.set_fact: @@ -76,13 +82,15 @@ when: - sap_ha_pacemaker_cluster_ibmcloud_region is defined - sap_vm_provision_iac_platform == "ibmcloud_vs" + no_log: "{{ __sap_vm_provision_no_log }}" - # - name: Set facts for all hosts - use facts from localhost - HA/DR - MS Azure - # ansible.builtin.set_fact: - # when: - # - sap_ha_pacemaker_cluster_msazure_resource_group is defined - # - sap_vm_provision_iac_type == "ansible" - # - sap_vm_provision_iac_platform == "msazure_vm" +# - name: Set facts for all hosts - use facts from localhost - HA/DR - MS Azure +# ansible.builtin.set_fact: +# when: +# - sap_ha_pacemaker_cluster_msazure_resource_group is defined +# - sap_vm_provision_iac_type == "ansible" +# - sap_vm_provision_iac_platform == "msazure_vm" +# no_log: "{{ __sap_vm_provision_no_log }}" # - name: Set facts for all hosts - use facts from localhost - HA/DR - IBM PowerVM # ansible.builtin.set_fact: @@ -90,6 +98,7 @@ # - sap_ha_pacemaker_cluster_ibmpower_vm_hmc_host is defined # - sap_vm_provision_iac_type == "ansible" # - sap_vm_provision_iac_platform == "ibmpowervm_vm" +# no_log: "{{ __sap_vm_provision_no_log }}" # - name: Set facts for all hosts - use facts from localhost - HA/DR - KubeVirt # ansible.builtin.set_fact: @@ -97,6 +106,7 @@ # - sap_ha_pacemaker_cluster___ is defined # - sap_vm_provision_iac_type == "ansible" # - sap_vm_provision_iac_platform == "kubevirt_vm" +# no_log: "{{ __sap_vm_provision_no_log }}" # - name: Set facts for all hosts - use facts from localhost - HA/DR - OVirt # ansible.builtin.set_fact: @@ -104,6 +114,7 @@ # - sap_ha_pacemaker_cluster_aws_region is defined # - sap_vm_provision_iac_type == "ansible" # - sap_vm_provision_iac_platform == "ovirt_vm" +# no_log: "{{ __sap_vm_provision_no_log }}" # - name: Set facts for all hosts - use facts from localhost - HA/DR - VMware # ansible.builtin.set_fact: @@ -111,6 +122,7 @@ # - sap_ha_pacemaker_cluster_aws_region is defined # - sap_vm_provision_iac_type == "ansible" # - sap_vm_provision_iac_platform == "vmware_vm" +# no_log: "{{ __sap_vm_provision_no_log }}" - name: Set facts for all hosts - IBM Power (ppc64le) only ansible.builtin.set_fact: diff --git a/roles/sap_vm_provision/tasks/common/set_ansible_vars_storage.yml b/roles/sap_vm_provision/tasks/common/set_ansible_vars_storage.yml index d1f0393..b8925bb 100644 --- a/roles/sap_vm_provision/tasks/common/set_ansible_vars_storage.yml +++ b/roles/sap_vm_provision/tasks/common/set_ansible_vars_storage.yml @@ -5,7 +5,7 @@ ansible.builtin.set_fact: host_node_scaleout_origin_spec: "{{ ansible_hostname | regex_replace('^(.+?)\\d*$', '\\1') }}" when: - - sap_hana_scaleout_active_coordinator is defined + - sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined - not inventory_hostname in vars[ansible_prompt_iac_platform_choice + '_host_specifications_dictionary'][sap_vm_provision_host_specification_plan].keys() # Use inventory_hostname_short to retrieve host specification from the dictionary. While ansible_hostname will work for Ansible only, using Ansible>Terraform may see ansible_hostname as 'localhost' and fail diff --git a/roles/sap_vm_provision/tasks/common/set_etc_hosts_scaleout.yml b/roles/sap_vm_provision/tasks/common/set_etc_hosts_scaleout.yml index 506259d..ae637a8 100644 --- a/roles/sap_vm_provision/tasks/common/set_etc_hosts_scaleout.yml +++ b/roles/sap_vm_provision/tasks/common/set_etc_hosts_scaleout.yml @@ -4,7 +4,7 @@ - name: Ansible Play for controlling execution to an Infrastructure Platform when SAP HANA Scale-Out is used when: - - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_hana_scaleout_active_coordinator is defined or sap_hana_scaleout_active_worker is defined or sap_hana_scaleout_standby is defined) + - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined or sap_vm_provision_calculate_sap_hana_scaleout_active_worker is defined or sap_vm_provision_calculate_sap_hana_scaleout_standby is defined) block: # Required to collect the remote host's facts for further processing @@ -35,7 +35,7 @@ loop_control: label: "{{ inventory_hostname_short }}" when: - - (sap_hana_scaleout_standby == 0) or (not sap_hana_scaleout_standby is defined) + - (sap_vm_provision_calculate_sap_hana_scaleout_standby == 0) or (not sap_vm_provision_calculate_sap_hana_scaleout_standby is defined) - name: Update /etc/hosts file for SAP HANA Scale-Out Active Workers (with Standby) ansible.builtin.lineinfile: @@ -46,7 +46,7 @@ - "# SAP HANA scale-out workers\n{% for host in (groups['hana_primary'] | reject('search', '0') | list)[:-1] %}{% if (host != inventory_hostname_short) %}{{ hostvars[host]['ansible_host'] }}\t{{ hostvars[host]['ansible_fqdn'] }}\t{{ hostvars[host]['inventory_hostname_short'] }}\n{% endif %}{% endfor %}" loop_control: label: "{{ inventory_hostname_short }}" - when: sap_hana_scaleout_standby > 0 + when: sap_vm_provision_calculate_sap_hana_scaleout_standby > 0 - name: Update /etc/hosts file for SAP HANA Scale-Out Standby ansible.builtin.lineinfile: @@ -58,5 +58,5 @@ loop_control: label: "{{ inventory_hostname_short }}" when: - - sap_hana_scaleout_standby > 0 + - sap_vm_provision_calculate_sap_hana_scaleout_standby > 0 - not inventory_hostname_short == hostvars[(groups['hana_primary'] | last)]['inventory_hostname_short'] diff --git a/roles/sap_vm_provision/tasks/platform_ansible/aws_ec2_vs/execute_main.yml b/roles/sap_vm_provision/tasks/platform_ansible/aws_ec2_vs/execute_main.yml index cdebca1..f34ce81 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/aws_ec2_vs/execute_main.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/aws_ec2_vs/execute_main.yml @@ -1,35 +1,42 @@ --- - name: Ansible Task block for looped provisioning of AWS EC2 instances + any_errors_fatal: true + # Using environment, no_log is ineffective and log will show 'EXEC /bin/sh -c 'ENV_VAR=value python3 /AnsiballZ_ansible_module_name.py && sleep 0' + # Therefore do not use environment for secrets, use only for non-sensitive values as this will reduce Ansible Task parameters. environment: - AWS_ACCESS_KEY_ID: "{{ sap_vm_provision_aws_access_key }}" - AWS_SECRET_ACCESS_KEY: "{{ sap_vm_provision_aws_secret_access_key }}" + # AWS_ACCESS_KEY_ID: "{{ sap_vm_provision_aws_access_key }}" + # AWS_SECRET_ACCESS_KEY: "{{ sap_vm_provision_aws_secret_access_key }}" AWS_REGION: "{{ sap_vm_provision_aws_region }}" block: - name: Identify OS Image (AWS AMI) - register: register_aws_ami + register: __sap_vm_provision_task_aws_ami + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.ec2_ami_info: owners: ["aws-marketplace"] filters: name: "{{ lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_os_image_dictionary')[sap_vm_provision_aws_ec2_vs_host_os_image] }}" + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" - name: Set fact to hold loop variables from include_tasks ansible.builtin.set_fact: register_provisioned_host_all: [] - name: Provision hosts to AWS - register: register_provisioned_hosts + register: __sap_vm_provision_task_provision_host_all_run ansible.builtin.include_tasks: file: "{{ 'platform_' + sap_vm_provision_iac_type }}/{{ sap_vm_provision_iac_platform }}/execute_provision.yml" - apply: - environment: - AWS_ACCESS_KEY_ID: "{{ sap_vm_provision_aws_access_key }}" - AWS_SECRET_ACCESS_KEY: "{{ sap_vm_provision_aws_secret_access_key }}" - AWS_REGION: "{{ sap_vm_provision_aws_region }}" + # apply: + # environment: + # # AWS_ACCESS_KEY_ID: "{{ sap_vm_provision_aws_access_key }}" + # # AWS_SECRET_ACCESS_KEY: "{{ sap_vm_provision_aws_secret_access_key }}" + # AWS_REGION: "{{ sap_vm_provision_aws_region }}" - name: Add hosts provisioned to the Ansible Inventory - register: register_add_hosts + register: __sap_vm_provision_task_provision_host_all_add + no_log: "{{ __sap_vm_provision_no_log }}" ansible.builtin.add_host: name: "{{ add_item[0].host_node }}" groups: "{{ add_item[0].sap_system_type + '_' if (add_item[0].sap_system_type != '') }}{{ add_item[0].sap_host_type }}" @@ -42,26 +49,30 @@ label: "{{ add_item[0].host_node }}" loop_var: add_item - # Cannot override any variables from extravars input, see https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#understanding-variable-precedence # Ensure no default value exists for any prompted variable before execution of Ansible Playbook - name: Gather information about AWS VPC Route Table for the VPC Subnet + register: __sap_vm_provision_task_aws_vpc_subnet_rt_info + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.ec2_vpc_route_table_info: filters: association.subnet-id: "{{ sap_vm_provision_aws_vpc_subnet_id }}" - register: aws_vpc_subnet_rt_info + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" - name: Set fact to hold all inventory hosts in all groups ansible.builtin.set_fact: groups_merged_list: "{{ [ [ groups['hana_primary'] | default([]) ] , [ groups['hana_secondary'] | default([]) ] , [ groups['nwas_ascs'] | default([]) ] , [ groups['nwas_ers'] | default([]) ] , [ groups['nwas_pas'] | default([]) ] , [ groups['nwas_aas'] | default([]) ] ] | flatten | select() }}" - name: Set Ansible Vars - register: register_set_ansible_vars + register: __sap_vm_provision_task_ansible_vars_set ansible.builtin.include_tasks: file: common/set_ansible_vars.yml - name: Ansible AWS Route53 DNS Records for hosts + register: __sap_vm_provision_task_aws_route53 + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.route53: state: present private_zone: true @@ -71,9 +82,34 @@ ttl: 7200 value: "{{ hostvars[inventory_hostname].ansible_host }}" wait: true + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" + + rescue: + # This requires no_log set on each Ansible Task, and not set on the Ansible Task Block + # This requires an Ansible Task Block containing the Ansible Tasks for calling + # Infrastructure Platform APIs (via Ansible Modules) + - name: Show errors in task outputs + ansible.builtin.fail: + msg: "{{ lookup('ansible.builtin.vars', loop_item) }}" + loop: + - __sap_vm_provision_task_aws_ami + - __sap_vm_provision_task_provision_host_all_run + - __sap_vm_provision_task_provision_host_single + - __sap_vm_provision_task_provision_host_single_info + - __sap_vm_provision_task_provision_host_single_volumes + - __sap_vm_provision_task_provision_host_all_add + - __sap_vm_provision_task_aws_vpc_subnet_rt_info + - __sap_vm_provision_task_aws_route53 + loop_control: + loop_var: loop_item + index_var: loop_item_index + label: "{{ 'Variable No. ' + (loop_item_index | string) }}" + when: + - lookup('ansible.builtin.vars', loop_item, default='') | length > 0 + - not lookup('ansible.builtin.vars', loop_item, default='') is skipped + - lookup('ansible.builtin.vars', loop_item, default='') is failed - # - ansible.builtin.debug: - # var: register_add_hosts.results - name: Ansible Task block to execute on target inventory hosts delegate_to: "{{ inventory_hostname }}" @@ -92,36 +128,39 @@ name: "{{ inventory_hostname_short }}" - name: Set /etc/hosts - register: register_etc_hosts_file + register: __sap_vm_provision_task_os_etc_hosts ansible.builtin.include_tasks: file: common/set_etc_hosts.yml - name: Set /etc/hosts for HA - register: register_etc_hosts_file_ha + register: __sap_vm_provision_task_os_etc_hosts_ha ansible.builtin.include_tasks: file: common/set_etc_hosts_ha.yml when: - (groups["hana_secondary"] is defined and (groups["hana_secondary"] | length>0)) or (groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0)) or (groups["anydb_secondary"] is defined and (groups["anydb_secondary"] | length>0)) - name: Set /etc/hosts for Scale-Out - register: register_etc_hosts_file_scaleout + register: __sap_vm_provision_task_os_etc_hosts_scaleout ansible.builtin.include_tasks: file: common/set_etc_hosts_scaleout.yml when: - - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_hana_scaleout_active_coordinator is defined or sap_hana_scaleout_active_worker is defined or sap_hana_scaleout_standby is defined) + - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined or sap_vm_provision_calculate_sap_hana_scaleout_active_worker is defined or sap_vm_provision_calculate_sap_hana_scaleout_standby is defined) - name: Set vars for sap_storage_setup Ansible Role - register: register_ansible_vars_storage + register: __sap_vm_provision_task_ansible_vars_storage ansible.builtin.include_tasks: file: common/set_ansible_vars_storage.yml - name: Ansible Task block for provisioning of High Availability resources for AWS EC2 instances delegate_to: localhost + any_errors_fatal: true run_once: true + # Using environment, no_log is ineffective and log will show 'EXEC /bin/sh -c 'ENV_VAR=value python3 /AnsiballZ_ansible_module_name.py && sleep 0' + # Therefore do not use environment for secrets, use only for non-sensitive values as this will reduce Ansible Task parameters. environment: - AWS_ACCESS_KEY_ID: "{{ sap_vm_provision_aws_access_key }}" - AWS_SECRET_ACCESS_KEY: "{{ sap_vm_provision_aws_secret_access_key }}" + # AWS_ACCESS_KEY_ID: "{{ sap_vm_provision_aws_access_key }}" + # AWS_SECRET_ACCESS_KEY: "{{ sap_vm_provision_aws_secret_access_key }}" AWS_REGION: "{{ sap_vm_provision_aws_region }}" when: - sap_ha_pacemaker_cluster_aws_region is defined @@ -131,8 +170,43 @@ - name: Provision High Availability resources for AWS EC2 hosts ansible.builtin.include_tasks: file: "{{ 'platform_' + sap_vm_provision_iac_type }}/{{ sap_vm_provision_iac_platform }}/execute_setup_ha.yml" - apply: - environment: - AWS_ACCESS_KEY_ID: "{{ sap_vm_provision_aws_access_key }}" - AWS_SECRET_ACCESS_KEY: "{{ sap_vm_provision_aws_secret_access_key }}" - AWS_REGION: "{{ sap_vm_provision_aws_region }}" + # apply: + # environment: + # # AWS_ACCESS_KEY_ID: "{{ sap_vm_provision_aws_access_key }}" + # # AWS_SECRET_ACCESS_KEY: "{{ sap_vm_provision_aws_secret_access_key }}" + # AWS_REGION: "{{ sap_vm_provision_aws_region }}" + + rescue: + # This requires no_log set on each Ansible Task, and not set on the Ansible Task Block + # This requires an Ansible Task Block containing the Ansible Tasks for calling + # Infrastructure Platform APIs (via Ansible Modules) + - name: Show errors in task outputs + ansible.builtin.fail: + msg: "{{ lookup('ansible.builtin.vars', loop_item) }}" + loop: + - __sap_vm_provision_task_aws_account_info + - __sap_vm_provision_task_aws_vpc_subnet_rt_info + - __sap_vm_provision_task_aws_vpc_subnet_rt_route_sap_hana + - __sap_vm_provision_task_aws_route53_sap_hana + - __sap_vm_provision_task_aws_vpc_subnet_rt_route_sap_anydb + - __sap_vm_provision_task_aws_route53_sap_anydb + - __sap_vm_provision_task_aws_vpc_subnet_rt_route_sap_netweaver_ascs + - __sap_vm_provision_task_aws_route53_sap_netweaver_ascs + - __sap_vm_provision_task_aws_vpc_subnet_rt_route_sap_netweaver_ers + - __sap_vm_provision_task_aws_route53_sap_netweaver_ers + - __sap_vm_provision_task_aws_iam_role_ha_pacemaker + - __sap_vm_provision_task_aws_iam_policy_dataprovider + - __sap_vm_provision_task_aws_iam_policy_overlayip + - __sap_vm_provision_task_aws_iam_policy_stonith_saphana + - __sap_vm_provision_task_aws_iam_policy_stonith_sapnwas + - __sap_vm_provision_task_aws_iam_attach_role + - __sap_vm_provision_task_aws_iam_associate_instance_saphana + - __sap_vm_provision_task_aws_iam_associate_instance_sapnwas + loop_control: + loop_var: loop_item + index_var: loop_item_index + label: "{{ 'Variable No. ' + (loop_item_index | string) }}" + when: + - lookup('ansible.builtin.vars', loop_item, default='') | length > 0 + - not lookup('ansible.builtin.vars', loop_item, default='') is skipped + - lookup('ansible.builtin.vars', loop_item, default='') is failed diff --git a/roles/sap_vm_provision/tasks/platform_ansible/aws_ec2_vs/execute_provision.yml b/roles/sap_vm_provision/tasks/platform_ansible/aws_ec2_vs/execute_provision.yml index fb1f484..7c62e81 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/aws_ec2_vs/execute_provision.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/aws_ec2_vs/execute_provision.yml @@ -1,20 +1,26 @@ --- # The tasks in this file are executed in a loop over the defined hosts +- name: Ensure short hostname is not longer than 13 characters (see SAP Note 611361) + ansible.builtin.assert: + that: (inventory_hostname | length | int) <= (13 | int) + fail_msg: "FAIL: The length of the hostname is {{ inventory_hostname | length | int }} but must be less or equal to 13 characters!" + # When SAP HANA Scale-Out is used, if host name is not in original specifications then strip suffix node number from host name - name: Set fact when performing SAP HANA Scale-Out ansible.builtin.set_fact: scaleout_origin_host_spec: "{{ inventory_hostname | regex_replace('^(.+?)\\d*$', '\\1') }}" when: - - sap_hana_scaleout_active_coordinator is defined + - sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined - not inventory_hostname in lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan].keys() - name: Provision AWS EC2 Virtual Server instance - register: register_provisioned_host_single + register: __sap_vm_provision_task_provision_host_single + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.ec2_instance: state: started name: "{{ inventory_hostname }}" - image_id: "{{ (register_aws_ami.images | sort(attribute='creation_date') | last).image_id }}" + image_id: "{{ (__sap_vm_provision_task_aws_ami.images | sort(attribute='creation_date') | last).image_id }}" instance_type: "{{ lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].virtual_machine_profile }}" key_name: "{{ sap_vm_provision_aws_key_pair_name_ssh_host_public_key }}" security_groups: "{{ sap_vm_provision_aws_vpc_sg_names }}" @@ -28,17 +34,22 @@ network: assign_public_ip: false source_dest_check: "{{ not lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].disable_ip_anti_spoofing }}" # Disable the Anti IP Spoofing by setting Source/Destination Check to false + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" - name: Set fact for storage volume letters calculations (max 25 volumes) ansible.builtin.set_fact: storage_vol_letters: "bcdefghijklmnopqrstuvwxyz" - name: Read AWS EC2 instance information + register: __sap_vm_provision_task_provision_host_single_info + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.ec2_instance_info: filters: "tag:Name": "{{ inventory_hostname }}" "instance-state-name": ["running"] - register: instance_info + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" - name: Set fact for available storage volume device names ansible.builtin.set_fact: @@ -46,7 +57,7 @@ {% set letters = 'bcdefghijklmnopqrstuvwxyz' %} {% set volumes = [] %} {%- for letter in letters -%} - {% for device in instance_info.instances[0].block_device_mappings -%} + {% for device in __sap_vm_provision_task_provision_host_single_info.instances[0].block_device_mappings -%} {% if '/dev/sd' + letter not in device.device_name -%} {% set dev = volumes.append('/dev/sd' + letter) %} {%- endif %} @@ -88,13 +99,17 @@ # The volume creation task requires the above task to define the parameter # which contains the calculated unique device names. - name: Provision AWS EBS volumes for AWS EC2 Virtual Server instance filesystems + register: __sap_vm_provision_task_provision_host_single_volumes + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.ec2_vol: name: "{{ inventory_hostname }}-vol_{{ vol_item.name }}" - instance: "{{ register_provisioned_host_single.instance_ids[0] }}" + instance: "{{ __sap_vm_provision_task_provision_host_single.instance_ids[0] }}" volume_type: "{{ vol_item.type }}" volume_size: "{{ vol_item.size }}" device_name: "{{ vol_item.device }}" delete_on_termination: true + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" loop: "{{ filesystem_volume_map }}" loop_control: loop_var: vol_item @@ -103,26 +118,28 @@ when: - vol_item.fstype is defined - vol_item.size > 0 - register: volume_provisioning - name: Read AWS EC2 instance information + register: __sap_vm_provision_task_provision_host_single_info + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.ec2_instance_info: filters: "tag:Name": "{{ inventory_hostname }}" - register: instance_info + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" - name: Add host facts + no_log: "{{ __sap_vm_provision_no_log }}" ansible.builtin.set_fact: filesystem_volume_map: "{{ filesystem_volume_map }}" - volume_provisioning: "{{ volume_provisioning }}" - instance_info: "{{ instance_info }}" + __sap_vm_provision_task_provision_host_single_volumes: "{{ __sap_vm_provision_task_provision_host_single_volumes }}" + __sap_vm_provision_task_provision_host_single_info: "{{ __sap_vm_provision_task_provision_host_single_info }}" delegate_to: "{{ inventory_hostname }}" delegate_facts: true - - name: Create fact for delegate host IP ansible.builtin.set_fact: - provisioned_private_ip: "{{ register_provisioned_host_single.instances[0].private_ip_address }}" + provisioned_private_ip: "{{ __sap_vm_provision_task_provision_host_single.instances[0].private_ip_address }}" - name: Copy facts to delegate host @@ -134,7 +151,7 @@ delegate_sap_vm_provision_bastion_ssh_port: "{{ sap_vm_provision_bastion_ssh_port }}" delegate_sap_vm_provision_ssh_bastion_private_key_file_path: "{{ sap_vm_provision_ssh_bastion_private_key_file_path }}" delegate_sap_vm_provision_ssh_host_private_key_file_path: "{{ sap_vm_provision_ssh_host_private_key_file_path }}" - delegate_private_ip: "{{ register_provisioned_host_single.instances[0].private_ip_address }}" + delegate_private_ip: "{{ __sap_vm_provision_task_provision_host_single.instances[0].private_ip_address }}" delegate_hostname: "{{ inventory_hostname }}" delegate_sap_vm_provision_dns_root_domain_name: "{{ sap_vm_provision_dns_root_domain }}" @@ -158,26 +175,26 @@ replace: 'ssh-rsa' - name: Permit root login + register: __sap_vm_provision_task_os_sshd_config ansible.builtin.replace: path: /etc/ssh/sshd_config regexp: '(^PermitRootLogin no)' replace: 'PermitRootLogin yes' - register: sshd_config - name: Reload sshd service ansible.builtin.service: name: sshd state: reloaded when: - - sshd_config.changed + - __sap_vm_provision_task_os_sshd_config.changed ### end of block - name: Append loop value to register ansible.builtin.set_fact: - register_provisioned_host_single: "{{ register_provisioned_host_single | combine( { 'host_node' : inventory_hostname } , { 'sap_host_type' : lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_host_type } , { 'sap_system_type' : (lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_system_type | default('')) } ) }}" + __sap_vm_provision_task_provision_host_single: "{{ __sap_vm_provision_task_provision_host_single | combine( { 'host_node' : inventory_hostname } , { 'sap_host_type' : lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_host_type } , { 'sap_system_type' : (lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_system_type | default('')) } ) }}" - name: Append output to merged register ansible.builtin.set_fact: - register_provisioned_host_all: "{{ register_provisioned_host_all + [register_provisioned_host_single] }}" + register_provisioned_host_all: "{{ register_provisioned_host_all + [__sap_vm_provision_task_provision_host_single] }}" diff --git a/roles/sap_vm_provision/tasks/platform_ansible/aws_ec2_vs/execute_setup_ha.yml b/roles/sap_vm_provision/tasks/platform_ansible/aws_ec2_vs/execute_setup_ha.yml index ec281c6..0ae617e 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/aws_ec2_vs/execute_setup_ha.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/aws_ec2_vs/execute_setup_ha.yml @@ -1,35 +1,45 @@ --- - name: Gather information about AWS account + register: __sap_vm_provision_task_aws_account_info + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.aws_caller_info: - register: aws_account_info + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" - name: Gather information about AWS VPC Route Table for the VPC Subnet + register: __sap_vm_provision_task_aws_vpc_subnet_rt_info + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.ec2_vpc_route_table_info: filters: association.subnet-id: "{{ sap_vm_provision_aws_vpc_subnet_id }}" - register: aws_vpc_subnet_rt_info - + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" - name: Ansible AWS VPC Route Table append route for SAP HANA HA + register: __sap_vm_provision_task_aws_vpc_subnet_rt_route_sap_hana + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.ec2_vpc_route_table: lookup: id - vpc_id: "{{ aws_vpc_subnet_rt_info.route_tables[0].vpc_id }}" - route_table_id: "{{ aws_vpc_subnet_rt_info.route_tables[0].route_table_id }}" + vpc_id: "{{ __sap_vm_provision_task_aws_vpc_subnet_rt_info.route_tables[0].vpc_id }}" + route_table_id: "{{ __sap_vm_provision_task_aws_vpc_subnet_rt_info.route_tables[0].route_table_id }}" purge_subnets: false purge_routes: false state: present routes: - dest: "{{ sap_ha_pacemaker_cluster_vip_hana_primary_ip_address | default('192.168.1.90/32') }}" instance_id: "{{ hostvars[host_node].ansible_board_asset_tag }}" + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" loop: "{{ (groups['hana_primary'] | default([])) }}" loop_control: loop_var: host_node - register: aws_vpc_subnet_rt_route_sap_hana when: - groups["hana_secondary"] is defined and (groups["hana_secondary"] | length>0) - name: Ansible AWS Route53 DNS Records for SAP HANA HA Virtual Hostname + register: __sap_vm_provision_task_aws_route53_sap_hana + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.route53: state: present private_zone: true @@ -39,32 +49,38 @@ ttl: 7200 value: "{{ (sap_ha_pacemaker_cluster_vip_hana_primary_ip_address | default('192.168.1.90/32')) | regex_replace('/.*', '') }}" wait: true + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" loop: "{{ (groups['hana_primary'] | default([])) }}" loop_control: loop_var: host_node when: - groups["hana_secondary"] is defined and (groups["hana_secondary"]|length>0) - - name: Ansible AWS VPC Route Table append route for SAP AnyDB HA + register: __sap_vm_provision_task_aws_vpc_subnet_rt_route_sap_anydb + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.ec2_vpc_route_table: lookup: id - vpc_id: "{{ aws_vpc_subnet_rt_info.route_tables[0].vpc_id }}" - route_table_id: "{{ aws_vpc_subnet_rt_info.route_tables[0].route_table_id }}" + vpc_id: "{{ __sap_vm_provision_task_aws_vpc_subnet_rt_info.route_tables[0].vpc_id }}" + route_table_id: "{{ __sap_vm_provision_task_aws_vpc_subnet_rt_info.route_tables[0].route_table_id }}" purge_subnets: false purge_routes: false state: present routes: - dest: "{{ sap_vm_temp_vip_anydb_primary | default('192.168.1.90/32') }}" instance_id: "{{ hostvars[host_node].ansible_board_asset_tag }}" + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" loop: "{{ (groups['anydb_primary'] | default([])) }}" loop_control: loop_var: host_node - register: aws_vpc_subnet_rt_route_sap_anydb when: - groups["anydb_secondary"] is defined and (groups["anydb_secondary"] | length>0) - name: Ansible AWS Route53 DNS Records for SAP AnyDB HA Virtual Hostname + register: __sap_vm_provision_task_aws_route53_sap_anydb + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.route53: state: present private_zone: true @@ -74,32 +90,38 @@ ttl: 7200 value: "{{ (sap_vm_temp_vip_anydb_primary | default('192.168.1.90/32')) | regex_replace('/.*', '') }}" wait: true + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" loop: "{{ (groups['anydb_primary'] | default([])) }}" loop_control: loop_var: host_node when: - groups["anydb_secondary"] is defined and (groups["anydb_secondary"]|length>0) - - name: Ansible AWS VPC Route Table append route for SAP NetWeaver ASCS HA + register: __sap_vm_provision_task_aws_vpc_subnet_rt_route_sap_netweaver_ascs + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.ec2_vpc_route_table: lookup: id - vpc_id: "{{ aws_vpc_subnet_rt_info.route_tables[0].vpc_id }}" - route_table_id: "{{ aws_vpc_subnet_rt_info.route_tables[0].route_table_id }}" + vpc_id: "{{ __sap_vm_provision_task_aws_vpc_subnet_rt_info.route_tables[0].vpc_id }}" + route_table_id: "{{ __sap_vm_provision_task_aws_vpc_subnet_rt_info.route_tables[0].route_table_id }}" purge_subnets: false purge_routes: false state: present routes: - dest: "{{ sap_ha_pacemaker_cluster_vip_nwas_abap_ascs_ip_address | default('192.168.2.10/32') }}" instance_id: "{{ hostvars[host_node].ansible_board_asset_tag }}" + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" loop: "{{ (groups['nwas_ascs'] | default([])) }}" loop_control: loop_var: host_node - register: aws_vpc_subnet_rt_route_sap_netweaver_ascs when: - groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0) - name: Ansible AWS Route53 DNS Records for SAP NetWeaver ASCS HA Virtual Hostname + register: __sap_vm_provision_task_aws_route53_sap_netweaver_ascs + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.route53: state: present private_zone: true @@ -109,32 +131,38 @@ ttl: 7200 value: "{{ (sap_ha_pacemaker_cluster_vip_nwas_abap_ascs_ip_address | default('192.168.2.10/32')) | regex_replace('/.*', '') }}" wait: true + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" loop: "{{ (groups['nwas_ascs'] | default([])) }}" loop_control: loop_var: host_node when: - groups["nwas_ers"] is defined and (groups["nwas_ers"]|length>0) - - name: Ansible AWS VPC Route Table append route for SAP NetWeaver ERS HA + register: __sap_vm_provision_task_aws_vpc_subnet_rt_route_sap_netweaver_ers + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.ec2_vpc_route_table: lookup: id - vpc_id: "{{ aws_vpc_subnet_rt_info.route_tables[0].vpc_id }}" - route_table_id: "{{ aws_vpc_subnet_rt_info.route_tables[0].route_table_id }}" + vpc_id: "{{ __sap_vm_provision_task_aws_vpc_subnet_rt_info.route_tables[0].vpc_id }}" + route_table_id: "{{ __sap_vm_provision_task_aws_vpc_subnet_rt_info.route_tables[0].route_table_id }}" purge_subnets: false purge_routes: false state: present routes: - dest: "{{ sap_ha_pacemaker_cluster_vip_nwas_abap_ers_ip_address | default('192.168.2.11/32') }}" instance_id: "{{ hostvars[host_node].ansible_board_asset_tag }}" + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" loop: "{{ (groups['nwas_ers'] | default([])) }}" loop_control: loop_var: host_node - register: aws_vpc_subnet_rt_route_sap_netweaver_ers when: - groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0) - name: Ansible AWS Route53 DNS Records for SAP NetWeaver ERS HA Virtual Hostname + register: __sap_vm_provision_task_aws_route53_sap_netweaver_ers + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.route53: state: present private_zone: true @@ -144,20 +172,23 @@ ttl: 7200 value: "{{ (sap_ha_pacemaker_cluster_vip_nwas_abap_ers_ip_address | default('192.168.2.11/32')) | regex_replace('/.*', '') }}" wait: true + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" loop: "{{ (groups['nwas_ers'] | default([])) }}" loop_control: loop_var: host_node when: - groups["nwas_ers"] is defined and (groups["nwas_ers"]|length>0) - ## For HA of PAS and AAS, if required # - name: Ansible AWS VPC Route Table append route for SAP NetWeaver PAS HA +# register: __sap_vm_provision_task_aws_route53_sap_netweaver_pas +# no_log: "{{ __sap_vm_provision_no_log }}" # amazon.aws.ec2_vpc_route_table: # lookup: id -# vpc_id: "{{ aws_vpc_subnet_rt_info.route_tables[0].vpc_id }}" -# route_table_id: "{{ aws_vpc_subnet_rt_info.route_tables[0].route_table_id }}" +# vpc_id: "{{ __sap_vm_provision_task_aws_vpc_subnet_rt_info.route_tables[0].vpc_id }}" +# route_table_id: "{{ __sap_vm_provision_task_aws_vpc_subnet_rt_info.route_tables[0].route_table_id }}" # purge_subnets: false # purge_routes: false # state: present @@ -167,7 +198,6 @@ # loop: "{{ (groups['nwas_pas'] | default([])) }}" # loop_control: # loop_var: host_node -# register: aws_vpc_subnet_rt_route_sap_netweaver_pas # when: # - groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0) @@ -189,10 +219,12 @@ # - name: Ansible AWS VPC Route Table append route for SAP NetWeaver AAS HA +# register: __sap_vm_provision_task_aws_route53_sap_netweaver_aas +# no_log: "{{ __sap_vm_provision_no_log }}" # amazon.aws.ec2_vpc_route_table: # lookup: id -# vpc_id: "{{ aws_vpc_subnet_rt_info.route_tables[0].vpc_id }}" -# route_table_id: "{{ aws_vpc_subnet_rt_info.route_tables[0].route_table_id }}" +# vpc_id: "{{ __sap_vm_provision_task_aws_vpc_subnet_rt_info.route_tables[0].vpc_id }}" +# route_table_id: "{{ __sap_vm_provision_task_aws_vpc_subnet_rt_info.route_tables[0].route_table_id }}" # purge_subnets: false # purge_routes: false # state: present @@ -202,7 +234,6 @@ # loop: "{{ (groups['nwas_aas'] | default([])) }}" # loop_control: # loop_var: host_node -# register: aws_vpc_subnet_rt_route_sap_netweaver_aas # when: # - groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0) @@ -224,6 +255,8 @@ - name: AWS IAM Role - HA-Role-Pacemaker + register: __sap_vm_provision_task_aws_iam_role_ha_pacemaker + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.iam_role: name: "HA-Role-Pacemaker" assume_role_policy_document: | @@ -240,9 +273,13 @@ } ] } + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" # AWS HA for SAP - DataProvider - name: AWS IAM Policy - HA-Policy-DataProvider + register: __sap_vm_provision_task_aws_iam_policy_dataprovider + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.iam_policy: state: present iam_type: role @@ -272,9 +309,13 @@ } ] } + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" # AWS HA for SAP - OverlayVirtualIPAgent - name: AWS IAM Policy - HA-Policy-OverlayVirtualIPAgent + register: __sap_vm_provision_task_aws_iam_policy_overlayip + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.iam_policy: state: present iam_type: role @@ -297,13 +338,17 @@ "ec2:ReplaceRoute" ], "Effect": "Allow", - "Resource": "arn:aws:ec2:{{ sap_vm_provision_aws_region }}:{{ aws_account_info.account }}:route-table/{{ aws_vpc_subnet_rt_info.route_tables[0].route_table_id }}" + "Resource": "arn:aws:ec2:{{ sap_vm_provision_aws_region }}:{{ __sap_vm_provision_task_aws_account_info.account }}:route-table/{{ __sap_vm_provision_task_aws_vpc_subnet_rt_info.route_tables[0].route_table_id }}" } ] } + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" # AWS HA for SAP - STONITH of SAP HANA - name: AWS IAM Policy - HA-Policy-STONITH-SAPHANA + register: __sap_vm_provision_task_aws_iam_policy_stonith_saphana + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.iam_policy: state: present iam_type: role @@ -332,21 +377,25 @@ "ec2:StopInstances" ], "Resource": [ - "arn:aws:ec2:{{ sap_vm_provision_aws_region }}:{{ aws_account_info.account }}:instance/{{ hostvars[groups['hana_primary'][0]].ansible_host }}", - "arn:aws:ec2:{{ sap_vm_provision_aws_region }}:{{ aws_account_info.account }}:instance/{{ hostvars[groups['hana_secondary'][0]].ansible_host }}" + "arn:aws:ec2:{{ sap_vm_provision_aws_region }}:{{ __sap_vm_provision_task_aws_account_info.account }}:instance/{{ hostvars[groups['hana_primary'][0]].ansible_host }}", + "arn:aws:ec2:{{ sap_vm_provision_aws_region }}:{{ __sap_vm_provision_task_aws_account_info.account }}:instance/{{ hostvars[groups['hana_secondary'][0]].ansible_host }}" ] } ] } + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" when: groups["hana_secondary"] is defined and (groups["hana_secondary"]|length>0) # AWS HA for SAP - STONITH of SAP NWAS - name: AWS IAM Policy - HA-Policy-STONITH-SAPNWAS + register: __sap_vm_provision_task_aws_iam_policy_stonith_sapnwas + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.iam_policy: state: present iam_type: role iam_name: "HA-Role-Pacemaker" - policy_name: "HA-Policy-STONITH-SAPHANA" + policy_name: "HA-Policy-STONITH-SAPNWAS" policy_json: | { "Version": "2012-10-17", @@ -370,74 +419,56 @@ "ec2:StopInstances" ], "Resource": [ - "arn:aws:ec2:{{ sap_vm_provision_aws_region }}:{{ aws_account_info.account }}:instance/{{ hostvars[groups['nwas_ascs'][0]].ansible_host }}", - "arn:aws:ec2:{{ sap_vm_provision_aws_region }}:{{ aws_account_info.account }}:instance/{{ hostvars[groups['nwas_ers'][0]].ansible_host }}" + "arn:aws:ec2:{{ sap_vm_provision_aws_region }}:{{ __sap_vm_provision_task_aws_account_info.account }}:instance/{{ hostvars[groups['nwas_ascs'][0]].ansible_host }}", + "arn:aws:ec2:{{ sap_vm_provision_aws_region }}:{{ __sap_vm_provision_task_aws_account_info.account }}:instance/{{ hostvars[groups['nwas_ers'][0]].ansible_host }}" ] } ] } + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" when: groups["nwas_ers"] is defined and (groups["nwas_ers"]|length>0) - # Equivalent to # aws iam create-instance-profile --instance-profile-name "HA-Instance-Profile-Pacemaker-Cluster" # aws iam add-role-to-instance-profile --role-name "HA-Role-Pacemaker" --instance-profile-name "HA-Instance-Profile-Pacemaker-Cluster" - name: AWS IAM Instance Profile and attach AWS IAM Role - "HA-Instance-Profile-Pacemaker-Cluster" + register: __sap_vm_provision_task_aws_iam_attach_role + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.iam_instance_profile: state: present name: "HA-Instance-Profile-Pacemaker-Cluster" role: "HA-Role-Pacemaker" path: "/" - -# - name: AWS IAM Instance Profile - "HA-Instance-Profile-Pacemaker-Cluster" -# ansible.builtin.command: aws iam create-instance-profile -# --instance-profile-name "HA-Instance-Profile-Pacemaker-Cluster" -# ignore_errors: true - -# - name: AWS IAM Instance Profile attach AWS IAM Role -# ansible.builtin.command: aws iam add-role-to-instance-profile -# --role-name "HA-Role-Pacemaker" -# --instance-profile-name "HA-Instance-Profile-Pacemaker-Cluster" -# ignore_errors: true + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" # Equivalent to aws ec2 associate-iam-instance-profile --iam-instance-profile "Name=HA-Instance-Profile-Pacemaker-Cluster" --instance-id {{ hostvars[host_node].ansible_board_asset_tag }} -- name: AWS EC2 Instances - attach AWS IAM Instance Profile for SAP HANA +- name: AWS EC2 Instances - associate AWS IAM Instance Profile for SAP HANA + register: __sap_vm_provision_task_aws_iam_associate_instance_saphana + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.ec2_instance: instance_ids: "{{ hostvars[host_node].ansible_board_asset_tag }}" iam_instance_profile: "HA-Instance-Profile-Pacemaker-Cluster" + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" loop: "{{ [ [ groups['hana_primary'] | default([]) ] , [ groups['hana_secondary'] | default([]) ] ] | flatten | select() }}" loop_control: loop_var: host_node when: groups["hana_secondary"] is defined and (groups["hana_secondary"]|length>0) ignore_errors: true -# - name: AWS EC2 Instances - attach AWS IAM Instance Profile for SAP HANA -# ansible.builtin.command: aws ec2 associate-iam-instance-profile -# --iam-instance-profile "Name=HA-Instance-Profile-Pacemaker-Cluster" -# --instance-id {{ hostvars[host_node].ansible_board_asset_tag }} -# loop: "{{ [ [ groups['hana_primary'] | default([]) ] , [ groups['hana_secondary'] | default([]) ] ] | flatten | select() }}" -# loop_control: -# loop_var: host_node -# when: groups["hana_secondary"] is defined and (groups["hana_secondary"]|length>0) -# ignore_errors: true - # Equivalent to aws ec2 associate-iam-instance-profile --iam-instance-profile "Name=HA-Instance-Profile-Pacemaker-Cluster" --instance-id {{ hostvars[host_node].ansible_board_asset_tag }} -- name: AWS EC2 Instances - attach AWS IAM Instance Profile for SAP NetWeaver +- name: AWS EC2 Instances - associate AWS IAM Instance Profile for SAP NetWeaver + register: __sap_vm_provision_task_aws_iam_associate_instance_sapnwas + no_log: "{{ __sap_vm_provision_no_log }}" amazon.aws.ec2_instance: instance_ids: "{{ hostvars[host_node].ansible_board_asset_tag }}" iam_instance_profile: "HA-Instance-Profile-Pacemaker-Cluster" + access_key: "{{ sap_vm_provision_aws_access_key }}" + secret_key: "{{ sap_vm_provision_aws_secret_access_key }}" loop: "{{ [ [ groups['nwas_ascs'] | default([]) ] , [ groups['nwas_ers'] | default([]) ] , [ groups['nwas_pas'] | default([]) ] , [ groups['nwas_aas'] | default([]) ] ] | flatten | select() }}" loop_control: loop_var: host_node when: groups["nwas_ers"] is defined and (groups["nwas_ers"]|length>0) ignore_errors: true - -# - name: AWS EC2 Instances - attach AWS IAM Instance Profile for SAP NetWeaver -# ansible.builtin.command: aws ec2 associate-iam-instance-profile -# --iam-instance-profile "Name=HA-Instance-Profile-Pacemaker-Cluster" -# --instance-id {{ hostvars[host_node].ansible_board_asset_tag }} -# loop: "{{ [ [ groups['nwas_ascs'] | default([]) ] , [ groups['nwas_ers'] | default([]) ] , [ groups['nwas_pas'] | default([]) ] , [ groups['nwas_aas'] | default([]) ] ] | flatten | select() }}" -# loop_control: -# loop_var: host_node -# when: groups["nwas_ers"] is defined and (groups["nwas_ers"]|length>0) -# ignore_errors: true diff --git a/roles/sap_vm_provision/tasks/platform_ansible/gcp_ce_vm/execute_main.yml b/roles/sap_vm_provision/tasks/platform_ansible/gcp_ce_vm/execute_main.yml index e08a478..3639180 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/gcp_ce_vm/execute_main.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/gcp_ce_vm/execute_main.yml @@ -1,52 +1,64 @@ --- - name: Ansible Task block for looped provisioning of Google Cloud CE VMs - environment: - GCP_AUTH_KIND: "serviceaccount" - GCP_SERVICE_ACCOUNT_FILE: "{{ sap_vm_provision_gcp_credentials_json }}" + any_errors_fatal: true + # Using environment, no_log is ineffective and log will show 'EXEC /bin/sh -c 'ENV_VAR=value python3 /AnsiballZ_ansible_module_name.py && sleep 0' + # Therefore do not use environment for secrets, use only for non-sensitive values as this will reduce Ansible Task parameters. + # environment: + # GCP_AUTH_KIND: "serviceaccount" + # GCP_SERVICE_ACCOUNT_FILE: "{{ sap_vm_provision_gcp_credentials_json }}" block: # # Must be GlobalOnly or ZonalPreferred. The default is ZonalOnly # - name: GCP Project metadata - check VmDnsSetting variable - name: Identify GCP OS Image - register: register_gcp_os_image + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_os_image_info google.cloud.gcp_compute_image_info: project: "{{ lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_os_image_dictionary')[sap_vm_provision_gcp_ce_vm_host_os_image].project }}" filters: - family = "{{ lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_os_image_dictionary')[sap_vm_provision_gcp_ce_vm_host_os_image].family }}" - -deprecated.state = DEPRECATED + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" - name: Identify GCP Network (VPC) + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_vpc_info google.cloud.gcp_compute_network_info: project: "{{ sap_vm_provision_gcp_project }}" filters: - name = "{{ sap_vm_provision_gcp_vpc_name }}" - register: gcp_vpc_info + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" - name: Identify GCP Subnetwork (VPC Subnet) + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_vpc_subnet_info google.cloud.gcp_compute_subnetwork_info: project: "{{ sap_vm_provision_gcp_project }}" region: "{{ sap_vm_provision_gcp_region }}" filters: - name = "{{ sap_vm_provision_gcp_vpc_subnet_name }}" - register: gcp_vpc_subnet_info + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" - name: Set fact to hold loop variables from include_tasks ansible.builtin.set_fact: register_provisioned_host_all: [] - name: Provision hosts to Google Cloud - register: register_provisioned_hosts + register: __sap_vm_provision_task_provision_host_all_run ansible.builtin.include_tasks: file: "{{ 'platform_' + sap_vm_provision_iac_type }}/{{ sap_vm_provision_iac_platform }}/execute_provision.yml" - apply: - environment: - GCP_AUTH_KIND: "serviceaccount" - GCP_SERVICE_ACCOUNT_FILE: "{{ sap_vm_provision_gcp_credentials_json }}" + # apply: + # environment: + # GCP_AUTH_KIND: "serviceaccount" + # GCP_SERVICE_ACCOUNT_FILE: "{{ sap_vm_provision_gcp_credentials_json }}" - name: Add hosts provisioned to the Ansible Inventory - register: register_add_hosts + register: __sap_vm_provision_task_provision_host_all_add ansible.builtin.add_host: name: "{{ add_item[0].host_node }}" groups: "{{ add_item[0].sap_system_type + '_' if (add_item[0].sap_system_type != '') }}{{ add_item[0].sap_host_type }}" @@ -68,65 +80,110 @@ groups_merged_list: "{{ [ [ groups['hana_primary'] | default([]) ] , [ groups['hana_secondary'] | default([]) ] , [ groups['nwas_ascs'] | default([]) ] , [ groups['nwas_ers'] | default([]) ] , [ groups['nwas_pas'] | default([]) ] , [ groups['nwas_aas'] | default([]) ] ] | flatten | select() }}" - name: Set Ansible Vars - register: register_set_ansible_vars + register: __sap_vm_provision_task_ansible_vars_set ansible.builtin.include_tasks: file: common/set_ansible_vars.yml - name: Gather GCP VM information + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_info google.cloud.gcp_compute_instance_info: project: "{{ sap_vm_provision_gcp_project }}" zone: "{{ sap_vm_provision_gcp_region_zone }}" filters: - name = {{ inventory_hostname }} - register: gcp_vm_info + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" - name: Gather GCP VPC Subnet information + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_vpc_subnet_info google.cloud.gcp_compute_subnetwork_info: project: "{{ sap_vm_provision_gcp_project }}" region: "{{ sap_vm_provision_gcp_region }}" filters: - name = {{ sap_vm_provision_gcp_vpc_subnet_name }} - register: gcp_vpc_subnet_info + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" - name: Gather GCP Private DNS information + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_pdns_info google.cloud.gcp_dns_managed_zone_info: project: "{{ sap_vm_provision_gcp_project }}" dns_name: "{{ sap_vm_provision_dns_root_domain }}." - register: gcp_pdns_info + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" # - name: Gather information about GCP Router and table for the VPC Subnet + # no_log: "{{ __sap_vm_provision_no_log }}" + # register: __sap_vm_provision_task_gcp_router_info # google.cloud.gcp_compute_router_info: # project: "{{ sap_vm_provision_gcp_project }}" # region: "{{ sap_vm_provision_gcp_region }}" # filters: - # - network = "{{ gcp_vpc_info.resources[0].selfLink }}" + # - network = "{{ __sap_vm_provision_task_gcp_vpc_info.resources[0].selfLink }}" # # - name = sap-vpc-router - # register: gcp_router_info + # auth_kind: "serviceaccount" + # service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" # - name: Verify IP Forwarding for GCP VMs # ansible.builtin.fail: # msg: GCP CE VM does not have IP Forwarding enabled - # when: not gcp_vm_info.resources[0].canIpForward + # when: not __sap_vm_provision_task_provision_host_single_info.resources[0].canIpForward - name: GCP Private DNS Records for hosts + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_pdns_records google.cloud.gcp_dns_resource_record_set: state: present project: "{{ sap_vm_provision_gcp_project }}" managed_zone: - name: "{{ gcp_pdns_info.resources[0].name }}" + name: "{{ __sap_vm_provision_task_gcp_pdns_info.resources[0].name }}" dnsName: "{{ hostvars[inventory_hostname].sap_vm_provision_dns_root_domain }}." name: "{{ inventory_hostname }}.{{ hostvars[inventory_hostname].sap_vm_provision_dns_root_domain }}." target: - "{{ hostvars[inventory_hostname].ansible_host }}" type: A ttl: 7200 - register: gcp_pdns_records - until: not gcp_pdns_records.failed + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" + until: not __sap_vm_provision_task_gcp_pdns_records.failed retries: 5 delay: 5 # - ansible.builtin.debug: -# var: register_add_hosts.results +# var: __sap_vm_provision_task_provision_host_all_add.results + + rescue: + # This requires no_log set on each Ansible Task, and not set on the Ansible Task Block + # This requires an Ansible Task Block containing the Ansible Tasks for calling + # Infrastructure Platform APIs (via Ansible Modules) + - name: Show errors in task outputs + ansible.builtin.fail: + msg: "{{ lookup('ansible.builtin.vars', loop_item) }}" + loop: + - __sap_vm_provision_task_gcp_os_image_info + - __sap_vm_provision_task_gcp_vpc_info + - __sap_vm_provision_task_gcp_vpc_subnet_info + - __sap_vm_provision_task_provision_host_all_run + - __sap_vm_provision_task_provision_host_single_volumes + - __sap_vm_provision_task_provision_host_single + - __sap_vm_provision_task_provision_host_single_info + - __sap_vm_provision_task_provision_host_all_add + - __sap_vm_provision_task_gcp_vpc_subnet_info + - __sap_vm_provision_task_gcp_pdns_info + - __sap_vm_provision_task_gcp_router_info + - __sap_vm_provision_task_gcp_pdns_records + loop_control: + loop_var: loop_item + index_var: loop_item_index + label: "{{ 'Variable No. ' + (loop_item_index | string) }}" + when: + - lookup('ansible.builtin.vars', loop_item, default='') | length > 0 + - not lookup('ansible.builtin.vars', loop_item, default='') is skipped + - lookup('ansible.builtin.vars', loop_item, default='') is failed + - name: Ansible Task block to execute on target inventory hosts delegate_to: "{{ inventory_hostname }}" @@ -202,26 +259,26 @@ - name: Set /etc/hosts - register: register_etc_hosts_file + register: __sap_vm_provision_task_os_etc_hosts ansible.builtin.include_tasks: file: common/set_etc_hosts.yml - name: Set /etc/hosts for HA - register: register_etc_hosts_file_ha + register: __sap_vm_provision_task_os_etc_hosts_ha ansible.builtin.include_tasks: file: common/set_etc_hosts_ha.yml when: - (groups["hana_secondary"] is defined and (groups["hana_secondary"] | length>0)) or (groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0)) or (groups["anydb_secondary"] is defined and (groups["anydb_secondary"] | length>0)) - name: Set /etc/hosts for Scale-Out - register: register_etc_hosts_file_scaleout + register: __sap_vm_provision_task_os_etc_hosts_scaleout ansible.builtin.include_tasks: file: common/set_etc_hosts_scaleout.yml when: - - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_hana_scaleout_active_coordinator is defined or sap_hana_scaleout_active_worker is defined or sap_hana_scaleout_standby is defined) + - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined or sap_vm_provision_calculate_sap_hana_scaleout_active_worker is defined or sap_vm_provision_calculate_sap_hana_scaleout_standby is defined) - name: Set vars for sap_storage_setup Ansible Role - register: register_ansible_vars_storage + register: __sap_vm_provision_task_ansible_vars_storage ansible.builtin.include_tasks: file: common/set_ansible_vars_storage.yml @@ -242,10 +299,13 @@ - name: Ansible Task block for looped provisioning of High Availability resources for Google Cloud CE VMs delegate_to: localhost + any_errors_fatal: true run_once: true - environment: - GCP_AUTH_KIND: "serviceaccount" - GCP_SERVICE_ACCOUNT_FILE: "{{ sap_vm_provision_gcp_credentials_json }}" + # Using environment, no_log is ineffective and log will show 'EXEC /bin/sh -c 'ENV_VAR=value python3 /AnsiballZ_ansible_module_name.py && sleep 0' + # Therefore do not use environment for secrets, use only for non-sensitive values as this will reduce Ansible Task parameters. + # environment: + # GCP_AUTH_KIND: "serviceaccount" + # GCP_SERVICE_ACCOUNT_FILE: "{{ sap_vm_provision_gcp_credentials_json }}" when: - sap_ha_pacemaker_cluster_gcp_region_zone is defined - (groups["hana_secondary"] is defined and (groups["hana_secondary"] | length>0)) or (groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0)) or (groups["anydb_secondary"] is defined and (groups["anydb_secondary"] | length>0)) @@ -254,7 +314,41 @@ - name: Provision High Availability resources for GCP CE hosts ansible.builtin.include_tasks: file: "{{ 'platform_' + sap_vm_provision_iac_type }}/{{ sap_vm_provision_iac_platform }}/execute_setup_ha.yml" - apply: - environment: - GCP_AUTH_KIND: "serviceaccount" - GCP_SERVICE_ACCOUNT_FILE: "{{ sap_vm_provision_gcp_credentials_json }}" + # apply: + # environment: + # GCP_AUTH_KIND: "serviceaccount" + # GCP_SERVICE_ACCOUNT_FILE: "{{ sap_vm_provision_gcp_credentials_json }}" + + rescue: + # This requires no_log set on each Ansible Task, and not set on the Ansible Task Block + # This requires an Ansible Task Block containing the Ansible Tasks for calling + # Infrastructure Platform APIs (via Ansible Modules) + - name: Show errors in task outputs + ansible.builtin.fail: + msg: "{{ lookup('ansible.builtin.vars', loop_item) }}" + loop: + - __sap_vm_provision_task_gcp_vpc_subnet_rt_route_sap_hana + - __sap_vm_provision_task_gcp_vpc_subnet_rt_route_sap_netweaver_ascs + - __sap_vm_provision_task_gcp_vpc_subnet_rt_route_sap_netweaver_ers + - __sap_vm_provision_task_gcp_vpc_subnet_rt_route_sap_netweaver_pas + - __sap_vm_provision_task_gcp_vpc_subnet_rt_route_sap_netweaver_aas + - __sap_vm_provision_task_gcp_lb_reserved_address + - __sap_vm_provision_task_gcp_lb_healthcheck_service + - __sap_vm_provision_task_gcp_lb_healthcheck_service_ascs + - __sap_vm_provision_task_gcp_lb_healthcheck_service_ers + - __sap_vm_provision_task_provision_host_single_info + - __sap_vm_provision_task_gcp_lb_instance_group1 + - __sap_vm_provision_task_gcp_lb_instance_group2 + - __sap_vm_provision_task_gcp_lb_backend_service_regional + - __sap_vm_provision_task_gcp_lb_backend_service_regional_ascs + - __sap_vm_provision_task_gcp_lb_backend_service_regional_ers + - __sap_vm_provision_task_gcp_lb_forwarding_rule + - __sap_vm_provision_task_gcp_lb_reserved_address + loop_control: + loop_var: loop_item + index_var: loop_item_index + label: "{{ 'Variable No. ' + (loop_item_index | string) }}" + when: + - lookup('ansible.builtin.vars', loop_item, default='') | length > 0 + - not lookup('ansible.builtin.vars', loop_item, default='') is skipped + - lookup('ansible.builtin.vars', loop_item, default='') is failed diff --git a/roles/sap_vm_provision/tasks/platform_ansible/gcp_ce_vm/execute_provision.yml b/roles/sap_vm_provision/tasks/platform_ansible/gcp_ce_vm/execute_provision.yml index bb4536c..6050f77 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/gcp_ce_vm/execute_provision.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/gcp_ce_vm/execute_provision.yml @@ -1,12 +1,17 @@ --- # The tasks in this file are executed in a loop over the defined hosts +- name: Ensure short hostname is not longer than 13 characters (see SAP Note 611361) + ansible.builtin.assert: + that: (inventory_hostname | length | int) <= (13 | int) + fail_msg: "FAIL: The length of the hostname is {{ inventory_hostname | length | int }} but must be less or equal to 13 characters!" + # When SAP HANA Scale-Out is used, if host name is not in original specifications then strip suffix node number from host name - name: Set fact when performing SAP HANA Scale-Out ansible.builtin.set_fact: scaleout_origin_host_spec: "{{ inventory_hostname | regex_replace('^(.+?)\\d*$', '\\1') }}" when: - - sap_hana_scaleout_active_coordinator is defined + - sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined - not inventory_hostname in lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan].keys() # Create flat list with names for each volume to be created. @@ -38,12 +43,16 @@ # The volume creation task requires the above task to define the parameter # which contains the calculated unique device names. - name: Provision Google Cloud Persistent Disk volumes for Google Cloud VM filesystems + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_volumes google.cloud.gcp_compute_disk: state: present project: "{{ sap_vm_provision_gcp_project }}" zone: "{{ sap_vm_provision_gcp_region_zone }}" name: "{{ inventory_hostname + '-vol-' + vol_item.name | replace('_', '-')}}" size_gb: "{{ vol_item.size }}" + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" loop: "{{ storage_disks_map }}" loop_control: loop_var: vol_item @@ -51,8 +60,7 @@ label: "{{ vol_item.definition_key }}: {{ vol_item.name }} (size: {{ vol_item.size }})" when: - vol_item.size > 0 - register: volume_provisioning -# failed_when: "(volume_provisioning.msg is defined) and ('already exists' not in volume_provisioning.msg)" +# failed_when: "(__sap_vm_provision_task_provision_host_single_volumes.msg is defined) and ('already exists' not in __sap_vm_provision_task_provision_host_single_volumes.msg)" # Create list of disks to attach to GCP VM @@ -66,11 +74,11 @@ 'interface': 'SCSI', 'initialize_params': { 'disk_type': 'pd-standard', - 'source_image': register_gcp_os_image.resources[0].selfLink + 'source_image': __sap_vm_provision_task_gcp_os_image_info.resources[0].selfLink } } ] -%} - {% for storage_item in volume_provisioning.results -%} + {% for storage_item in __sap_vm_provision_task_provision_host_single_volumes.results -%} {% set vol = disks_map.extend([ { 'auto_delete': 'true', @@ -86,7 +94,8 @@ - name: Provision Google Cloud VM - register: register_provisioned_host_single + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single google.cloud.gcp_compute_instance: state: present project: "{{ sap_vm_provision_gcp_project }}" @@ -96,9 +105,9 @@ can_ip_forward: "{{ lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].disable_ip_anti_spoofing }}" # When disable the Anti IP Spoofing = true, then Can IP Forward = true network_interfaces: - network: - selfLink: "{{ gcp_vpc_info.resources[0].selfLink }}" + selfLink: "{{ __sap_vm_provision_task_gcp_vpc_info.resources[0].selfLink }}" subnetwork: - selfLink: "{{ gcp_vpc_subnet_info.resources[0].selfLink }}" + selfLink: "{{ __sap_vm_provision_task_gcp_vpc_subnet_info.resources[0].selfLink }}" # 'NVME interface is only supported for confidential VMs or the following VM families: [a3-vm, c1-metal, c2-metal, c3-metal, c3-vm, c3d-vm, ct5p-vm, g2-vm, h3-vm, m3-vm, t2a-vm] disks: "{{ provisioned_disks_map }}" metadata: @@ -110,26 +119,30 @@ scopes: - "https://www.googleapis.com/auth/cloud-platform" # Allow full access to all Cloud APIs # ["compute-rw", "storage-rw", "logging-write", "monitoring-write", "service-control", "service-management"] + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" # Required as state: present on Ansible Module gcp_compute_instance does not allow for waiting until VM has booted - name: Wait 90 seconds for Google Cloud VM to boot ansible.builtin.pause: seconds: 90 prompt: "" - when: register_provisioned_host_single.changed + when: __sap_vm_provision_task_provision_host_single.changed - name: Read Google Cloud VM information + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_info google.cloud.gcp_compute_instance_info: project: "{{ sap_vm_provision_gcp_project }}" zone: "{{ sap_vm_provision_gcp_region_zone }}" filters: - name = {{ inventory_hostname }} - register: instance_info - + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" - name: Create fact for delegate host IP ansible.builtin.set_fact: - provisioned_private_ip: "{{ register_provisioned_host_single.networkInterfaces[0].networkIP }}" + provisioned_private_ip: "{{ __sap_vm_provision_task_provision_host_single.networkInterfaces[0].networkIP }}" - name: Copy facts to delegate host @@ -141,7 +154,7 @@ delegate_sap_vm_provision_bastion_ssh_port: "{{ sap_vm_provision_bastion_ssh_port }}" delegate_sap_vm_provision_ssh_bastion_private_key_file_path: "{{ sap_vm_provision_ssh_bastion_private_key_file_path }}" delegate_sap_vm_provision_ssh_host_private_key_file_path: "{{ sap_vm_provision_ssh_host_private_key_file_path }}" - delegate_private_ip: "{{ register_provisioned_host_single.networkInterfaces[0].networkIP }}" + delegate_private_ip: "{{ __sap_vm_provision_task_provision_host_single.networkInterfaces[0].networkIP }}" delegate_hostname: "{{ inventory_hostname }}" delegate_sap_vm_provision_dns_root_domain_name: "{{ sap_vm_provision_dns_root_domain }}" @@ -172,26 +185,26 @@ {{ lookup('ansible.builtin.file', sap_vm_provision_ssh_host_public_key_file_path ) }} - name: Permit root login + register: __sap_vm_provision_task_os_sshd_config ansible.builtin.replace: path: /etc/ssh/sshd_config regexp: '(^PermitRootLogin no)' replace: 'PermitRootLogin yes' - register: sshd_config - name: Reload sshd service ansible.builtin.service: name: sshd state: reloaded when: - - sshd_config.changed + - __sap_vm_provision_task_os_sshd_config.changed ### end of block - name: Append loop value to register ansible.builtin.set_fact: - register_provisioned_host_single: "{{ register_provisioned_host_single | combine( { 'host_node' : inventory_hostname } , { 'sap_host_type' : lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_host_type } , { 'sap_system_type' : (lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_system_type | default('')) } ) }}" + __sap_vm_provision_task_provision_host_single: "{{ __sap_vm_provision_task_provision_host_single | combine( { 'host_node' : inventory_hostname } , { 'sap_host_type' : lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_host_type } , { 'sap_system_type' : (lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_system_type | default('')) } ) }}" - name: Append output to merged register ansible.builtin.set_fact: - register_provisioned_host_all: "{{ register_provisioned_host_all + [register_provisioned_host_single] }}" + register_provisioned_host_all: "{{ register_provisioned_host_all + [__sap_vm_provision_task_provision_host_single] }}" diff --git a/roles/sap_vm_provision/tasks/platform_ansible/gcp_ce_vm/execute_setup_ha.yml b/roles/sap_vm_provision/tasks/platform_ansible/gcp_ce_vm/execute_setup_ha.yml index 5d5e520..ba71fdb 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/gcp_ce_vm/execute_setup_ha.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/gcp_ce_vm/execute_setup_ha.yml @@ -4,34 +4,40 @@ # Virtual IP Address also uses subnet netmask /32 CIDR, otherwise subnet traffic attempts to route through the Load Balancer Backend Service # - name: GCP append route for SAP HANA HA (route must be outside of existing VPC Subnet Range/s) +# no_log: "{{ __sap_vm_provision_no_log }}" +# register: __sap_vm_provision_task_gcp_vpc_subnet_rt_route_sap_hana # google.cloud.gcp_compute_route: # state: present # project: "{{ sap_vm_provision_gcp_project }}" # name: "{{ sap_swpm_db_host }}-vip" # dest_range: "{{ (sap_ha_pacemaker_cluster_vip_hana_primary_ip_address | default('192.168.1.90/32')) | regex_replace('/.*', '') }}" # next_hop_instance: -# selfLink: "{{ gcp_vm_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" +# selfLink: "{{ __sap_vm_provision_task_provision_host_single_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" # network: -# selfLink: "{{ gcp_vpc_info.resources[0].selfLink }}" +# selfLink: "{{ __sap_vm_provision_task_gcp_vpc_info.resources[0].selfLink }}" +# auth_kind: "serviceaccount" +# service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" # loop: "{{ (groups['hana_primary'] | default([])) }}" # loop_control: # loop_var: host_node -# register: gcp_vpc_subnet_rt_route_sap_hana # when: # - groups["hana_secondary"] is defined and (groups["hana_secondary"] | length>0) - name: GCP Private DNS Record for SAP HANA HA Virtual Hostname + no_log: "{{ __sap_vm_provision_no_log }}" google.cloud.gcp_dns_resource_record_set: state: present project: "{{ sap_vm_provision_gcp_project }}" managed_zone: - name: "{{ gcp_pdns_info.resources[0].name }}" + name: "{{ __sap_vm_provision_task_gcp_pdns_info.resources[0].name }}" dnsName: "{{ hostvars[host_node].sap_vm_provision_dns_root_domain }}." name: "{{ sap_swpm_db_host }}.{{ hostvars[host_node].sap_vm_provision_dns_root_domain }}." target: - "{{ (sap_ha_pacemaker_cluster_vip_hana_primary_ip_address | default('192.168.1.90/32')) | regex_replace('/.*', '') }}" type: A ttl: 7200 + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" loop: "{{ (groups['hana_primary'] | default([])) }}" loop_control: loop_var: host_node @@ -40,34 +46,40 @@ # - name: GCP append route for SAP AnyDB HA (route must be outside of existing VPC Subnet Range/s) +# no_log: "{{ __sap_vm_provision_no_log }}" +# register: __sap_vm_provision_task_gcp_vpc_subnet_rt_route_sap_hana # google.cloud.gcp_compute_route: # state: present # project: "{{ sap_vm_provision_gcp_project }}" # name: "{{ sap_swpm_db_host }}-vip" # dest_range: "{{ (sap_vm_temp_vip_anydb_primary | default('192.168.1.90/32')) | regex_replace('/.*', '') }}" # next_hop_instance: -# selfLink: "{{ gcp_vm_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" +# selfLink: "{{ __sap_vm_provision_task_provision_host_single_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" # network: -# selfLink: "{{ gcp_vpc_info.resources[0].selfLink }}" +# selfLink: "{{ __sap_vm_provision_task_gcp_vpc_info.resources[0].selfLink }}" +# auth_kind: "serviceaccount" +# service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" # loop: "{{ (groups['anydb_primary'] | default([])) }}" # loop_control: # loop_var: host_node -# register: gcp_vpc_subnet_rt_route_sap_hana # when: # - groups["hana_secondary"] is defined and (groups["hana_secondary"] | length>0) - name: GCP Private DNS Record for SAP AnyDB HA Virtual Hostname + no_log: "{{ __sap_vm_provision_no_log }}" google.cloud.gcp_dns_resource_record_set: state: present project: "{{ sap_vm_provision_gcp_project }}" managed_zone: - name: "{{ gcp_pdns_info.resources[0].name }}" + name: "{{ __sap_vm_provision_task_gcp_pdns_info.resources[0].name }}" dnsName: "{{ hostvars[host_node].sap_vm_provision_dns_root_domain }}." name: "{{ sap_swpm_db_host }}.{{ hostvars[host_node].sap_vm_provision_dns_root_domain }}." target: - "{{ (sap_vm_temp_vip_anydb_primary | default('192.168.1.90/32')) | regex_replace('/.*', '') }}" type: A ttl: 7200 + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" loop: "{{ (groups['anydb_primary'] | default([])) }}" loop_control: loop_var: host_node @@ -76,34 +88,40 @@ # - name: GCP append route for SAP NetWeaver ASCS HA (route must be outside of existing VPC Subnet Range/s) +# no_log: "{{ __sap_vm_provision_no_log }}" +# register: __sap_vm_provision_task_gcp_vpc_subnet_rt_route_sap_netweaver_ascs # google.cloud.gcp_compute_route: # state: present # project: "{{ sap_vm_provision_gcp_project }}" # name: "{{ sap_swpm_ascs_instance_hostname }}-vip" # dest_range: "{{ (sap_ha_pacemaker_cluster_vip_nwas_abap_ascs_ip_address | default('192.168.2.10/32')) | regex_replace('/.*', '') }}" # next_hop_instance: -# selfLink: "{{ gcp_vm_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" +# selfLink: "{{ __sap_vm_provision_task_provision_host_single_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" # network: -# selfLink: "{{ gcp_vpc_info.resources[0].selfLink }}" +# selfLink: "{{ __sap_vm_provision_task_gcp_vpc_info.resources[0].selfLink }}" +# auth_kind: "serviceaccount" +# service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" # loop: "{{ (groups['nwas_ascs'] | default([])) }}" # loop_control: # loop_var: host_node -# register: gcp_vpc_subnet_rt_route_sap_netweaver_ascs # when: # - groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0) - name: GCP Private DNS Record for SAP NetWeaver ASCS HA Virtual Hostname + no_log: "{{ __sap_vm_provision_no_log }}" google.cloud.gcp_dns_resource_record_set: state: present project: "{{ sap_vm_provision_gcp_project }}" managed_zone: - name: "{{ gcp_pdns_info.resources[0].name }}" + name: "{{ __sap_vm_provision_task_gcp_pdns_info.resources[0].name }}" dnsName: "{{ hostvars[host_node].sap_vm_provision_dns_root_domain }}." name: "{{ sap_swpm_ascs_instance_hostname }}.{{ hostvars[host_node].sap_vm_provision_dns_root_domain }}." target: - "{{ (sap_ha_pacemaker_cluster_vip_nwas_abap_ascs_ip_address | default('192.168.2.10/32')) | regex_replace('/.*', '') }}" type: A ttl: 7200 + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" loop: "{{ (groups['nwas_ascs'] | default([])) }}" loop_control: loop_var: host_node @@ -112,34 +130,40 @@ # - name: GCP append route for SAP NetWeaver ERS HA +# no_log: "{{ __sap_vm_provision_no_log }}" +# register: __sap_vm_provision_task_gcp_vpc_subnet_rt_route_sap_netweaver_ers # google.cloud.gcp_compute_route: # state: present # project: "{{ sap_vm_provision_gcp_project }}" # name: "{{ sap_swpm_ers_instance_hostname }}-vip" # dest_range: "{{ (sap_ha_pacemaker_cluster_vip_nwas_abap_ers_ip_address | default('192.168.2.11/32')) | regex_replace('/.*', '') }}" # next_hop_instance: -# selfLink: "{{ gcp_vm_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" +# selfLink: "{{ __sap_vm_provision_task_provision_host_single_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" # network: -# selfLink: "{{ gcp_vpc_info.resources[0].selfLink }}" +# selfLink: "{{ __sap_vm_provision_task_gcp_vpc_info.resources[0].selfLink }}" +# auth_kind: "serviceaccount" +# service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" # loop: "{{ (groups['nwas_ers'] | default([])) }}" # loop_control: # loop_var: host_node -# register: gcp_vpc_subnet_rt_route_sap_netweaver_ers # when: # - groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0) - name: GCP Private DNS Record for SAP NetWeaver ERS HA Virtual Hostname + no_log: "{{ __sap_vm_provision_no_log }}" google.cloud.gcp_dns_resource_record_set: state: present project: "{{ sap_vm_provision_gcp_project }}" managed_zone: - name: "{{ gcp_pdns_info.resources[0].name }}" + name: "{{ __sap_vm_provision_task_gcp_pdns_info.resources[0].name }}" dnsName: "{{ hostvars[host_node].sap_vm_provision_dns_root_domain }}." name: "{{ sap_swpm_ers_instance_hostname }}.{{ hostvars[host_node].sap_vm_provision_dns_root_domain }}." target: - "{{ (sap_ha_pacemaker_cluster_vip_nwas_abap_ers_ip_address | default('192.168.2.11/32')) | regex_replace('/.*', '') }}" type: A ttl: 7200 + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" loop: "{{ (groups['nwas_ers'] | default([])) }}" loop_control: loop_var: host_node @@ -150,34 +174,40 @@ ## For HA of PAS and AAS, if required # - name: GCP append route for SAP NetWeaver PAS HA +# no_log: "{{ __sap_vm_provision_no_log }}" +# register: __sap_vm_provision_task_gcp_vpc_subnet_rt_route_sap_netweaver_pas # google.cloud.gcp_compute_route: # state: present # project: "{{ sap_vm_provision_gcp_project }}" # name: "{{ sap_swpm_pas_instance_hostname }}-vip" # dest_range: "{{ (sap_ha_pacemaker_cluster_vip_nwas_abap_pas_ip_address | default('192.168.2.12/32')) | regex_replace('/.*', '') }}" # next_hop_instance: -# selfLink: "{{ gcp_vm_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" +# selfLink: "{{ __sap_vm_provision_task_provision_host_single_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" # network: -# selfLink: "{{ gcp_vpc_info.resources[0].selfLink }}" +# selfLink: "{{ __sap_vm_provision_task_gcp_vpc_info.resources[0].selfLink }}" +# auth_kind: "serviceaccount" +# service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" # loop: "{{ (groups['nwas_pas'] | default([])) }}" # loop_control: # loop_var: host_node -# register: gcp_vpc_subnet_rt_route_sap_netweaver_pas # when: # - groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0) # - name: GCP Private DNS Record for SAP NetWeaver PAS HA Virtual Hostname +# no_log: "{{ __sap_vm_provision_no_log }}" # google.cloud.gcp_dns_resource_record_set: # state: present # project: "{{ sap_vm_provision_gcp_project }}" # managed_zone: -# name: "{{ gcp_pdns_info.resources[0].name }}" +# name: "{{ __sap_vm_provision_task_gcp_pdns_info.resources[0].name }}" # dnsName: "{{ hostvars[host_node].sap_vm_provision_dns_root_domain }}." # name: "{{ sap_swpm_pas_instance_hostname }}.{{ hostvars[host_node].sap_vm_provision_dns_root_domain }}." # target: # - "{{ (sap_ha_pacemaker_cluster_vip_nwas_abap_pas_ip_address | default('192.168.2.12/32')) | regex_replace('/.*', '') }}" # type: A # ttl: 7200 +# auth_kind: "serviceaccount" +# service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" # loop: "{{ (groups['nwas_pas'] | default([])) }}" # loop_control: # loop_var: host_node @@ -186,34 +216,40 @@ # - name: GCP append route for SAP NetWeaver AAS HA +# no_log: "{{ __sap_vm_provision_no_log }}" +# register: __sap_vm_provision_task_gcp_vpc_subnet_rt_route_sap_netweaver_aas # google.cloud.gcp_compute_route: # state: present # project: "{{ sap_vm_provision_gcp_project }}" # name: "{{ sap_swpm_aas_instance_hostname }}-vip" # dest_range: "{{ (sap_ha_pacemaker_cluster_vip_nwas_abap_aas_ip_address | default('192.168.2.13/32')) | regex_replace('/.*', '') }}" # next_hop_instance: -# selfLink: "{{ gcp_vm_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" +# selfLink: "{{ __sap_vm_provision_task_provision_host_single_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" # network: -# selfLink: "{{ gcp_vpc_info.resources[0].selfLink }}" +# selfLink: "{{ __sap_vm_provision_task_gcp_vpc_info.resources[0].selfLink }}" +# auth_kind: "serviceaccount" +# service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" # loop: "{{ (groups['nwas_aas'] | default([])) }}" # loop_control: # loop_var: host_node -# register: gcp_vpc_subnet_rt_route_sap_netweaver_aas # when: # - groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0) # - name: GCP Private DNS Record for SAP NetWeaver AAS HA Virtual Hostname +# no_log: "{{ __sap_vm_provision_no_log }}" # google.cloud.gcp_dns_resource_record_set: # state: present # project: "{{ sap_vm_provision_gcp_project }}" # managed_zone: -# name: "{{ gcp_pdns_info.resources[0].name }}" +# name: "{{ __sap_vm_provision_task_gcp_pdns_info.resources[0].name }}" # dnsName: "{{ hostvars[host_node].sap_vm_provision_dns_root_domain }}." # name: "{{ sap_swpm_aas_instance_hostname }}.{{ hostvars[host_node].sap_vm_provision_dns_root_domain }}." # target: # - "{{ (sap_ha_pacemaker_cluster_vip_nwas_abap_aas_ip_address | default('192.168.2.13/32')) | regex_replace('/.*', '') }}" # type: A # ttl: 7200 +# auth_kind: "serviceaccount" +# service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" # loop: "{{ (groups['nwas_aas'] | default([])) }}" # loop_control: # loop_var: host_node @@ -237,17 +273,20 @@ # tcpdump -i eth0 net 130.211.0.0/22 and dst port 55550/55551/55552 - name: Create Google Cloud Compute Engine Reserved Static Internal IP Address for the Virtual IP (VIP) of SAP HANA + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_reserved_address google.cloud.gcp_compute_address: state: present project: "{{ sap_vm_provision_gcp_project }}" region: "{{ sap_vm_provision_gcp_region }}" - subnetwork: { "selfLink": "{{ gcp_vpc_subnet_info.resources[0].selfLink }}" } + subnetwork: { "selfLink": "{{ __sap_vm_provision_task_gcp_vpc_subnet_info.resources[0].selfLink }}" } name: "lb-reserved-static-ip-vip-hana-{{ vip_item_nr }}" address_type: internal address: "{{ vip_item | regex_replace('/.*', '') }}" #network_tier: PREMIUM # An address with type INTERNAL cannot have a network tier purpose: GCE_ENDPOINT # GCE_ENDPOINT is for addresses used by VMs, alias IP ranges, and internal load balancers - register: gcp_lb_reserved_address + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - vip_item | length > 0 - groups["hana_secondary"] is defined and (groups["hana_secondary"]|length>0) @@ -258,6 +297,8 @@ loop_var: vip_item - name: Create Google Cloud Compute Engine Health Check (Global) service instance for SAP HANA + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_healthcheck_service google.cloud.gcp_compute_health_check: state: present project: "{{ sap_vm_provision_gcp_project }}" @@ -270,17 +311,21 @@ timeout_sec: 10 unhealthy_threshold: 2 healthy_threshold: 2 - register: gcp_lb_healthcheck_service + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - groups["hana_secondary"] is defined and (groups["hana_secondary"]|length>0) - name: Gather GCP VM information + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_info google.cloud.gcp_compute_instance_info: project: "{{ sap_vm_provision_gcp_project }}" zone: "{{ sap_vm_provision_gcp_region_zone }}" filters: - name = {{ host_node }} - register: gcp_vm_info + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" loop: "{{ groups_merged_list }}" loop_control: loop_var: host_node @@ -288,17 +333,20 @@ - groups["hana_secondary"] is defined and (groups["hana_secondary"]|length>0) - name: Create Google Cloud Compute Engine Instance Group (Self-Managed/Unmanaged) Primary - for SAP HANA + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_instance_group1 google.cloud.gcp_compute_instance_group: state: present project: "{{ sap_vm_provision_gcp_project }}" name: "lb-instance-group-hana-primary" - zone: "{{ gcp_vm_info | json_query('results[*].resources[?name==`' + host_node + '`].zone') | flatten | join(' ') | basename }}" + zone: "{{ __sap_vm_provision_task_provision_host_single_info | json_query('results[*].resources[?name==`' + host_node + '`].zone') | flatten | join(' ') | basename }}" instances: - - { "selfLink": "{{ gcp_vm_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" } + - { "selfLink": "{{ __sap_vm_provision_task_provision_host_single_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" } #named_ports: # - name: http # default, not applicable to internal passthrough NLB, only applicable to proxy NLB # port: 80 # default - register: gcp_lb_instance_group1 + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" loop: "{{ (groups['hana_primary'] | default([])) }}" loop_control: loop_var: host_node @@ -306,17 +354,20 @@ - groups["hana_secondary"] is defined and (groups["hana_secondary"]|length>0) - name: Create Google Cloud Compute Engine Instance Group (Self-Managed/Unmanaged) Secondary (Failover) - for SAP HANA + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_instance_group2 google.cloud.gcp_compute_instance_group: state: present project: "{{ sap_vm_provision_gcp_project }}" name: "lb-instance-group-hana-secondary" - zone: "{{ gcp_vm_info | json_query('results[*].resources[?name==`' + host_node + '`].zone') | flatten | join(' ') | basename }}" + zone: "{{ __sap_vm_provision_task_provision_host_single_info | json_query('results[*].resources[?name==`' + host_node + '`].zone') | flatten | join(' ') | basename }}" instances: - - { "selfLink": "{{ gcp_vm_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" } + - { "selfLink": "{{ __sap_vm_provision_task_provision_host_single_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" } #named_ports: # - name: http # default, not applicable to internal passthrough NLB, only applicable to proxy NLB # port: 80 # default - register: gcp_lb_instance_group2 + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" loop: "{{ (groups['hana_secondary'] | default([])) }}" loop_control: loop_var: host_node @@ -326,20 +377,22 @@ # Note: Failover Ratio must be 1.0, which enforces failover to Secondary/Failover Instance Group if any VM the Backend Service's Primary Instance Group # No option for --global-health-checks ? - name: Create Google Cloud Compute Engine Backend Service (Regional) for the Internal passthrough Network Load Balancer used by SAP HANA + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_backend_service_regional google.cloud.gcp_compute_region_backend_service: state: present project: "{{ sap_vm_provision_gcp_project }}" region: "{{ sap_vm_provision_gcp_region }}" name: "lb-backend-service-hana" backends: - - group: "{{ gcp_lb_instance_group1.results[0].selfLink }}" + - group: "{{ __sap_vm_provision_task_gcp_lb_instance_group1.results[0].selfLink }}" balancing_mode: CONNECTION # UTILIZATION , RATE , CONNECTION #failover: false # Should be unset according to GCP for SAP documentation, which is different than set to false - - group: "{{ gcp_lb_instance_group2.results[0].selfLink }}" + - group: "{{ __sap_vm_provision_task_gcp_lb_instance_group2.results[0].selfLink }}" balancing_mode: CONNECTION # UTILIZATION , RATE , CONNECTION failover: true health_checks: - - "{{ gcp_lb_healthcheck_service.selfLink }}" + - "{{ __sap_vm_provision_task_gcp_lb_healthcheck_service.selfLink }}" load_balancing_scheme: INTERNAL failover_policy: disable_connection_drain_on_failover: true @@ -347,11 +400,14 @@ failover_ratio: 1 # 1.0 session_affinity: NONE #timeout_sec: 30 # value ignored for internal passthrough NLB, default 30s to wait for backend before failure - see https://cloud.google.com/load-balancing/docs/backend-service#timeout-setting - register: gcp_lb_backend_service_regional + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - groups["hana_secondary"] is defined and (groups["hana_secondary"]|length>0) - name: Create Google Cloud Compute Engine Forwarding Rule (aka. Frontend IP and Port) for SAP HANA + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_forwarding_rule google.cloud.gcp_compute_forwarding_rule: state: present project: "{{ sap_vm_provision_gcp_project }}" @@ -361,12 +417,13 @@ ip_address: "{{ vip_item | regex_replace('/.*', '') }}" all_ports: true # For internal network load balancing, allow any ports to be forwarded to the backend service (can not be set if ports are defined) allow_global_access: false # Only for use if access to the SAP HANA Database Server is required from outside of the GCP Region - backend_service: { "selfLink": "{{ gcp_lb_backend_service_regional.selfLink }}" } # Mandatory, otherwise error "Invalid value for field 'resource.target'" + backend_service: { "selfLink": "{{ __sap_vm_provision_task_gcp_lb_backend_service_regional.selfLink }}" } # Mandatory, otherwise error "Invalid value for field 'resource.target'" #backend_service: { "selfLink": "https://www.googleapis.com/compute/v1/projects/{{ sap_vm_provision_gcp_project }}/regions/{{ sap_vm_provision_gcp_region }}/backendServices/lb-backend-service-hana" } - subnetwork: { "selfLink": "{{ gcp_vpc_subnet_info.resources[0].selfLink }}" } + subnetwork: { "selfLink": "{{ __sap_vm_provision_task_gcp_vpc_subnet_info.resources[0].selfLink }}" } load_balancing_scheme: INTERNAL network_tier: PREMIUM - register: gcp_lb_forwarding_rule + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - vip_item | length > 0 - groups["hana_secondary"] is defined and (groups["hana_secondary"]|length>0) @@ -377,28 +434,34 @@ loop_var: vip_item - name: Get information on Google Cloud Compute Engine (Regional) Backend Service + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_backend_service_regional google.cloud.gcp_compute_region_backend_service_info: project: "{{ sap_vm_provision_gcp_project }}" region: "{{ sap_vm_provision_gcp_region }}" filters: - name = "lb-backend-service-hana" - register: gcp_info_lb_backend_service_regional + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - groups["hana_secondary"] is defined and (groups["hana_secondary"]|length>0) - name: Create Google Cloud Compute Engine Reserved Static Internal IP Address for the Virtual IP (VIP) of SAP AnyDB + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_reserved_address google.cloud.gcp_compute_address: state: present project: "{{ sap_vm_provision_gcp_project }}" region: "{{ sap_vm_provision_gcp_region }}" - subnetwork: { "selfLink": "{{ gcp_vpc_subnet_info.resources[0].selfLink }}" } + subnetwork: { "selfLink": "{{ __sap_vm_provision_task_gcp_vpc_subnet_info.resources[0].selfLink }}" } name: "lb-reserved-static-ip-vip-anydb-{{ vip_item_nr }}" address_type: internal address: "{{ vip_item | regex_replace('/.*', '') }}" #network_tier: PREMIUM # An address with type INTERNAL cannot have a network tier purpose: GCE_ENDPOINT # GCE_ENDPOINT is for addresses used by VMs, alias IP ranges, and internal load balancers - register: gcp_lb_reserved_address + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - vip_item | length > 0 - groups["anydb_secondary"] is defined and (groups["anydb_secondary"]|length>0) @@ -409,6 +472,8 @@ loop_var: vip_item - name: Create Google Cloud Compute Engine Health Check (Global) service instance for SAP AnyDB + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_healthcheck_service google.cloud.gcp_compute_health_check: state: present project: "{{ sap_vm_provision_gcp_project }}" @@ -421,17 +486,21 @@ timeout_sec: 10 unhealthy_threshold: 2 healthy_threshold: 2 - register: gcp_lb_healthcheck_service + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - groups["anydb_secondary"] is defined and (groups["anydb_secondary"]|length>0) - name: Gather GCP VM information + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_info google.cloud.gcp_compute_instance_info: project: "{{ sap_vm_provision_gcp_project }}" zone: "{{ sap_vm_provision_gcp_region_zone }}" filters: - name = {{ host_node }} - register: gcp_vm_info + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" loop: "{{ groups_merged_list }}" loop_control: loop_var: host_node @@ -439,17 +508,20 @@ - groups["anydb_secondary"] is defined and (groups["anydb_secondary"]|length>0) - name: Create Google Cloud Compute Engine Instance Group (Self-Managed/Unmanaged) Primary - for SAP AnyDB + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_instance_group1 google.cloud.gcp_compute_instance_group: state: present project: "{{ sap_vm_provision_gcp_project }}" name: "lb-instance-group-anydb-primary" - zone: "{{ gcp_vm_info | json_query('results[*].resources[?name==`' + host_node + '`].zone') | flatten | join(' ') | basename }}" + zone: "{{ __sap_vm_provision_task_provision_host_single_info | json_query('results[*].resources[?name==`' + host_node + '`].zone') | flatten | join(' ') | basename }}" instances: - - { "selfLink": "{{ gcp_vm_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" } + - { "selfLink": "{{ __sap_vm_provision_task_provision_host_single_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" } #named_ports: # - name: http # default, not applicable to internal passthrough NLB, only applicable to proxy NLB # port: 80 # default - register: gcp_lb_instance_group1 + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" loop: "{{ (groups['anydb_primary'] | default([])) }}" loop_control: loop_var: host_node @@ -457,17 +529,20 @@ - groups["anydb_secondary"] is defined and (groups["anydb_secondary"]|length>0) - name: Create Google Cloud Compute Engine Instance Group (Self-Managed/Unmanaged) Secondary (Failover) - for SAP AnyDB + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_instance_group2 google.cloud.gcp_compute_instance_group: state: present project: "{{ sap_vm_provision_gcp_project }}" name: "lb-instance-group-anydb-secondary" - zone: "{{ gcp_vm_info | json_query('results[*].resources[?name==`' + host_node + '`].zone') | flatten | join(' ') | basename }}" + zone: "{{ __sap_vm_provision_task_provision_host_single_info | json_query('results[*].resources[?name==`' + host_node + '`].zone') | flatten | join(' ') | basename }}" instances: - - { "selfLink": "{{ gcp_vm_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" } + - { "selfLink": "{{ __sap_vm_provision_task_provision_host_single_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" } #named_ports: # - name: http # default, not applicable to internal passthrough NLB, only applicable to proxy NLB # port: 80 # default - register: gcp_lb_instance_group2 + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" loop: "{{ (groups['anydb_secondary'] | default([])) }}" loop_control: loop_var: host_node @@ -477,20 +552,22 @@ # Note: Failover Ratio must be 1.0, which enforces failover to Secondary/Failover Instance Group if any VM the Backend Service's Primary Instance Group # No option for --global-health-checks ? - name: Create Google Cloud Compute Engine Backend Service (Regional) for the Internal passthrough Network Load Balancer used by SAP AnyDB + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_backend_service_regional google.cloud.gcp_compute_region_backend_service: state: present project: "{{ sap_vm_provision_gcp_project }}" region: "{{ sap_vm_provision_gcp_region }}" name: "lb-backend-service-anydb" backends: - - group: "{{ gcp_lb_instance_group1.results[0].selfLink }}" + - group: "{{ __sap_vm_provision_task_gcp_lb_instance_group1.results[0].selfLink }}" balancing_mode: CONNECTION # UTILIZATION , RATE , CONNECTION #failover: false # Should be unset according to GCP for SAP documentation, which is different than set to false - - group: "{{ gcp_lb_instance_group2.results[0].selfLink }}" + - group: "{{ __sap_vm_provision_task_gcp_lb_instance_group2.results[0].selfLink }}" balancing_mode: CONNECTION # UTILIZATION , RATE , CONNECTION failover: true health_checks: - - "{{ gcp_lb_healthcheck_service.selfLink }}" + - "{{ __sap_vm_provision_task_gcp_lb_healthcheck_service.selfLink }}" load_balancing_scheme: INTERNAL failover_policy: disable_connection_drain_on_failover: true @@ -498,11 +575,14 @@ failover_ratio: 1 # 1.0 session_affinity: NONE #timeout_sec: 30 # value ignored for internal passthrough NLB, default 30s to wait for backend before failure - see https://cloud.google.com/load-balancing/docs/backend-service#timeout-setting - register: gcp_lb_backend_service_regional + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - groups["anydb_secondary"] is defined and (groups["anydb_secondary"]|length>0) - name: Create Google Cloud Compute Engine Forwarding Rule (aka. Frontend IP and Port) for SAP AnyDB + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_forwarding_rule google.cloud.gcp_compute_forwarding_rule: state: present project: "{{ sap_vm_provision_gcp_project }}" @@ -512,12 +592,13 @@ ip_address: "{{ vip_item | regex_replace('/.*', '') }}" all_ports: true # For internal network load balancing, allow any ports to be forwarded to the backend service (can not be set if ports are defined) allow_global_access: false # Only for use if access to the SAP AnyDB Database Server is required from outside of the GCP Region - backend_service: { "selfLink": "{{ gcp_lb_backend_service_regional.selfLink }}" } # Mandatory, otherwise error "Invalid value for field 'resource.target'" + backend_service: { "selfLink": "{{ __sap_vm_provision_task_gcp_lb_backend_service_regional.selfLink }}" } # Mandatory, otherwise error "Invalid value for field 'resource.target'" #backend_service: { "selfLink": "https://www.googleapis.com/compute/v1/projects/{{ sap_vm_provision_gcp_project }}/regions/{{ sap_vm_provision_gcp_region }}/backendServices/lb-backend-service-anydb" } - subnetwork: { "selfLink": "{{ gcp_vpc_subnet_info.resources[0].selfLink }}" } + subnetwork: { "selfLink": "{{ __sap_vm_provision_task_gcp_vpc_subnet_info.resources[0].selfLink }}" } load_balancing_scheme: INTERNAL network_tier: PREMIUM - register: gcp_lb_forwarding_rule + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - vip_item | length > 0 - groups["anydb_secondary"] is defined and (groups["anydb_secondary"]|length>0) @@ -528,47 +609,58 @@ loop_var: vip_item - name: Get information on Google Cloud Compute Engine (Regional) Backend Service + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_backend_service_regional google.cloud.gcp_compute_region_backend_service_info: project: "{{ sap_vm_provision_gcp_project }}" region: "{{ sap_vm_provision_gcp_region }}" filters: - name = "lb-backend-service-anydb" - register: gcp_info_lb_backend_service_regional + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - groups["anydb_secondary"] is defined and (groups["anydb_secondary"]|length>0) - name: Create Google Cloud Compute Engine Reserved Static Internal IP Address for the Virtual IP (VIP) of SAP NetWeaver ASCS + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_reserved_address google.cloud.gcp_compute_address: state: present project: "{{ sap_vm_provision_gcp_project }}" region: "{{ sap_vm_provision_gcp_region }}" - subnetwork: { "selfLink": "{{ gcp_vpc_subnet_info.resources[0].selfLink }}" } + subnetwork: { "selfLink": "{{ __sap_vm_provision_task_gcp_vpc_subnet_info.resources[0].selfLink }}" } name: "lb-reserved-static-ip-vip-nwas-ascs" address_type: internal address: "{{ sap_ha_pacemaker_cluster_vip_nwas_abap_ascs_ip_address | regex_replace('/.*', '') }}" #network_tier: PREMIUM # An address with type INTERNAL cannot have a network tier purpose: GCE_ENDPOINT # GCE_ENDPOINT is for addresses used by VMs, alias IP ranges, and internal load balancers - register: gcp_lb_reserved_address + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - groups["nwas_ers"] is defined and (groups["nwas_ers"]|length>0) - name: Create Google Cloud Compute Engine Reserved Static Internal IP Address for the Virtual IP (VIP) of SAP NetWeaver ERS + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_reserved_address google.cloud.gcp_compute_address: state: present project: "{{ sap_vm_provision_gcp_project }}" region: "{{ sap_vm_provision_gcp_region }}" - subnetwork: { "selfLink": "{{ gcp_vpc_subnet_info.resources[0].selfLink }}" } + subnetwork: { "selfLink": "{{ __sap_vm_provision_task_gcp_vpc_subnet_info.resources[0].selfLink }}" } name: "lb-reserved-static-ip-vip-nwas-ers" address_type: internal address: "{{ sap_ha_pacemaker_cluster_vip_nwas_abap_ers_ip_address | regex_replace('/.*', '') }}" #network_tier: PREMIUM # An address with type INTERNAL cannot have a network tier purpose: GCE_ENDPOINT # GCE_ENDPOINT is for addresses used by VMs, alias IP ranges, and internal load balancers - register: gcp_lb_reserved_address + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - groups["nwas_ers"] is defined and (groups["nwas_ers"]|length>0) - name: Create Google Cloud Compute Engine Health Check (Global) service instance for SAP NetWeaver ASCS + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_healthcheck_service_ascs google.cloud.gcp_compute_health_check: state: present project: "{{ sap_vm_provision_gcp_project }}" @@ -581,11 +673,14 @@ timeout_sec: 10 unhealthy_threshold: 2 healthy_threshold: 2 - register: gcp_lb_healthcheck_service_ascs + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - groups["nwas_ers"] is defined and (groups["nwas_ers"]|length>0) - name: Create Google Cloud Compute Engine Health Check (Global) service instance for SAP NetWeaver ERS + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_healthcheck_service_ers google.cloud.gcp_compute_health_check: state: present project: "{{ sap_vm_provision_gcp_project }}" @@ -598,17 +693,21 @@ timeout_sec: 10 unhealthy_threshold: 2 healthy_threshold: 2 - register: gcp_lb_healthcheck_service_ers + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - groups["nwas_ers"] is defined and (groups["nwas_ers"]|length>0) - name: Gather GCP VM information + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_info google.cloud.gcp_compute_instance_info: project: "{{ sap_vm_provision_gcp_project }}" zone: "{{ sap_vm_provision_gcp_region_zone }}" filters: - name = {{ host_node }} - register: gcp_vm_info + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" loop: "{{ groups_merged_list }}" loop_control: loop_var: host_node @@ -616,17 +715,20 @@ - groups["nwas_ers"] is defined and (groups["nwas_ers"]|length>0) - name: Create Google Cloud Compute Engine Instance Group (Self-Managed/Unmanaged) Primary - for SAP NetWeaver ASCS + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_instance_group1 google.cloud.gcp_compute_instance_group: state: present project: "{{ sap_vm_provision_gcp_project }}" name: "lb-instance-group-nwas-ascs" - zone: "{{ gcp_vm_info | json_query('results[*].resources[?name==`' + host_node + '`].zone') | flatten | join(' ') | basename }}" + zone: "{{ __sap_vm_provision_task_provision_host_single_info | json_query('results[*].resources[?name==`' + host_node + '`].zone') | flatten | join(' ') | basename }}" instances: - - { "selfLink": "{{ gcp_vm_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" } + - { "selfLink": "{{ __sap_vm_provision_task_provision_host_single_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" } #named_ports: # - name: http # default, not applicable to internal passthrough NLB, only applicable to proxy NLB # port: 80 # default - register: gcp_lb_instance_group1 + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" loop: "{{ (groups['nwas_ascs'] | default([])) }}" loop_control: loop_var: host_node @@ -634,17 +736,20 @@ - groups["nwas_ers"] is defined and (groups["nwas_ers"]|length>0) - name: Create Google Cloud Compute Engine Instance Group (Self-Managed/Unmanaged) Secondary (Failover) - for SAP NetWeaver ERS + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_instance_group2 google.cloud.gcp_compute_instance_group: state: present project: "{{ sap_vm_provision_gcp_project }}" name: "lb-instance-group-nwas-ers" - zone: "{{ gcp_vm_info | json_query('results[*].resources[?name==`' + host_node + '`].zone') | flatten | join(' ') | basename }}" + zone: "{{ __sap_vm_provision_task_provision_host_single_info | json_query('results[*].resources[?name==`' + host_node + '`].zone') | flatten | join(' ') | basename }}" instances: - - { "selfLink": "{{ gcp_vm_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" } + - { "selfLink": "{{ __sap_vm_provision_task_provision_host_single_info | json_query('results[*].resources[?name==`' + host_node + '`].selfLink') | flatten | join(' ') }}" } #named_ports: # - name: http # default, not applicable to internal passthrough NLB, only applicable to proxy NLB # port: 80 # default - register: gcp_lb_instance_group2 + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" loop: "{{ (groups['nwas_ers'] | default([])) }}" loop_control: loop_var: host_node @@ -654,20 +759,22 @@ # Note: Failover Ratio must be 1.0, which enforces failover to Secondary/Failover Instance Group if any VM the Backend Service's Primary Instance Group # No option for --global-health-checks ? - name: Create Google Cloud Compute Engine Backend Service (Regional) for the Internal passthrough Network Load Balancer used by SAP NetWeaver ASCS + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_backend_service_regional_ascs google.cloud.gcp_compute_region_backend_service: state: present project: "{{ sap_vm_provision_gcp_project }}" region: "{{ sap_vm_provision_gcp_region }}" name: "lb-backend-service-nwas-ascs" backends: - - group: "{{ gcp_lb_instance_group1.results[0].selfLink }}" + - group: "{{ __sap_vm_provision_task_gcp_lb_instance_group1.results[0].selfLink }}" balancing_mode: CONNECTION # UTILIZATION , RATE , CONNECTION #failover: false # Should be unset according to GCP for SAP documentation, which is different than set to false - - group: "{{ gcp_lb_instance_group2.results[0].selfLink }}" + - group: "{{ __sap_vm_provision_task_gcp_lb_instance_group2.results[0].selfLink }}" balancing_mode: CONNECTION # UTILIZATION , RATE , CONNECTION failover: true health_checks: - - "{{ gcp_lb_healthcheck_service_ascs.selfLink }}" + - "{{ __sap_vm_provision_task_gcp_lb_healthcheck_service_ascs.selfLink }}" load_balancing_scheme: INTERNAL failover_policy: disable_connection_drain_on_failover: true @@ -675,27 +782,30 @@ failover_ratio: 1 # 1.0 session_affinity: NONE #timeout_sec: 30 # value ignored for internal passthrough NLB, default 30s to wait for backend before failure - see https://cloud.google.com/load-balancing/docs/backend-service#timeout-setting - register: gcp_lb_backend_service_regional_ascs + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - groups["nwas_ers"] is defined and (groups["nwas_ers"]|length>0) # Note: Failover Ratio must be 1.0, which enforces failover to Secondary/Failover Instance Group if any VM the Backend Service's Primary Instance Group # No option for --global-health-checks ? - name: Create Google Cloud Compute Engine Backend Service (Regional) for the Internal passthrough Network Load Balancer used by SAP NetWeaver ERS + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_backend_service_regional_ers google.cloud.gcp_compute_region_backend_service: state: present project: "{{ sap_vm_provision_gcp_project }}" region: "{{ sap_vm_provision_gcp_region }}" name: "lb-backend-service-nwas-ers" backends: - - group: "{{ gcp_lb_instance_group2.results[0].selfLink }}" + - group: "{{ __sap_vm_provision_task_gcp_lb_instance_group2.results[0].selfLink }}" balancing_mode: CONNECTION # UTILIZATION , RATE , CONNECTION #failover: false # Should be unset according to GCP for SAP documentation, which is different than set to false - - group: "{{ gcp_lb_instance_group1.results[0].selfLink }}" + - group: "{{ __sap_vm_provision_task_gcp_lb_instance_group1.results[0].selfLink }}" balancing_mode: CONNECTION # UTILIZATION , RATE , CONNECTION failover: true health_checks: - - "{{ gcp_lb_healthcheck_service_ers.selfLink }}" + - "{{ __sap_vm_provision_task_gcp_lb_healthcheck_service_ers.selfLink }}" load_balancing_scheme: INTERNAL failover_policy: disable_connection_drain_on_failover: true @@ -703,11 +813,14 @@ failover_ratio: 1 # 1.0 session_affinity: NONE #timeout_sec: 30 # value ignored for internal passthrough NLB, default 30s to wait for backend before failure - see https://cloud.google.com/load-balancing/docs/backend-service#timeout-setting - register: gcp_lb_backend_service_regional_ers + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - groups["nwas_ers"] is defined and (groups["nwas_ers"]|length>0) - name: Create Google Cloud Compute Engine Forwarding Rule (aka. Frontend IP and Port) for SAP NetWeaver ASCS + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_forwarding_rule google.cloud.gcp_compute_forwarding_rule: state: present project: "{{ sap_vm_provision_gcp_project }}" @@ -717,16 +830,19 @@ ip_address: "{{ sap_ha_pacemaker_cluster_vip_nwas_abap_ascs_ip_address | regex_replace('/.*', '') }}" all_ports: true # For internal network load balancing, allow any ports to be forwarded to the backend service (can not be set if ports are defined) allow_global_access: false # Only for use if access to the SAP NetWeaver Database Server is required from outside of the GCP Region - backend_service: { "selfLink": "{{ gcp_lb_backend_service_regional_ascs.selfLink }}" } # Mandatory, otherwise error "Invalid value for field 'resource.target'" + backend_service: { "selfLink": "{{ __sap_vm_provision_task_gcp_lb_backend_service_regional_ascs.selfLink }}" } # Mandatory, otherwise error "Invalid value for field 'resource.target'" #backend_service: { "selfLink": "https://www.googleapis.com/compute/v1/projects/{{ sap_vm_provision_gcp_project }}/regions/{{ sap_vm_provision_gcp_region }}/backendServices/lb-backend-service-nwas-ascs" } - subnetwork: { "selfLink": "{{ gcp_vpc_subnet_info.resources[0].selfLink }}" } + subnetwork: { "selfLink": "{{ __sap_vm_provision_task_gcp_vpc_subnet_info.resources[0].selfLink }}" } load_balancing_scheme: INTERNAL network_tier: PREMIUM - register: gcp_lb_forwarding_rule + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - groups["nwas_ers"] is defined and (groups["nwas_ers"]|length>0) - name: Create Google Cloud Compute Engine Forwarding Rule (aka. Frontend IP and Port) for SAP NetWeaver ERS + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_forwarding_rule google.cloud.gcp_compute_forwarding_rule: state: present project: "{{ sap_vm_provision_gcp_project }}" @@ -736,32 +852,39 @@ ip_address: "{{ sap_ha_pacemaker_cluster_vip_nwas_abap_ers_ip_address | regex_replace('/.*', '') }}" all_ports: true # For internal network load balancing, allow any ports to be forwarded to the backend service (can not be set if ports are defined) allow_global_access: false # Only for use if access to the SAP NetWeaver Database Server is required from outside of the GCP Region - backend_service: { "selfLink": "{{ gcp_lb_backend_service_regional_ascs.selfLink }}" } # Mandatory, otherwise error "Invalid value for field 'resource.target'" + backend_service: { "selfLink": "{{ __sap_vm_provision_task_gcp_lb_backend_service_regional_ascs.selfLink }}" } # Mandatory, otherwise error "Invalid value for field 'resource.target'" #backend_service: { "selfLink": "https://www.googleapis.com/compute/v1/projects/{{ sap_vm_provision_gcp_project }}/regions/{{ sap_vm_provision_gcp_region }}/backendServices/lb-backend-service-nwas-ascs" } - subnetwork: { "selfLink": "{{ gcp_vpc_subnet_info.resources[0].selfLink }}" } + subnetwork: { "selfLink": "{{ __sap_vm_provision_task_gcp_vpc_subnet_info.resources[0].selfLink }}" } load_balancing_scheme: INTERNAL network_tier: PREMIUM - register: gcp_lb_forwarding_rule + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - groups["nwas_ers"] is defined and (groups["nwas_ers"]|length>0) - name: Get information on Google Cloud Compute Engine (Regional) Backend Service for SAP NetWeaver ASCS + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_backend_service_regional google.cloud.gcp_compute_region_backend_service_info: project: "{{ sap_vm_provision_gcp_project }}" region: "{{ sap_vm_provision_gcp_region }}" filters: - name = "lb-backend-service-nwas-ascs" - register: gcp_info_lb_backend_service_regional + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - groups["nwas_ers"] is defined and (groups["nwas_ers"]|length>0) - name: Get information on Google Cloud Compute Engine (Regional) Backend Service for SAP NetWeaver ERS + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_backend_service_regional google.cloud.gcp_compute_region_backend_service_info: project: "{{ sap_vm_provision_gcp_project }}" region: "{{ sap_vm_provision_gcp_region }}" filters: - name = "lb-backend-service-nwas-ers" - register: gcp_info_lb_backend_service_regional + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - groups["nwas_ers"] is defined and (groups["nwas_ers"]|length>0) diff --git a/roles/sap_vm_provision/tasks/platform_ansible/gcp_ce_vm/post_deployment_execute.yml b/roles/sap_vm_provision/tasks/platform_ansible/gcp_ce_vm/post_deployment_execute.yml index 6941662..d9dc144 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/gcp_ce_vm/post_deployment_execute.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/gcp_ce_vm/post_deployment_execute.yml @@ -3,9 +3,12 @@ - name: Ansible Task block for amending Load Balancer ports for High Availability - after provisioning GCP CE VMs delegate_to: localhost run_once: true - environment: - GCP_AUTH_KIND: "serviceaccount" - GCP_SERVICE_ACCOUNT_FILE: "{{ sap_vm_provision_gcp_credentials_json }}" + any_errors_fatal: true + # Using environment, no_log is ineffective and log will show 'EXEC /bin/sh -c 'ENV_VAR=value python3 /AnsiballZ_ansible_module_name.py && sleep 0' + # Therefore do not use environment for secrets, use only for non-sensitive values as this will reduce Ansible Task parameters. + # environment: + # GCP_AUTH_KIND: "serviceaccount" + # GCP_SERVICE_ACCOUNT_FILE: "{{ sap_vm_provision_gcp_credentials_json }}" when: - sap_ha_pacemaker_cluster_msazure_resource_group is defined - (groups["hana_secondary"] is defined and (groups["hana_secondary"] | length>0)) or (groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0)) or (groups["anydb_secondary"] is defined and (groups["anydb_secondary"] | length>0)) @@ -13,52 +16,57 @@ - name: Inherit variable - set fact for Google Cloud Compute Engine Health Check (Global) - SAP HANA ansible.builtin.set_fact: - gcp_lb_healthcheck_hana: "{{ sap_ha_pacemaker_cluster_healthcheck_hana_primary_port | default('') }}" + __sap_vm_provision_task_gcp_lb_healthcheck_hana: "{{ sap_ha_pacemaker_cluster_healthcheck_hana_primary_port | default('') }}" when: sap_ha_pacemaker_cluster_healthcheck_hana_primary_port is defined - name: Inherit variable - set fact for Google Cloud Compute Engine Health Check (Global) - SAP NWAS ASCS ansible.builtin.set_fact: - gcp_lb_healthcheck_nwas_ascs: "{{ sap_ha_pacemaker_cluster_healthcheck_nwas_abap_ascs_port | default('') }}" + __sap_vm_provision_task_gcp_lb_healthcheck_nwas_ascs: "{{ sap_ha_pacemaker_cluster_healthcheck_nwas_abap_ascs_port | default('') }}" when: sap_ha_pacemaker_cluster_healthcheck_nwas_abap_ascs_port is defined - name: Inherit variable - set fact for Google Cloud Compute Engine Health Check (Global) - SAP NWAS ERS ansible.builtin.set_fact: - gcp_lb_healthcheck_nwas_ers: "{{ sap_ha_pacemaker_cluster_healthcheck_nwas_abap_ers_port | default('') }}" + __sap_vm_provision_task_gcp_lb_healthcheck_nwas_ers: "{{ sap_ha_pacemaker_cluster_healthcheck_nwas_abap_ers_port | default('') }}" when: sap_ha_pacemaker_cluster_healthcheck_nwas_abap_ers_port is defined - name: Default variable - Set fact for Google Cloud Compute Engine Health Check (Global) - SAP HANA ansible.builtin.set_fact: - gcp_lb_healthcheck_hana: "{{ ('620' + (sap_system_hana_db_instance_nr | default('')) | string) | int }}" + __sap_vm_provision_task_gcp_lb_healthcheck_hana: "{{ ('620' + (sap_system_hana_db_instance_nr | default('')) | string) | int }}" when: not sap_ha_pacemaker_cluster_healthcheck_hana_primary_port is defined - name: Default variable - Set fact for Google Cloud Compute Engine Health Check (Global) - SAP NWAS ASCS ansible.builtin.set_fact: - gcp_lb_healthcheck_nwas_ascs: "{{ ('620' + (sap_system_nwas_abap_ascs_instance_nr | default('')) | string) | int }}" + __sap_vm_provision_task_gcp_lb_healthcheck_nwas_ascs: "{{ ('620' + (sap_system_nwas_abap_ascs_instance_nr | default('')) | string) | int }}" when: not sap_ha_pacemaker_cluster_healthcheck_nwas_abap_ascs_port is defined - name: Default variable - Set fact for Google Cloud Compute Engine Health Check (Global) - SAP NWAS ERS ansible.builtin.set_fact: - gcp_lb_healthcheck_nwas_ers: "{{ ('620' + (sap_system_nwas_abap_ers_instance_nr | default('')) | string) | int }}" + __sap_vm_provision_task_gcp_lb_healthcheck_nwas_ers: "{{ ('620' + (sap_system_nwas_abap_ers_instance_nr | default('')) | string) | int }}" when: not sap_ha_pacemaker_cluster_healthcheck_nwas_abap_ers_port is defined - name: Create Google Cloud Compute Engine Health Check (Global) service instance for SAP HANA + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_healthcheck_service google.cloud.gcp_compute_health_check: state: present project: "{{ sap_vm_provision_gcp_project }}" name: "lb-probe-hc-vip-hana" type: TCP tcp_health_check: - port: "{{ gcp_lb_healthcheck_hana }}" + port: "{{ __sap_vm_provision_task_gcp_lb_healthcheck_hana }}" proxy_header: NONE check_interval_sec: 10 timeout_sec: 10 unhealthy_threshold: 2 healthy_threshold: 2 - register: gcp_lb_healthcheck_service + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - groups["hana_secondary"] is defined and (groups["hana_secondary"]|length>0) - name: Create Google Cloud Compute Engine Health Check (Global) service instance for SAP AnyDB + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_healthcheck_service google.cloud.gcp_compute_health_check: state: present project: "{{ sap_vm_provision_gcp_project }}" @@ -71,40 +79,47 @@ timeout_sec: 10 unhealthy_threshold: 2 healthy_threshold: 2 - register: gcp_lb_healthcheck_service + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - groups["anydb_secondary"] is defined and (groups["anydb_secondary"]|length>0) - name: Create Google Cloud Compute Engine Health Check (Global) service instance for SAP NetWeaver ASCS + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_healthcheck_service_ascs google.cloud.gcp_compute_health_check: state: present project: "{{ sap_vm_provision_gcp_project }}" name: "lb-probe-hc-vip-nwas-ascs" type: TCP tcp_health_check: - port: "{{ gcp_lb_healthcheck_nwas_ascs }}" + port: "{{ __sap_vm_provision_task_gcp_lb_healthcheck_nwas_ascs }}" proxy_header: NONE check_interval_sec: 10 timeout_sec: 10 unhealthy_threshold: 2 healthy_threshold: 2 - register: gcp_lb_healthcheck_service_ascs + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - groups["nwas_ers"] is defined and (groups["nwas_ers"]|length>0) - name: Create Google Cloud Compute Engine Health Check (Global) service instance for SAP NetWeaver ERS + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_gcp_lb_healthcheck_service_ers google.cloud.gcp_compute_health_check: state: present project: "{{ sap_vm_provision_gcp_project }}" name: "lb-probe-hc-vip-nwas-ers" type: TCP tcp_health_check: - port: "{{ gcp_lb_healthcheck_nwas_ers }}" + port: "{{ __sap_vm_provision_task_gcp_lb_healthcheck_nwas_ers }}" proxy_header: NONE check_interval_sec: 10 timeout_sec: 10 unhealthy_threshold: 2 healthy_threshold: 2 - register: gcp_lb_healthcheck_service_ers + auth_kind: "serviceaccount" + service_account_file: "{{ sap_vm_provision_gcp_credentials_json }}" when: - groups["nwas_ers"] is defined and (groups["nwas_ers"]|length>0) diff --git a/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_powervs/execute_main.yml b/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_powervs/execute_main.yml index f24a27b..a7642b5 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_powervs/execute_main.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_powervs/execute_main.yml @@ -44,84 +44,141 @@ sap_vm_provision_ibmcloud_powervs_region: "{{ list_ibmcloud_powervs_location_to_powervs_region[sap_vm_provision_ibmcloud_powervs_location] }}" - name: Ansible Task block for looped provisioning of IBM Power Virtual Servers on IBM Cloud + any_errors_fatal: true + # Using environment, no_log is ineffective and log will show 'EXEC /bin/sh -c 'ENV_VAR=value python3 /AnsiballZ_ansible_module_name.py && sleep 0' + # Therefore do not use environment for secrets, use only for non-sensitive values as this will reduce Ansible Task parameters. environment: - IC_API_KEY: "{{ sap_vm_provision_ibmcloud_api_key }}" + # IC_API_KEY: "{{ sap_vm_provision_ibmcloud_api_key }}" IC_REGION: "{{ sap_vm_provision_ibmcloud_region }}" IC_ZONE: "{{ sap_vm_provision_ibmcloud_powervs_location }}" # Required only for IBM Power VS, to set IBM Power VS location block: - name: Identify Resource Group info - register: register_ibmcloud_resource_group + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_resource_group ibm.cloudcollection.ibm_resource_group_info: name: "{{ sap_vm_provision_ibmcloud_resource_group_name }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" + + # DNS may exist in separate Resource Group + # Use empty string var (or default false if undefined) to evaluate to false boolean + - name: Identify Resource Group info for IBM Cloud Private DNS + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_resource_group_dns + ibm.cloudcollection.ibm_resource_group_info: + name: "{{ sap_vm_provision_ibmcloud_private_dns_resource_group_name }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" + when: (sap_vm_provision_ibmcloud_private_dns_resource_group_name | default(false)) - name: Identify IBM Power Infrastructure Workspace - register: register_ibmcloud_power_iaas_workspace_service_instance + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_pi_workspace_service_instance ibm.cloudcollection.ibm_resource_instance_info: - resource_group_id: "{{ register_ibmcloud_resource_group.resource.id }}" + resource_group_id: "{{ __sap_vm_provision_task_ibmcloud_resource_group.resource.id }}" location: "{{ sap_vm_provision_ibmcloud_powervs_location }}" service: power-iaas name: "{{ sap_vm_provision_ibmcloud_powervs_workspace_name }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" - - name: Identify pre-loaded Power Infrastructure SSH Public Key info - register: register_ibmcloud_pi_ssh_public_key + - name: Identify pre-loaded IBM Power Infrastructure SSH Public Key info + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_pi_ssh_public_key environment: IC_REGION: "{{ sap_vm_provision_ibmcloud_powervs_region }}" ibm.cloudcollection.ibm_pi_key_info: - pi_cloud_instance_id: "{{ register_ibmcloud_power_iaas_workspace_service_instance.resource.guid }}" # must be GUID, not CRN + pi_cloud_instance_id: "{{ __sap_vm_provision_task_ibmcloud_pi_workspace_service_instance.resource.guid }}" # must be GUID, not CRN pi_key_name: "{{ sap_vm_provision_ibmcloud_powervs_key_pair_name_ssh_host_public_key }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" - - name: Identify Power Infrastructure VLAN Subnet info - register: register_ibmcloud_pi_subnet + - name: Identify IBM Power Infrastructure VLAN Subnet info + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_pi_subnet environment: IC_REGION: "{{ sap_vm_provision_ibmcloud_powervs_region }}" ibm.cloudcollection.ibm_pi_network_info: - pi_cloud_instance_id: "{{ register_ibmcloud_power_iaas_workspace_service_instance.resource.guid }}" # must be GUID, not CRN + pi_cloud_instance_id: "{{ __sap_vm_provision_task_ibmcloud_pi_workspace_service_instance.resource.guid }}" # must be GUID, not CRN pi_network_name: "{{ sap_vm_provision_ibmcloud_powervs_vlan_subnet_name }}" - - - name: Identify Power Infrastructure OS Image list - register: register_ibmcloud_pi_os_image_list - environment: - IC_REGION: "{{ sap_vm_provision_ibmcloud_powervs_region }}" - ibm.cloudcollection.ibm_pi_catalog_images_info: - pi_cloud_instance_id: "{{ register_ibmcloud_power_iaas_workspace_service_instance.resource.guid }}" # must be GUID, not CRN - - - name: Identify Private DNS instance - register: register_ibmcloud_pdns_service_instance + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" + + - name: Confirm IBM Power Infrastructure VLAN Subnet uses IBM Cloud IaaS Backbone DNS Resolver + ansible.builtin.fail: + msg: + If IBM Power Infrastructure Workspace uses Power Edge Router (and not legacy Cloud Connection) networking configuration, + then Subnet DNS Default should use IBM Cloud IaaS Backbone DNS Resolver 161.26.0.10/11 (which will be populated into /etc/resolv.conf). + Otherwise cloud-init actions during provisioning may not be successful. + when: + - not sap_vm_provision_proxy_web_forward_proxy_ip is defined + - not (__sap_vm_provision_task_ibmcloud_pi_subnet.resource.dns | first) in ['161.26.0.10', '161.26.0.11'] + + # DNS may exist in separate Resource Group + # If previous identification task is skipped, use resource group else use the resource group defined for the Private DNS + - name: Identify IBM Cloud Private DNS instance + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_pdns_service_instance ibm.cloudcollection.ibm_resource_instance_info: - resource_group_id: "{{ register_ibmcloud_resource_group.resource.id }}" + resource_group_id: "{{ __sap_vm_provision_task_ibmcloud_resource_group.resource.id if __sap_vm_provision_task_ibmcloud_resource_group_dns is skipped else __sap_vm_provision_task_ibmcloud_resource_group_dns.resource.id }}" location: global service: dns-svcs name: "{{ sap_vm_provision_ibmcloud_private_dns_instance_name }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" - - name: Identify Private DNS Zone info - register: register_ibmcloud_pdns + - name: Identify IBM Cloud Private DNS Zone info + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_pdns ibm.cloudcollection.ibm_dns_zones_info: - instance_id: "{{ register_ibmcloud_pdns_service_instance.resource.guid }}" + instance_id: "{{ __sap_vm_provision_task_ibmcloud_pdns_service_instance.resource.guid }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" + + - name: Identify IBM Power Infrastructure OS Catalog Stock Image list + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_pi_os_image_list + environment: + IC_REGION: "{{ sap_vm_provision_ibmcloud_powervs_region }}" + ibm.cloudcollection.ibm_pi_catalog_images_info: + pi_cloud_instance_id: "{{ __sap_vm_provision_task_ibmcloud_pi_workspace_service_instance.resource.guid }}" # must be GUID, not CRN + sap: true # Return all OS Images for SAP + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" - - name: Set fact for latest IBM Power Infrastructure OS Catalog Stock Image + - name: Set fact for selected IBM Power Infrastructure OS Catalog Stock Image ansible.builtin.set_fact: - register_ibmcloud_pi_os_image_selected: "{{ register_ibmcloud_pi_os_image_list.resource.images | selectattr('name', 'search', lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_os_image_dictionary')[sap_vm_provision_ibmcloud_powervs_host_os_image]) | sort(reverse=True,case_sensitive=False,attribute='name') | first }}" + register_ibmcloud_pi_os_image_selected: "{{ __sap_vm_provision_task_ibmcloud_pi_os_image_list.resource.images | rejectattr('name', 'search', '.*BYOL.*') | selectattr('name', 'search', lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_os_image_dictionary')[sap_vm_provision_ibmcloud_powervs_host_os_image]) | sort(reverse=True,case_sensitive=False,attribute='name') | first }}" - - name: Create Boot Image from IBM Power Infrastructure OS Catalog Stock Image - register: register_provisioned_os_image + - name: Import Boot Image to current IBM Power Infrastructure Workspace from the IBM Power Infrastructure OS Catalog Stock Image + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_pi_os_image_provisioned environment: IC_REGION: "{{ sap_vm_provision_ibmcloud_powervs_region }}" ibm.cloudcollection.ibm_pi_image: - pi_cloud_instance_id: "{{ register_ibmcloud_power_iaas_workspace_service_instance.resource.guid }}" # must be GUID, not CRN + pi_cloud_instance_id: "{{ __sap_vm_provision_task_ibmcloud_pi_workspace_service_instance.resource.guid }}" # must be GUID, not CRN pi_image_id: "{{ register_ibmcloud_pi_os_image_selected.image_id }}" pi_image_name: "{{ sap_vm_provision_ibmcloud_powervs_host_os_image }}-boot" - failed_when: not register_provisioned_os_image.rc == 0 and not 'already exists' in register_provisioned_os_image.stderr + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" + failed_when: not __sap_vm_provision_task_ibmcloud_pi_os_image_provisioned.rc == 0 and not 'already exists' in __sap_vm_provision_task_ibmcloud_pi_os_image_provisioned.stderr run_once: true + - name: Identify IBM Power Infrastructure Workspace imported OS Image list + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_pi_imported_os_image_list + environment: + IC_REGION: "{{ sap_vm_provision_ibmcloud_powervs_region }}" + ibm.cloudcollection.ibm_pi_images_info: + pi_cloud_instance_id: "{{ __sap_vm_provision_task_ibmcloud_pi_workspace_service_instance.resource.guid }}" # must be GUID, not CRN + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" + + - name: Set fact for selected IBM Power Infrastructure imported OS Image + ansible.builtin.set_fact: + register_ibmcloud_pi_imported_os_image_selected: "{{ __sap_vm_provision_task_ibmcloud_pi_imported_os_image_list.resource.image_info | rejectattr('name', 'search', '.*BYOL.*') | selectattr('name', 'search', lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_os_image_dictionary')[sap_vm_provision_ibmcloud_powervs_host_os_image]) | sort(reverse=True,case_sensitive=False,attribute='name') | first }}" + # Use check to avoid idempotency issues with legacy ibm.cloudcollection Ansible Collection (until ibm.cloud Ansible Collection is ready) - name: Check for existing Boot Image imported already from IBM Power Infrastructure OS Catalog Stock Image - register: register_existing_os_image + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_pi_os_image_existing environment: IC_REGION: "{{ sap_vm_provision_ibmcloud_powervs_region }}" ibm.cloudcollection.ibm_pi_image_info: - pi_cloud_instance_id: "{{ register_ibmcloud_power_iaas_workspace_service_instance.resource.guid }}" # must be GUID, not CRN - pi_image_name: "{{ register_ibmcloud_pi_os_image_selected.name }}" + pi_cloud_instance_id: "{{ __sap_vm_provision_task_ibmcloud_pi_workspace_service_instance.resource.guid }}" # must be GUID, not CRN + pi_image_name: "{{ register_ibmcloud_pi_imported_os_image_selected.name }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" run_once: true - name: Set fact to hold loop variables from include_tasks @@ -129,21 +186,21 @@ register_provisioned_host_all: [] - name: Provision IBM Power Virtual Server hosts on IBM Cloud - register: register_provisioned_hosts + register: __sap_vm_provision_task_provision_host_all_run ansible.builtin.include_tasks: file: "{{ 'platform_' + sap_vm_provision_iac_type }}/{{ sap_vm_provision_iac_platform }}/execute_provision.yml" apply: environment: - IC_API_KEY: "{{ sap_vm_provision_ibmcloud_api_key }}" + # IC_API_KEY: "{{ sap_vm_provision_ibmcloud_api_key }}" IC_REGION: "{{ sap_vm_provision_ibmcloud_powervs_region }}" IC_ZONE: "{{ sap_vm_provision_ibmcloud_powervs_location }}" # Required only for IBM Power VS, to set IBM Power VS location - name: Add hosts provisioned to the Ansible Inventory - register: register_add_hosts + register: __sap_vm_provision_task_provision_host_all_add ansible.builtin.add_host: name: "{{ add_item[0].host_node }}" groups: "{{ add_item[0].sap_system_type + '_' if (add_item[0].sap_system_type != '') }}{{ add_item[0].sap_host_type }}" - ansible_host: "{{ add_item[0].resource.addresses[0].ip }}" + ansible_host: "{{ add_item[0].resource.networks[0].ip }}" ansible_user: "root" ansible_ssh_private_key_file: "{{ sap_vm_provision_ssh_host_private_key_file_path }}" ansible_ssh_common_args: -o ConnectTimeout=180 -o ControlMaster=auto -o ControlPersist=3600s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ForwardX11=no -o ProxyCommand='ssh -W %h:%p {{ sap_vm_provision_bastion_user }}@{{ sap_vm_provision_bastion_public_ip }} -p {{ sap_vm_provision_bastion_ssh_port }} -i {{ sap_vm_provision_ssh_bastion_private_key_file_path }} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' @@ -161,23 +218,61 @@ groups_merged_list: "{{ [ [ groups['hana_primary'] | default([]) ] , [ groups['hana_secondary'] | default([]) ] , [ groups['nwas_ascs'] | default([]) ] , [ groups['nwas_ers'] | default([]) ] , [ groups['nwas_pas'] | default([]) ] , [ groups['nwas_aas'] | default([]) ] ] | flatten | select() }}" - name: Set Ansible Vars - register: register_set_ansible_vars + register: __sap_vm_provision_task_ansible_vars_set ansible.builtin.include_tasks: file: common/set_ansible_vars.yml - name: IBM Cloud Private DNS Record for hosts - register: register_ibmcloud_pdns_record + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_pdns_record ibm.cloudcollection.ibm_dns_resource_record: - instance_id: "{{ register_ibmcloud_pdns_service_instance.resource.guid }}" - zone_id: "{{ (register_ibmcloud_pdns.resource.dns_zones | selectattr('name', '==', sap_vm_provision_dns_root_domain) | first).zone_id }}" + instance_id: "{{ __sap_vm_provision_task_ibmcloud_pdns_service_instance.resource.guid }}" + zone_id: "{{ (__sap_vm_provision_task_ibmcloud_pdns.resource.dns_zones | selectattr('name', '==', sap_vm_provision_dns_root_domain) | first).zone_id }}" name: "{{ inventory_hostname }}.{{ hostvars[inventory_hostname].sap_vm_provision_dns_root_domain }}" # Host FQDN rdata: "{{ hostvars[inventory_hostname].ansible_host }}" # IP Address type: A ttl: 7200 - failed_when: not register_ibmcloud_pdns_record.rc == 0 and not 'The record already exists' in register_ibmcloud_pdns_record.stderr + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" + failed_when: not __sap_vm_provision_task_ibmcloud_pdns_record.rc == 0 and not 'The record already exists' in __sap_vm_provision_task_ibmcloud_pdns_record.stderr # - ansible.builtin.debug: - # var: register_add_hosts.results + # var: __sap_vm_provision_task_provision_host_all_add.results + + rescue: + # This requires no_log set on each Ansible Task, and not set on the Ansible Task Block + # This requires an Ansible Task Block containing the Ansible Tasks for calling + # Infrastructure Platform APIs (via Ansible Modules) + - name: Show errors in task outputs + ansible.builtin.fail: + msg: "{{ lookup('ansible.builtin.vars', loop_item) }}" + loop: + - __sap_vm_provision_task_ibmcloud_resource_group + - __sap_vm_provision_task_ibmcloud_resource_group_dns + - __sap_vm_provision_task_ibmcloud_pi_workspace_service_instance + - __sap_vm_provision_task_ibmcloud_pi_ssh_public_key + - __sap_vm_provision_task_ibmcloud_pi_subnet + - __sap_vm_provision_task_ibmcloud_pi_os_image_list + - __sap_vm_provision_task_ibmcloud_pdns_service_instance + - __sap_vm_provision_task_ibmcloud_pdns + - __sap_vm_provision_task_ibmcloud_pi_os_image_provisioned + - __sap_vm_provision_task_ibmcloud_pi_os_image_existing + - __sap_vm_provision_task_provision_host_all_run + - __sap_vm_provision_task_provision_host_single + - __sap_vm_provision_task_provision_host_single_volumes + - __sap_vm_provision_task_provision_host_single_volumes_info + - __sap_vm_provision_task_provision_host_single_volume_attachments + - __sap_vm_provision_task_provision_host_single_info + - __sap_vm_provision_task_provision_host_all_add + - __sap_vm_provision_task_ibmcloud_pdns_record + loop_control: + loop_var: loop_item + index_var: loop_item_index + label: "{{ 'Variable No. ' + (loop_item_index | string) }}" + when: + - lookup('ansible.builtin.vars', loop_item, default='') | length > 0 + - not lookup('ansible.builtin.vars', loop_item, default='') is skipped + - lookup('ansible.builtin.vars', loop_item, default='') is failed + - name: Ansible Task block to execute on target inventory hosts delegate_to: "{{ inventory_hostname }}" @@ -196,26 +291,26 @@ name: "{{ inventory_hostname_short }}" - name: Set /etc/hosts - register: register_etc_hosts_file + register: __sap_vm_provision_task_os_etc_hosts ansible.builtin.include_tasks: file: common/set_etc_hosts.yml - name: Set /etc/hosts for HA - register: register_etc_hosts_file_ha + register: __sap_vm_provision_task_os_etc_hosts_ha ansible.builtin.include_tasks: file: common/set_etc_hosts_ha.yml when: - (groups["hana_secondary"] is defined and (groups["hana_secondary"] | length>0)) or (groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0)) or (groups["anydb_secondary"] is defined and (groups["anydb_secondary"] | length>0)) - name: Set /etc/hosts for Scale-Out - register: register_etc_hosts_file_scaleout + register: __sap_vm_provision_task_os_etc_hosts_scaleout ansible.builtin.include_tasks: file: common/set_etc_hosts_scaleout.yml when: - - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_hana_scaleout_active_coordinator is defined or sap_hana_scaleout_active_worker is defined or sap_hana_scaleout_standby is defined) + - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined or sap_vm_provision_calculate_sap_hana_scaleout_active_worker is defined or sap_vm_provision_calculate_sap_hana_scaleout_standby is defined) - name: Set vars for sap_storage_setup Ansible Role - register: register_ansible_vars_storage + register: __sap_vm_provision_task_ansible_vars_storage ansible.builtin.include_tasks: file: common/set_ansible_vars_storage.yml @@ -224,35 +319,61 @@ path: /etc/resolv.conf line: nameserver 161.26.0.10 - - name: Register Web Forward Proxy + # Not applicable to the IBM PowerVS Workspace enabled with Power Edge Router (from Q4-2023 onwards) + - name: Register Web Forward Proxy (for legacy Power Infrastructure Cloud Connections networking configuration) ansible.builtin.include_tasks: file: common/register_proxy.yml + when: sap_vm_provision_proxy_web_forward_proxy_ip is defined + # Not applicable to the IBM PowerVS Workspace enabled with Power Edge Router (from Q4-2023 onwards) # Extract the generated command string and activation key from /usr/share, then execute script from /usr/local/bin # Use nohup to ensure completion, wait 2 minutes # Verify with /var/log/rhsm/rhsm.log if necessary - - name: Execute OS Activation Script for IBM Power Virtual Server - RHEL + - name: Execute OS Activation Script for IBM Power Virtual Server - RHEL - IBM PowerVS Workspace with legacy Cloud Connection ansible.builtin.shell: | - set -o pipefail && web_proxy_ip_port="{{ sap_vm_provision_proxy_web_forward_proxy_ip }}" - set -o pipefail && if [[ ! -f /usr/share/powervs-fls/powervs-fls-readme.md ]]; then echo "File does not exist" && exit 1; fi - set -o pipefail && activation_script_exec=$(cat /usr/share/powervs-fls/powervs-fls-readme.md | grep networklayer.com | sed "s|Private.proxy.IP.address:3128|$web_proxy_ip_port|" | sed 's|. ||') - set -o pipefail && nohup $activation_script_exec >/dev/null 2>&1 - set -o pipefail && sleep 120 + set -o pipefail && web_proxy_ip_port="{{ sap_vm_provision_proxy_web_forward_proxy_ip | default('') }}" + set -o pipefail && if [[ ! -f /usr/share/powervs-fls/powervs-fls-readme.md ]] ; then workspace_per=true ; else workspace_legacy_cc=true ; fi + set -o pipefail && if [ "${workspace_per}" = true ]; then echo "Not required, automatically executed in IBM Power VS Workspace with Power Edge Router enabled" exit 0 ; fi + set -o pipefail && if [ "${workspace_legacy_cc}" = true ]; then activation_script_exec=$(cat /usr/share/powervs-fls/powervs-fls-readme.md | grep networklayer.com | sed "s|Private.proxy.IP.address:3128|$web_proxy_ip_port|" | sed 's|. ||') ; fi + set -o pipefail && if [ "${workspace_legacy_cc}" = true ]; then nohup $activation_script_exec >/dev/null 2>&1 ; fi + set -o pipefail && if [ "${workspace_legacy_cc}" = true ]; then sleep 120 ; fi when: ansible_os_family == "RedHat" + # Not applicable to the IBM PowerVS Workspace enabled with Power Edge Router (from Q4-2023 onwards) # Extract the generated command string and activation key from /usr/share, then execute script from /usr/local/bin # Use nohup to ensure completion, wait 2 minutes - - name: Execute OS Activation Script for IBM Power Virtual Server - SLES + - name: Execute OS Activation Script for IBM Power Virtual Server - SLES - IBM PowerVS Workspace with legacy Cloud Connection ansible.builtin.shell: | - set -o pipefail && web_proxy_ip_port="{{ sap_vm_provision_proxy_web_forward_proxy_ip }}" - set -o pipefail && if [[ ! -f /usr/share/powervs-fls/powervs-fls-readme.md ]]; then echo "File does not exist" && exit 1; fi - set -o pipefail && activation_script_exec=$(cat /usr/share/powervs-fls/powervs-fls-readme.md | grep networklayer.com | sed 's|. ||' | sed "s|$|$web_proxy_ip_port|") - set -o pipefail && nohup $activation_script_exec >/dev/null 2>&1 - set -o pipefail && sleep 60 + set -o pipefail && web_proxy_ip_port="{{ sap_vm_provision_proxy_web_forward_proxy_ip | default('') }}" + set -o pipefail && if [[ ! -f /usr/share/powervs-fls/powervs-fls-readme.md ]] ; then workspace_per=true ; else workspace_legacy_cc=true ; fi + set -o pipefail && if [ "${workspace_per}" = true ]; then echo "Not required, automatically executed in IBM Power VS Workspace with Power Edge Router enabled" exit 0 ; fi + set -o pipefail && if [ "${workspace_legacy_cc}" = true ]; then activation_script_exec=$(cat /usr/share/powervs-fls/powervs-fls-readme.md | grep networklayer.com | sed 's|. ||' | sed "s|$|$web_proxy_ip_port|") ; fi + set -o pipefail && if [ "${workspace_legacy_cc}" = true ]; then nohup $activation_script_exec >/dev/null 2>&1 ; fi + set -o pipefail && if [ "${workspace_legacy_cc}" = true ]; then sleep 120 ; fi set -o pipefail && SUSEConnect --product PackageHub/{{ ansible_distribution_version }}/ppc64le when: ansible_os_family == "Suse" - # Enusure lock to RHEL major.minor version + - name: Verify connection to NFS + ansible.builtin.wait_for: + host: "{{ sap_vm_provision_nfs_mount_point | regex_replace(':.*', '') }}" + port: 2049 + delay: 10 + sleep: 10 + connect_timeout: 15 + timeout: 120 + when: sap_vm_provision_nfs_mount_point is defined + + - name: Verify connection to separate NFS for SAP Transport Directory + ansible.builtin.wait_for: + host: "{{ sap_vm_provision_nfs_mount_point_separate_sap_transport_dir | regex_replace(':.*', '') }}" + port: 2049 + delay: 10 + sleep: 10 + connect_timeout: 15 + timeout: 120 + when: sap_vm_provision_nfs_mount_point_separate_sap_transport_dir is defined + + # Ensure lock to RHEL major.minor version # Lock using subscription-manager release --set or /var/lib/rhsm/cache/releasever.json, alternatively using /etc/yum/vars/releasever or /etc/dnf/vars/releasever - name: Set facts on each host - HA/DR diff --git a/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_powervs/execute_provision.yml b/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_powervs/execute_provision.yml index 6bf99c5..3862b07 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_powervs/execute_provision.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_powervs/execute_provision.yml @@ -1,30 +1,38 @@ --- # The tasks in this file are executed in a loop over the defined hosts +- name: Ensure short hostname is not longer than 13 characters (see SAP Note 611361) + ansible.builtin.assert: + that: (inventory_hostname | length | int) <= (13 | int) + fail_msg: "FAIL: The length of the hostname is {{ inventory_hostname | length | int }} but must be less or equal to 13 characters!" + # When SAP HANA Scale-Out is used, if host name is not in original specifications then strip suffix node number from host name - name: Set fact when performing SAP HANA Scale-Out ansible.builtin.set_fact: scaleout_origin_host_spec: "{{ inventory_hostname | regex_replace('^(.+?)\\d*$', '\\1') }}" when: - - sap_hana_scaleout_active_coordinator is defined + - sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined - not inventory_hostname in lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan].keys() # Status will change from Building > Warning (VM = Active, Health = Warning) > Active. The Ansible Task will continue once the Active status has been reached. - name: Provision IBM Power Virtual Server instance on IBM Cloud - register: register_provision_host_single + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single ibm.cloudcollection.ibm_pi_instance: - pi_cloud_instance_id: "{{ register_ibmcloud_power_iaas_workspace_service_instance.resource.guid }}" # must be GUID, not CRN + pi_cloud_instance_id: "{{ __sap_vm_provision_task_ibmcloud_pi_workspace_service_instance.resource.guid }}" # must be GUID, not CRN pi_instance_name: "{{ inventory_hostname }}" - pi_image_id: "{{ register_provisioned_os_image.resource.id if register_provisioned_os_image.rc == 0 else register_existing_os_image.resource.id }}" + pi_image_id: "{{ __sap_vm_provision_task_ibmcloud_pi_os_image_existing.resource.id }}" + + pi_sys_type: "{{ lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].ibmcloud_powervs_hardware_machine_type }}" - pi_sys_type: e980 pi_sap_profile_id: "{{ lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].virtual_machine_profile }}" + pi_key_pair_name: "{{ sap_vm_provision_ibmcloud_powervs_key_pair_name_ssh_host_public_key }}" pi_network: - - network_id: "{{ register_ibmcloud_pi_subnet.resource.id }}" + - network_id: "{{ __sap_vm_provision_task_ibmcloud_pi_subnet.resource.id }}" pi_storage_type: tier1 #pi_volume_ids: [] @@ -32,12 +40,16 @@ pi_pin_policy: none pi_health_status: OK + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" + # Use check to avoid idempotency issues with legacy ibm.cloudcollection Ansible Collection (until ibm.cloud Ansible Collection is out of beta) - name: Check IBM Power Virtual Server instance on IBM Cloud - register: register_provisioned_host_single + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single ibm.cloudcollection.ibm_pi_instance_info: - pi_cloud_instance_id: "{{ register_ibmcloud_power_iaas_workspace_service_instance.resource.guid }}" # must be GUID, not CRN + pi_cloud_instance_id: "{{ __sap_vm_provision_task_ibmcloud_pi_workspace_service_instance.resource.guid }}" # must be GUID, not CRN pi_instance_name: "{{ inventory_hostname }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" # Create flat list with names for each volume to be created. @@ -66,15 +78,17 @@ - name: Provision IBM Power Infrastructure Block Storage volumes for IBM Power VS instance filesystems - register: register_provisioned_volumes + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_volumes ibm.cloudcollection.ibm_pi_volume: - pi_cloud_instance_id: "{{ register_ibmcloud_power_iaas_workspace_service_instance.resource.guid }}" # must be GUID, not CRN + pi_cloud_instance_id: "{{ __sap_vm_provision_task_ibmcloud_pi_workspace_service_instance.resource.guid }}" # must be GUID, not CRN pi_volume_name: "{{ inventory_hostname + '-vol-' + vol_item.name | replace('_', '-')}}" pi_volume_type: "{{ vol_item.type }}" pi_volume_size: "{{ vol_item.size }}" pi_volume_shareable: false pi_replication_enabled: false #delete_on_termination: true + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ storage_disks_map }}" loop_control: loop_var: vol_item @@ -83,15 +97,17 @@ when: - vol_item.size > 0 failed_when: - - not register_provisioned_volumes.rc == 0 - - not 'already exists' in register_provisioned_volumes.stderr + - not __sap_vm_provision_task_provision_host_single_volumes.rc == 0 + - not 'already exists' in __sap_vm_provision_task_provision_host_single_volumes.stderr # Use check to avoid idempotency issues with legacy ibm.cloudcollection Ansible Collection (until ibm.cloud Ansible Collection is out of beta) - name: Check status of IBM Power Infrastructure Block Storage volumes - register: register_volumes + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_volumes_info ibm.cloudcollection.ibm_pi_volume_info: - pi_cloud_instance_id: "{{ register_ibmcloud_power_iaas_workspace_service_instance.resource.guid }}" # must be GUID, not CRN + pi_cloud_instance_id: "{{ __sap_vm_provision_task_ibmcloud_pi_workspace_service_instance.resource.guid }}" # must be GUID, not CRN pi_volume_name: "{{ inventory_hostname + '-vol-' + vol_item.name | replace('_', '-')}}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ storage_disks_map }}" loop_control: loop_var: vol_item @@ -100,44 +116,48 @@ when: - vol_item.size > 0 retries: 5 - until: register_volumes.rc == 0 and (register_volumes.resource is defined and register_volumes.resource.state == "available", "in-use") + until: __sap_vm_provision_task_provision_host_single_volumes_info.rc == 0 and (__sap_vm_provision_task_provision_host_single_volumes_info.resource is defined and __sap_vm_provision_task_provision_host_single_volumes_info.resource.state == "available", "in-use") delay: 20 - name: Attach IBM Power Infrastructure Block Storage volumes as filesystem for IBM Power VS instance - register: register_attached_volumes + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_volume_attachments ibm.cloudcollection.ibm_pi_volume_attach: - pi_cloud_instance_id: "{{ register_ibmcloud_power_iaas_workspace_service_instance.resource.guid }}" # must be GUID, not CRN + pi_cloud_instance_id: "{{ __sap_vm_provision_task_ibmcloud_pi_workspace_service_instance.resource.guid }}" # must be GUID, not CRN pi_volume_id: "{{ vol_item.resource.id }}" - pi_instance_id: "{{ register_provisioned_host_single.resource.id }}" - loop: "{{ register_volumes.results }}" + pi_instance_id: "{{ __sap_vm_provision_task_provision_host_single.resource.id }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" + loop: "{{ __sap_vm_provision_task_provision_host_single_volumes_info.results }}" loop_control: loop_var: vol_item index_var: vol_item_index label: "{{ vol_item.resource.pi_volume_name }}" failed_when: - - not register_attached_volumes.rc == 0 - - not 'volume cannot be attached in the current state' in register_attached_volumes.stderr # when already attached message + - not __sap_vm_provision_task_provision_host_single_volume_attachments.rc == 0 + - not 'volume cannot be attached in the current state' in __sap_vm_provision_task_provision_host_single_volume_attachments.stderr # when already attached message retries: 1 - until: register_attached_volumes is success + until: __sap_vm_provision_task_provision_host_single_volume_attachments is success delay: 10 - name: Read IBM Power Virtual Server information - register: instance_info + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_info ibm.cloudcollection.ibm_pi_instance_info: - pi_cloud_instance_id: "{{ register_ibmcloud_power_iaas_workspace_service_instance.resource.guid }}" # must be GUID, not CRN - pi_instance_name: "{{ register_provisioned_host_single.resource.pi_instance_name }}" + pi_cloud_instance_id: "{{ __sap_vm_provision_task_ibmcloud_pi_workspace_service_instance.resource.guid }}" # must be GUID, not CRN + pi_instance_name: "{{ __sap_vm_provision_task_provision_host_single.resource.pi_instance_name }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" - name: Add host facts ansible.builtin.set_fact: - volume_provisioning: "{{ register_volumes }}" - instance_info: "{{ instance_info }}" + __sap_vm_provision_task_provision_host_single_volumes: "{{ __sap_vm_provision_task_provision_host_single_volumes_info }}" + __sap_vm_provision_task_provision_host_single_info: "{{ __sap_vm_provision_task_provision_host_single_info }}" delegate_to: "{{ inventory_hostname }}" delegate_facts: true - name: Create fact for delegate host IP ansible.builtin.set_fact: - provisioned_private_ip: "{{ register_provisioned_host_single.resource.addresses[0].ip }}" + provisioned_private_ip: "{{ __sap_vm_provision_task_provision_host_single.resource.networks[0].ip }}" - name: Copy facts to delegate host @@ -149,7 +169,7 @@ delegate_sap_vm_provision_bastion_ssh_port: "{{ sap_vm_provision_bastion_ssh_port }}" delegate_sap_vm_provision_ssh_bastion_private_key_file_path: "{{ sap_vm_provision_ssh_bastion_private_key_file_path }}" delegate_sap_vm_provision_ssh_host_private_key_file_path: "{{ sap_vm_provision_ssh_host_private_key_file_path }}" - delegate_private_ip: "{{ register_provisioned_host_single.resource.addresses[0].ip }}" + delegate_private_ip: "{{ __sap_vm_provision_task_provision_host_single.resource.networks[0].ip }}" delegate_hostname: "{{ inventory_hostname }}" delegate_sap_vm_provision_dns_root_domain_name: "{{ sap_vm_provision_dns_root_domain }}" @@ -177,29 +197,29 @@ dest: /root/.ssh/authorized_keys mode: '0600' content: | - {{ register_ibmcloud_pi_ssh_public_key.resource.ssh_key }} + {{ __sap_vm_provision_task_ibmcloud_pi_ssh_public_key.resource.ssh_key }} - name: Permit root login + register: __sap_vm_provision_task_os_sshd_config ansible.builtin.replace: path: /etc/ssh/sshd_config regexp: '(^PermitRootLogin no)' replace: 'PermitRootLogin yes' - register: sshd_config - name: Reload sshd service ansible.builtin.service: name: sshd state: reloaded when: - - sshd_config.changed + - __sap_vm_provision_task_os_sshd_config.changed ### end of block - name: Append loop value to register ansible.builtin.set_fact: - register_provisioned_host_single: "{{ register_provisioned_host_single | combine( { 'host_node' : inventory_hostname } , { 'sap_host_type' : lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_host_type } , { 'sap_system_type' : (lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_system_type | default('')) } ) }}" + __sap_vm_provision_task_provision_host_single: "{{ __sap_vm_provision_task_provision_host_single | combine( { 'host_node' : inventory_hostname } , { 'sap_host_type' : lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_host_type } , { 'sap_system_type' : (lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_system_type | default('')) } ) }}" - name: Append output to merged register ansible.builtin.set_fact: - register_provisioned_host_all: "{{ register_provisioned_host_all + [register_provisioned_host_single] }}" + register_provisioned_host_all: "{{ register_provisioned_host_all + [__sap_vm_provision_task_provision_host_single] }}" diff --git a/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_vs/execute_main.yml b/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_vs/execute_main.yml index c947801..501d6d1 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_vs/execute_main.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_vs/execute_main.yml @@ -1,65 +1,92 @@ --- - name: Ansible Task block for looped provisioning of IBM Cloud Virtual Servers + any_errors_fatal: true + # Using environment, no_log is ineffective and log will show 'EXEC /bin/sh -c 'ENV_VAR=value python3 /AnsiballZ_ansible_module_name.py && sleep 0' + # Therefore do not use environment for secrets, use only for non-sensitive values as this will reduce Ansible Task parameters. environment: - IC_API_KEY: "{{ sap_vm_provision_ibmcloud_api_key }}" + # IC_API_KEY: "{{ sap_vm_provision_ibmcloud_api_key }}" IC_REGION: "{{ sap_vm_provision_ibmcloud_region }}" block: - name: Identify Resource Group info - register: register_ibmcloud_resource_group + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_resource_group ibm.cloudcollection.ibm_resource_group_info: name: "{{ sap_vm_provision_ibmcloud_resource_group_name }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" + + # DNS may exist in separate Resource Group + # Use empty string var (or default false if undefined) to evaluate to false boolean + - name: Identify Resource Group info for Private DNS + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_resource_group_dns + ibm.cloudcollection.ibm_resource_group_info: + name: "{{ sap_vm_provision_ibmcloud_private_dns_resource_group_name }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" + when: (sap_vm_provision_ibmcloud_private_dns_resource_group_name | default(false)) - name: Identify pre-loaded SSH Public Key info - register: register_ibmcloud_ssh_public_key + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_ssh_public_key ibm.cloudcollection.ibm_is_ssh_key_info: name: "{{ sap_vm_provision_ibmcloud_key_pair_name_ssh_host_public_key }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" - name: Identify VPC Subnet info - register: register_ibmcloud_vpc_subnet + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_vpc_subnet ibm.cloudcollection.ibm_is_subnet_info: name: "{{ sap_vm_provision_ibmcloud_vpc_subnet_name }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" - name: Identify VPC Security Group info - register: register_ibmcloud_vpc_sg + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_vpc_sg ibm.cloudcollection.ibm_is_security_group_info: name: "{{ item }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ sap_vm_provision_ibmcloud_vpc_sg_names | split(',') }}" - name: Identify Private DNS instance - register: register_ibmcloud_pdns_service_instance + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_pdns_service_instance ibm.cloudcollection.ibm_resource_instance_info: - resource_group_id: "{{ register_ibmcloud_resource_group.resource.id }}" + resource_group_id: "{{ __sap_vm_provision_task_ibmcloud_resource_group.resource.id }}" location: global service: dns-svcs name: "{{ sap_vm_provision_ibmcloud_private_dns_instance_name }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" - name: Identify Private DNS Zone info - register: register_ibmcloud_pdns + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_pdns ibm.cloudcollection.ibm_dns_zones_info: - instance_id: "{{ register_ibmcloud_pdns_service_instance.resource.guid }}" + instance_id: "{{ __sap_vm_provision_task_ibmcloud_pdns_service_instance.resource.guid }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" - name: Identify OS Image list - register: register_ibmcloud_os_image_list + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_os_image_list ibm.cloudcollection.ibm_is_images_info: status: available + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" - name: Set fact to hold loop variables from include_tasks ansible.builtin.set_fact: register_provisioned_host_all: [] - name: Provision hosts to IBM Cloud - register: register_provisioned_hosts + register: __sap_vm_provision_task_provision_host_all_run ansible.builtin.include_tasks: file: "{{ 'platform_' + sap_vm_provision_iac_type }}/{{ sap_vm_provision_iac_platform }}/execute_provision.yml" apply: environment: - IC_API_KEY: "{{ sap_vm_provision_ibmcloud_api_key }}" + # IC_API_KEY: "{{ sap_vm_provision_ibmcloud_api_key }}" IC_REGION: "{{ sap_vm_provision_ibmcloud_region }}" - name: Add hosts provisioned to the Ansible Inventory - register: register_add_hosts + register: __sap_vm_provision_task_provision_host_all_add ansible.builtin.add_host: name: "{{ add_item[0].host_node }}" groups: "{{ add_item[0].sap_system_type + '_' if (add_item[0].sap_system_type != '') }}{{ add_item[0].sap_host_type }}" @@ -81,23 +108,58 @@ groups_merged_list: "{{ [ [ groups['hana_primary'] | default([]) ] , [ groups['hana_secondary'] | default([]) ] , [ groups['nwas_ascs'] | default([]) ] , [ groups['nwas_ers'] | default([]) ] , [ groups['nwas_pas'] | default([]) ] , [ groups['nwas_aas'] | default([]) ] ] | flatten | select() }}" - name: Set Ansible Vars - register: register_set_ansible_vars + register: __sap_vm_provision_task_ansible_vars_set ansible.builtin.include_tasks: file: common/set_ansible_vars.yml - name: IBM Cloud Private DNS Record for hosts - register: register_ibmcloud_pdns_record + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_pdns_record ibm.cloudcollection.ibm_dns_resource_record: - instance_id: "{{ register_ibmcloud_pdns_service_instance.resource.guid }}" - zone_id: "{{ (register_ibmcloud_pdns.resource.dns_zones | selectattr('name', '==', sap_vm_provision_dns_root_domain) | first).zone_id }}" + instance_id: "{{ __sap_vm_provision_task_ibmcloud_pdns_service_instance.resource.guid }}" + zone_id: "{{ (__sap_vm_provision_task_ibmcloud_pdns.resource.dns_zones | selectattr('name', '==', sap_vm_provision_dns_root_domain) | first).zone_id }}" name: "{{ inventory_hostname }}.{{ hostvars[inventory_hostname].sap_vm_provision_dns_root_domain }}" # Host FQDN rdata: "{{ hostvars[inventory_hostname].ansible_host }}" # IP Address type: A ttl: 7200 - failed_when: not register_ibmcloud_pdns_record.rc == 0 and not 'The record already exists' in register_ibmcloud_pdns_record.stderr + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" + failed_when: not __sap_vm_provision_task_ibmcloud_pdns_record.rc == 0 and not 'The record already exists' in __sap_vm_provision_task_ibmcloud_pdns_record.stderr # - ansible.builtin.debug: - # var: register_add_hosts.results + # var: __sap_vm_provision_task_provision_host_all_add.results + + rescue: + # This requires no_log set on each Ansible Task, and not set on the Ansible Task Block + # This requires an Ansible Task Block containing the Ansible Tasks for calling + # Infrastructure Platform APIs (via Ansible Modules) + - name: Show errors in task outputs + ansible.builtin.fail: + msg: "{{ lookup('ansible.builtin.vars', loop_item) }}" + loop: + - __sap_vm_provision_task_ibmcloud_resource_group + - __sap_vm_provision_task_ibmcloud_resource_group_dns + - __sap_vm_provision_task_ibmcloud_ssh_public_key + - __sap_vm_provision_task_ibmcloud_vpc_subnet + - __sap_vm_provision_task_ibmcloud_vpc_sg + - __sap_vm_provision_task_ibmcloud_pdns_service_instance + - __sap_vm_provision_task_ibmcloud_pdns + - __sap_vm_provision_task_ibmcloud_os_image_list + - __sap_vm_provision_task_provision_host_all_run + - __sap_vm_provision_task_provision_host_single + - __sap_vm_provision_task_provision_host_single_volumes + - __sap_vm_provision_task_provision_host_single_volume_attachments + - __sap_vm_provision_task_provision_host_single_info + - __sap_vm_provision_task_provision_host_all_add + - __sap_vm_provision_task_ibmcloud_pdns_record + loop_control: + loop_var: loop_item + index_var: loop_item_index + label: "{{ 'Variable No. ' + (loop_item_index | string) }}" + when: + - lookup('ansible.builtin.vars', loop_item, default='') | length > 0 + - not lookup('ansible.builtin.vars', loop_item, default='') is skipped + - lookup('ansible.builtin.vars', loop_item, default='') is failed + - name: Ansible Task block to execute on target inventory hosts delegate_to: "{{ inventory_hostname }}" @@ -116,19 +178,19 @@ name: "{{ inventory_hostname_short }}" - name: Set /etc/hosts - register: register_etc_hosts_file + register: __sap_vm_provision_task_os_etc_hosts ansible.builtin.include_tasks: file: common/set_etc_hosts.yml - name: Set /etc/hosts for Scale-Out - register: register_etc_hosts_file_scaleout + register: __sap_vm_provision_task_os_etc_hosts_scaleout ansible.builtin.include_tasks: file: common/set_etc_hosts_scaleout.yml when: - - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_hana_scaleout_active_coordinator is defined or sap_hana_scaleout_active_worker is defined or sap_hana_scaleout_standby is defined) + - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined or sap_vm_provision_calculate_sap_hana_scaleout_active_worker is defined or sap_vm_provision_calculate_sap_hana_scaleout_standby is defined) - name: Set vars for sap_storage_setup Ansible Role - register: register_ansible_vars_storage + register: __sap_vm_provision_task_ansible_vars_storage ansible.builtin.include_tasks: file: common/set_ansible_vars_storage.yml @@ -143,10 +205,13 @@ - name: Ansible Task block for looped provisioning of High Availability resources for IBM Cloud VS instances delegate_to: localhost + any_errors_fatal: true run_once: true + # Using environment, no_log is ineffective and log will show 'EXEC /bin/sh -c 'ENV_VAR=value python3 /AnsiballZ_ansible_module_name.py && sleep 0' + # Therefore do not use environment for secrets, use only for non-sensitive values as this will reduce Ansible Task parameters. environment: - IC_API_KEY: "{{ sap_vm_provision_ibmcloud_api_key }}" # For legacy Ansible Collection - IBMCLOUD_API_KEY: "{{ sap_vm_provision_ibmcloud_api_key }}" # For IBM Cloud CLI quiet login + # IC_API_KEY: "{{ sap_vm_provision_ibmcloud_api_key }}" # For legacy Ansible Collection + # IBMCLOUD_API_KEY: "{{ sap_vm_provision_ibmcloud_api_key }}" # For IBM Cloud CLI quiet login IC_REGION: "{{ sap_vm_provision_ibmcloud_region }}" when: - sap_ha_pacemaker_cluster_ibmcloud_region is defined @@ -158,10 +223,97 @@ file: "{{ 'platform_' + sap_vm_provision_iac_type }}/{{ sap_vm_provision_iac_platform }}/execute_setup_ha.yml" apply: environment: - IC_API_KEY: "{{ sap_vm_provision_ibmcloud_api_key }}" # For legacy Ansible Collection - IBMCLOUD_API_KEY: "{{ sap_vm_provision_ibmcloud_api_key }}" # For IBM Cloud CLI quiet login + # IC_API_KEY: "{{ sap_vm_provision_ibmcloud_api_key }}" # For legacy Ansible Collection + # IBMCLOUD_API_KEY: "{{ sap_vm_provision_ibmcloud_api_key }}" # For IBM Cloud CLI quiet login IC_REGION: "{{ sap_vm_provision_ibmcloud_region }}" + rescue: + # This requires no_log set on each Ansible Task, and not set on the Ansible Task Block + # This requires an Ansible Task Block containing the Ansible Tasks for calling + # Infrastructure Platform APIs (via Ansible Modules) + - name: Show errors in task outputs + ansible.builtin.fail: + msg: "{{ lookup('ansible.builtin.vars', loop_item) }}" + loop: + - __sap_vm_provision_task_ibmcloud_iam_auth_policy + - __sap_vm_provision_task_ibmcloud_lb_provision_parallel + - __sap_vm_provision_task_ibmcloud_lb_provision_parallel_async_status + - __sap_vm_provision_task_ibmcloud_lb_update_dns + - __sap_vm_provision_task_ibmcloud_vs_all_info + - __sap_vm_provision_task_ibmcloud_lb_all_info_shell + - __sap_vm_provision_task_ibmcloud_lb_pool_hana1 + - __sap_vm_provision_task_ibmcloud_lb_pool_hana2 + - __sap_vm_provision_task_ibmcloud_lb_pool_hana3 + - __sap_vm_provision_task_ibmcloud_lb_pool_hana4 + - __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ascs1 + - __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ascs2 + - __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ascs3 + - __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ascs4 + - __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ascs5 + - __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ers1 + - __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ers2 + - __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ers3 + - __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ers4 + - __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ers5 + - __sap_vm_provision_task_ibmcloud_lb_pools + - __sap_vm_provision_task_ibmcloud_lb_pool_members_hana1 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_hana2 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_hana3 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_hana4 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_hana5 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_hana6 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_hana7 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_hana8 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_anydb1 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_anydb2 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs1 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs2 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs3 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs4 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs5 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs6 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs7 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs8 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs9 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs10 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers1 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers2 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers3 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers4 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers5 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers6 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers7 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers8 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers9 + - __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers10 + - __sap_vm_provision_task_ibmcloud_lb_frontend_listener_hana1 + - __sap_vm_provision_task_ibmcloud_lb_frontend_listener_hana2 + - __sap_vm_provision_task_ibmcloud_lb_frontend_listener_hana3 + - __sap_vm_provision_task_ibmcloud_lb_frontend_listener_hana4 + - __sap_vm_provision_task_ibmcloud_lb_frontend_listener_anydb1 + - __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ascs1 + - __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ascs2 + - __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ascs3 + - __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ascs4 + - __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ascs5 + - __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ers1 + - __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ers2 + - __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ers3 + - __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ers4 + - __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ers5 + - __sap_vm_provision_task_ibmcloud_pdns_record_ha_hana + - __sap_vm_provision_task_ibmcloud_pdns_record_ha_anydb + - __sap_vm_provision_task_ibmcloud_pdns_record_ha_nwas_ascs + - __sap_vm_provision_task_ibmcloud_pdns_record_ha_nwas_ers + loop_control: + loop_var: loop_item + index_var: loop_item_index + label: "{{ 'Variable No. ' + (loop_item_index | string) }}" + when: + - lookup('ansible.builtin.vars', loop_item, default='') | length > 0 + - not lookup('ansible.builtin.vars', loop_item, default='') is skipped + - lookup('ansible.builtin.vars', loop_item, default='') is failed + - name: Ansible Task block to execute on target inventory hosts for HA delegate_to: "{{ inventory_hostname }}" @@ -171,6 +323,6 @@ block: - name: Set /etc/hosts for HA - register: register_etc_hosts_file_ha + register: __sap_vm_provision_task_os_etc_hosts_ha ansible.builtin.include_tasks: file: common/set_etc_hosts_ha.yml diff --git a/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_vs/execute_provision.yml b/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_vs/execute_provision.yml index 3f61147..cc0525e 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_vs/execute_provision.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_vs/execute_provision.yml @@ -1,35 +1,41 @@ --- # The tasks in this file are executed in a loop over the defined hosts +- name: Ensure short hostname is not longer than 13 characters (see SAP Note 611361) + ansible.builtin.assert: + that: (inventory_hostname | length | int) <= (13 | int) + fail_msg: "FAIL: The length of the hostname is {{ inventory_hostname | length | int }} but must be less or equal to 13 characters!" + # When SAP HANA Scale-Out is used, if host name is not in original specifications then strip suffix node number from host name - name: Set fact when performing SAP HANA Scale-Out ansible.builtin.set_fact: scaleout_origin_host_spec: "{{ inventory_hostname | regex_replace('^(.+?)\\d*$', '\\1') }}" when: - - sap_hana_scaleout_active_coordinator is defined + - sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined - not inventory_hostname in lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan].keys() - name: Provision IBM Cloud Virtual Server instance - register: register_provisioned_host_single + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single ibm.cloudcollection.ibm_is_instance: state: available name: "{{ inventory_hostname }}" - image: "{{ (register_ibmcloud_os_image_list.resource.images | select('search', lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_os_image_dictionary')[sap_vm_provision_ibmcloud_vs_host_os_image]) | sort(reverse=True,case_sensitive=False,attribute='name') | first).id }}" + image: "{{ (__sap_vm_provision_task_ibmcloud_os_image_list.resource.images | select('search', lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_os_image_dictionary')[sap_vm_provision_ibmcloud_vs_host_os_image]) | sort(reverse=True,case_sensitive=False,attribute='name') | first).id }}" profile: "{{ lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].virtual_machine_profile }}" keys: - - "{{ register_ibmcloud_ssh_public_key.resource.id }}" + - "{{ __sap_vm_provision_task_ibmcloud_ssh_public_key.resource.id }}" - resource_group: "{{ register_ibmcloud_resource_group.resource.id }}" + resource_group: "{{ __sap_vm_provision_task_ibmcloud_resource_group.resource.id }}" zone: "{{ sap_vm_provision_ibmcloud_availability_zone }}" - vpc: "{{ register_ibmcloud_vpc_subnet.resource.vpc }}" + vpc: "{{ __sap_vm_provision_task_ibmcloud_vpc_subnet.resource.vpc }}" # The Subnet assigned to the primary Virtual Network Interface (vNIC) cannot be changed # The Name and Security Group assigned to the Primary Network Interface (vNIC) are editable primary_network_interface: - name: "{{ inventory_hostname }}-vnic0" - subnet: "{{ register_ibmcloud_vpc_subnet.resource.id }}" + subnet: "{{ __sap_vm_provision_task_ibmcloud_vpc_subnet.resource.id }}" allow_ip_spoofing: "{{ lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].disable_ip_anti_spoofing }}" # When disable the Anti IP Spoofing = true, then Allow IP Spoofing = true - security_groups: "{{ register_ibmcloud_vpc_sg.results | map(attribute='resource.id') }}" + security_groups: "{{ __sap_vm_provision_task_ibmcloud_vpc_sg.results | map(attribute='resource.id') }}" #network_interfaces: auto_delete_volume: true @@ -41,6 +47,8 @@ protocol: https response_hop_limit: 5 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" + # Create flat list with names for each volume to be created. - name: Set fact for target device map @@ -67,12 +75,15 @@ {{ disks_map }} - name: Provision IBM Cloud Block Storage volumes for IBM Cloud VS instance filesystems + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_volumes ibm.cloudcollection.ibm_is_volume: - resource_group: "{{ register_ibmcloud_resource_group.resource.id }}" + resource_group: "{{ __sap_vm_provision_task_ibmcloud_resource_group.resource.id }}" zone: "{{ sap_vm_provision_ibmcloud_availability_zone }}" name: "{{ inventory_hostname + '-vol-' + vol_item.name | replace('_', '-')}}" profile: "{{ vol_item.type }}" capacity: "{{ vol_item.size }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ storage_disks_map }}" loop_control: loop_var: vol_item @@ -80,16 +91,18 @@ label: "{{ vol_item.definition_key }}: {{ vol_item.name }} (size: {{ vol_item.size }})" when: - vol_item.size > 0 - register: volume_provisioning - name: Attach IBM Cloud Block Storage volumes as filesystem for IBM Cloud VS instance + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_volume_attachments ibm.cloudcollection.ibm_is_instance_volume_attachment: name: "{{ vol_item.resource.name }}-attach" volume: "{{ vol_item.resource.id }}" - instance: "{{ register_provisioned_host_single.resource.id }}" + instance: "{{ __sap_vm_provision_task_provision_host_single.resource.id }}" delete_volume_on_attachment_delete: true delete_volume_on_instance_delete: true - loop: "{{ volume_provisioning.results }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" + loop: "{{ __sap_vm_provision_task_provision_host_single_volumes.results }}" loop_control: loop_var: vol_item index_var: vol_item_index @@ -97,21 +110,23 @@ - name: Read IBM Cloud VS information + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_info ibm.cloudcollection.ibm_is_instance: - name: "{{ register_provisioned_host_single.resource.name }}" - register: instance_info + name: "{{ __sap_vm_provision_task_provision_host_single.resource.name }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" - name: Add host facts ansible.builtin.set_fact: - volume_provisioning: "{{ volume_provisioning }}" - instance_info: "{{ instance_info }}" + __sap_vm_provision_task_provision_host_single_volumes: "{{ __sap_vm_provision_task_provision_host_single_volumes }}" + __sap_vm_provision_task_provision_host_single_info: "{{ __sap_vm_provision_task_provision_host_single_info }}" delegate_to: "{{ inventory_hostname }}" delegate_facts: true - name: Create fact for delegate host IP ansible.builtin.set_fact: - provisioned_private_ip: "{{ register_provisioned_host_single.resource.primary_network_interface[0].primary_ipv4_address }}" + provisioned_private_ip: "{{ __sap_vm_provision_task_provision_host_single.resource.primary_network_interface[0].primary_ipv4_address }}" - name: Copy facts to delegate host @@ -123,7 +138,7 @@ delegate_sap_vm_provision_bastion_ssh_port: "{{ sap_vm_provision_bastion_ssh_port }}" delegate_sap_vm_provision_ssh_bastion_private_key_file_path: "{{ sap_vm_provision_ssh_bastion_private_key_file_path }}" delegate_sap_vm_provision_ssh_host_private_key_file_path: "{{ sap_vm_provision_ssh_host_private_key_file_path }}" - delegate_private_ip: "{{ register_provisioned_host_single.resource.primary_network_interface[0].primary_ipv4_address }}" + delegate_private_ip: "{{ __sap_vm_provision_task_provision_host_single.resource.primary_network_interface[0].primary_ipv4_address }}" delegate_hostname: "{{ inventory_hostname }}" delegate_sap_vm_provision_dns_root_domain_name: "{{ sap_vm_provision_dns_root_domain }}" @@ -151,29 +166,29 @@ dest: /root/.ssh/authorized_keys mode: '0600' content: | - {{ register_ibmcloud_ssh_public_key.resource.public_key }} + {{ __sap_vm_provision_task_ibmcloud_ssh_public_key.resource.public_key }} - name: Permit root login + register: __sap_vm_provision_task_os_sshd_config ansible.builtin.replace: path: /etc/ssh/sshd_config regexp: '(^PermitRootLogin no)' replace: 'PermitRootLogin yes' - register: sshd_config - name: Reload sshd service ansible.builtin.service: name: sshd state: reloaded when: - - sshd_config.changed + - __sap_vm_provision_task_os_sshd_config.changed ### end of block - name: Append loop value to register ansible.builtin.set_fact: - register_provisioned_host_single: "{{ register_provisioned_host_single | combine( { 'host_node' : inventory_hostname } , { 'sap_host_type' : lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_host_type } , { 'sap_system_type' : (lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_system_type | default('')) } ) }}" + __sap_vm_provision_task_provision_host_single: "{{ __sap_vm_provision_task_provision_host_single | combine( { 'host_node' : inventory_hostname } , { 'sap_host_type' : lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_host_type } , { 'sap_system_type' : (lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_system_type | default('')) } ) }}" - name: Append output to merged register ansible.builtin.set_fact: - register_provisioned_host_all: "{{ register_provisioned_host_all + [register_provisioned_host_single] }}" + register_provisioned_host_all: "{{ register_provisioned_host_all + [__sap_vm_provision_task_provision_host_single] }}" diff --git a/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_vs/execute_setup_ha.yml b/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_vs/execute_setup_ha.yml index bc0efc1..eeeb283 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_vs/execute_setup_ha.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_vs/execute_setup_ha.yml @@ -1,15 +1,17 @@ --- - name: Create IBM Cloud IAM Authorization Policy for IBM Cloud Load Balancer to communicate with IBM Cloud Private DNS - register: ibmcloud_iam_auth_policy + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_iam_auth_policy ibm.cloudcollection.ibm_iam_authorization_policy: roles: Manager - source_resource_group_id: "{{ register_ibmcloud_resource_group.resource.id }}" - target_resource_group_id: "{{ register_ibmcloud_resource_group.resource.id }}" + source_resource_group_id: "{{ __sap_vm_provision_task_ibmcloud_resource_group.resource.id }}" + target_resource_group_id: "{{ __sap_vm_provision_task_ibmcloud_resource_group.resource.id }}" source_service_name: is source_resource_type: load-balancer target_service_name: dns-svcs - failed_when: not ibmcloud_iam_auth_policy.rc == 0 and not 'access policy with identical attributes already exists' in ibmcloud_iam_auth_policy.stderr + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" + failed_when: not __sap_vm_provision_task_ibmcloud_iam_auth_policy.rc == 0 and not 'access policy with identical attributes already exists' in __sap_vm_provision_task_ibmcloud_iam_auth_policy.stderr # The IBM Cloud Load Balancer is provisioned before Linux Pacemaker and requires a temporary Health Check Probe port to be used with an an active OS service listening. @@ -25,20 +27,22 @@ # Private Network Load Balancer (Layer 4), restricts HA within single Availability Zone. Permits TCP and UDP, does not permit HTTP/S. # Use async with poll '0' to create all IBM Cloud Load Balancers in parallel - name: Create IBM Cloud Load Balancer (Private ALB) for each Virtual Hostname / Virtual IP required - register: ibmcloud_lb_provision_parallel + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_provision_parallel ibm.cloudcollection.ibm_is_lb: - resource_group: "{{ register_ibmcloud_resource_group.resource.id }}" + resource_group: "{{ __sap_vm_provision_task_ibmcloud_resource_group.resource.id }}" name: "{{ item }}" type: private - subnets: ["{{ register_ibmcloud_vpc_subnet.resource.id }}"] - security_groups: "{{ register_ibmcloud_vpc_sg.results | map(attribute='resource.id') }}" + subnets: ["{{ __sap_vm_provision_task_ibmcloud_vpc_subnet.resource.id }}"] + security_groups: "{{ __sap_vm_provision_task_ibmcloud_vpc_sg.results | map(attribute='resource.id') }}" #access_tags: logging: true # For ALB L7, not NLB L4 #profile: network-fixed / dynamic # For NLB L4, not ALB L7 #route_mode: false # For NLB L4, not ALB L7 # dns: # Unsupported by legacy Ansible Collection, use IBM Cloud CLI as workaround - # instance_crn: "{{ register_ibmcloud_pdns_service_instance.resource.resource_crn }}" - # zone_id: "{{ (register_ibmcloud_pdns.resource.dns_zones | selectattr('name', '==', sap_vm_provision_dns_root_domain) | first).zone_id }}" + # instance_crn: "{{ __sap_vm_provision_task_ibmcloud_pdns_service_instance.resource.resource_crn }}" + # zone_id: "{{ (__sap_vm_provision_task_ibmcloud_pdns.resource.dns_zones | selectattr('name', '==', sap_vm_provision_dns_root_domain) | first).zone_id }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: - "{{ 'lb-sap-ha-hana' if (groups['hana_secondary'] is defined and (groups['hana_secondary'] | length>0)) else '' }}" - "{{ 'lb-sap-ha-anydb' if (groups['anydb_secondary'] is defined and (groups['anydb_secondary'] | length>0)) else '' }}" @@ -51,53 +55,64 @@ poll: 0 # parallel - name: Wait for IBM Cloud Load Balancer provisioning - register: async_status_ibmcloud_lb_provision_parallel + register: __sap_vm_provision_task_ibmcloud_lb_provision_parallel_async_status ansible.builtin.async_status: jid: "{{ item.ansible_job_id }}" retries: 40 delay: 30 # seconds - until: async_status_ibmcloud_lb_provision_parallel.finished - loop: "{{ ibmcloud_lb_provision_parallel.results | selectattr('ansible_job_id', 'defined') }}" - # failed_when: not async_status_ibmcloud_lb_provision_parallel.rc == 0 + until: __sap_vm_provision_task_ibmcloud_lb_provision_parallel_async_status.finished + loop: "{{ __sap_vm_provision_task_ibmcloud_lb_provision_parallel.results | selectattr('ansible_job_id', 'defined') }}" + # failed_when: not __sap_vm_provision_task_ibmcloud_lb_provision_parallel_async_status.rc == 0 # Workaround to missing Ansible Module functionality in legacy Ansible Collection - name: IBM Cloud CLI append DNS to Load Balancer - register: ibmcloud_lb_update_dns + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_update_dns ansible.builtin.shell: | - ibmcloud config --quiet --check-version false && ibmcloud login -g {{ sap_vm_provision_ibmcloud_resource_group_name }} -r {{ sap_vm_provision_ibmcloud_region }} --quiet + ibmcloud config --quiet --check-version false && ibmcloud login --apikey="{{ sap_vm_provision_ibmcloud_api_key }}" -g {{ sap_vm_provision_ibmcloud_resource_group_name }} -r {{ sap_vm_provision_ibmcloud_region }} --quiet ibmcloud plugin install infrastructure-service -f --quiet - ibmcloud is load-balancer-update "{{ item }}" --dns-instance-crn "{{ register_ibmcloud_pdns_service_instance.resource.resource_crn }}" --dns-zone-id "{{ (register_ibmcloud_pdns.resource.dns_zones | selectattr('name', '==', sap_vm_provision_dns_root_domain) | first).zone_id }}" + ibmcloud is load-balancer-update "{{ item }}" --dns-instance-crn "{{ __sap_vm_provision_task_ibmcloud_pdns_service_instance.resource.resource_crn }}" --dns-zone-id "{{ (__sap_vm_provision_task_ibmcloud_pdns.resource.dns_zones | selectattr('name', '==', sap_vm_provision_dns_root_domain) | first).zone_id }}" loop: - "{{ 'lb-sap-ha-hana' if (groups['hana_secondary'] is defined and (groups['hana_secondary'] | length>0)) else '' }}" - "{{ 'lb-sap-ha-anydb' if (groups['anydb_secondary'] is defined and (groups['anydb_secondary'] | length>0)) else '' }}" - "{{ 'lb-sap-ha-nwas-ascs' if (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) else '' }}" - "{{ 'lb-sap-ha-nwas-ers' if (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) else '' }}" when: not item == '' - failed_when: not ibmcloud_lb_update_dns.rc == 0 and not 'nothing to update the load balancer with' in ibmcloud_lb_update_dns.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_update_dns.rc == 0 and not 'nothing to update the load balancer with' in __sap_vm_provision_task_ibmcloud_lb_update_dns.stderr - name: Identify IBM Cloud Virtual Servers info - register: ibmcloud_vs_all_info + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_vs_all_info ibm.cloudcollection.ibm_is_instances_info: - vpc: "{{ register_ibmcloud_vpc_subnet.resource.vpc }}" + vpc: "{{ __sap_vm_provision_task_ibmcloud_vpc_subnet.resource.vpc }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" # Workaround for bug which populates region and ibmcloud_api_key as TF arguments for ibm_is_lbs_info Ansible Module in legacy Ansible Collection - name: IBM Cloud CLI execution to list Load Balancer/s info - register: ibmcloud_lbs_all_info_shell + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_all_info_shell ansible.builtin.shell: | - ibmcloud config --quiet --check-version false && ibmcloud login -g {{ sap_vm_provision_ibmcloud_resource_group_name }} -r {{ sap_vm_provision_ibmcloud_region }} --quiet + ibmcloud config --quiet --check-version false && ibmcloud login --apikey="{{ sap_vm_provision_ibmcloud_api_key }}" -g {{ sap_vm_provision_ibmcloud_resource_group_name }} -r {{ sap_vm_provision_ibmcloud_region }} --quiet #ibmcloud plugin install infrastructure-service -f --quiet ibmcloud is load-balancers --quiet --output json - name: Set fact for IBM Cloud Load Balancer/s info ansible.builtin.set_fact: - ibmcloud_lbs_all_info: "{{ ibmcloud_lbs_all_info_shell.stdout | split('Space:') | last | trim | from_json }}" + ibmcloud_lbs_all_info: "{{ __sap_vm_provision_task_ibmcloud_lb_all_info_shell.stdout | split('Space:') | last | trim | from_json }}" + +# Required because CLI executed with API Key +- name: Set fact for Ansible Tasks debug with redaction + ansible.builtin.set_fact: + __sap_vm_provision_task_ibmcloud_lb_update_dns: "{{ __sap_vm_provision_task_ibmcloud_lb_update_dns | regex_replace(sap_vm_provision_ibmcloud_api_key) }}" + __sap_vm_provision_task_ibmcloud_lb_all_info_shell: "{{ __sap_vm_provision_task_ibmcloud_lb_all_info_shell | regex_replace(sap_vm_provision_ibmcloud_api_key) }}" # Create IBM Cloud Load Balancer Back-end Pools - name: Create IBM Cloud Load Balancer Back-end Pool for SAP HANA - System DB SQL - register: __ibmcloud_lb_pool_hana1 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_hana1 ibm.cloudcollection.ibm_is_lb_pool: name: lb-sap-ha-hana-pool-sysdb-sql lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-hana'))[0].id }}" @@ -108,10 +123,12 @@ health_timeout: 10 health_type: tcp health_monitor_port: 55550 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['hana_secondary'] is defined and (groups['hana_secondary'] | length>0)) - name: Create IBM Cloud Load Balancer Back-end Pool for SAP HANA - MDC Tenant 1 SQL - register: __ibmcloud_lb_pool_hana2 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_hana2 ibm.cloudcollection.ibm_is_lb_pool: name: lb-sap-ha-hana-pool-mdc1-sql lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-hana'))[0].id }}" @@ -122,10 +139,12 @@ health_timeout: 10 health_type: tcp health_monitor_port: 55550 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['hana_secondary'] is defined and (groups['hana_secondary'] | length>0)) - name: Create IBM Cloud Load Balancer Back-end Pool for SAP HANA - startsrv HTTP - register: __ibmcloud_lb_pool_hana3 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_hana3 ibm.cloudcollection.ibm_is_lb_pool: name: lb-sap-ha-hana-pool-startsrv-http lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-hana'))[0].id }}" @@ -136,10 +155,12 @@ health_timeout: 10 health_type: tcp health_monitor_port: 55550 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['hana_secondary'] is defined and (groups['hana_secondary'] | length>0)) - name: Create IBM Cloud Load Balancer Back-end Pool for SAP HANA - startsrv HTTPS - register: __ibmcloud_lb_pool_hana4 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_hana4 ibm.cloudcollection.ibm_is_lb_pool: name: lb-sap-ha-hana-pool-startsrv-https lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-hana'))[0].id }}" @@ -150,9 +171,11 @@ health_timeout: 10 health_type: tcp health_monitor_port: 55550 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['hana_secondary'] is defined and (groups['hana_secondary'] | length>0)) - name: Create IBM Cloud Load Balancer Back-end Pool for SAP AnyDB - IBM Db2 Communication Port + no_log: "{{ __sap_vm_provision_no_log }}" ibm.cloudcollection.ibm_is_lb_pool: name: lb-sap-ha-anydb-pool-ibmdb2 lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-anydb'))[0].id }}" @@ -163,10 +186,12 @@ health_timeout: 10 health_type: tcp health_monitor_port: 55550 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['anydb_secondary'] is defined and (groups['anydb_secondary'] | length>0)) - name: Create IBM Cloud Load Balancer Back-end Pool for SAP NetWeaver ASCS - Dispatcher sapdp process - register: __ibmcloud_lb_pool_nwas_ascs1 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ascs1 ibm.cloudcollection.ibm_is_lb_pool: name: lb-sap-ha-nwas-ascs-pool-dp lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}" @@ -177,10 +202,12 @@ health_timeout: 10 health_type: tcp health_monitor_port: 55551 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - name: Create IBM Cloud Load Balancer Back-end Pool for SAP NetWeaver ASCS - Message Server sapms process - register: __ibmcloud_lb_pool_nwas_ascs2 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ascs2 ibm.cloudcollection.ibm_is_lb_pool: name: lb-sap-ha-nwas-ascs-pool-ms lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}" @@ -191,10 +218,12 @@ health_timeout: 10 health_type: tcp health_monitor_port: 55551 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - name: Create IBM Cloud Load Balancer Back-end Pool for SAP NetWeaver ASCS - Enqueue Server sapenq process - register: __ibmcloud_lb_pool_nwas_ascs3 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ascs3 ibm.cloudcollection.ibm_is_lb_pool: name: lb-sap-ha-nwas-ascs-pool-enq lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}" @@ -205,10 +234,12 @@ health_timeout: 10 health_type: tcp health_monitor_port: 55551 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - name: Create IBM Cloud Load Balancer Back-end Pool for SAP NetWeaver ASCS - SAP Start Service (SAPControl SOAP) HTTP sapctrl process - register: __ibmcloud_lb_pool_nwas_ascs4 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ascs4 ibm.cloudcollection.ibm_is_lb_pool: name: lb-sap-ha-nwas-ascs-pool-sapctrl lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}" @@ -219,10 +250,12 @@ health_timeout: 10 health_type: tcp health_monitor_port: 55551 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - name: Create IBM Cloud Load Balancer Back-end Pool for SAP NetWeaver ASCS - SAP Start Service (SAPControl SOAP) HTTPS (Secure) sapctrls - register: __ibmcloud_lb_pool_nwas_ascs5 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ascs5 ibm.cloudcollection.ibm_is_lb_pool: name: lb-sap-ha-nwas-ascs-pool-sapctrls lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}" @@ -233,10 +266,12 @@ health_timeout: 10 health_type: tcp health_monitor_port: 55551 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) # - name: Create IBM Cloud Load Balancer Back-end Pool for SAP NetWeaver ERS - Dispatcher sapdp process -# register: __ibmcloud_lb_pool_nwas_ers1 +# no_log: "{{ __sap_vm_provision_no_log }}" +# register: __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ers1 # ibm.cloudcollection.ibm_is_lb_pool: # name: lb-sap-ha-nwas-ers-pool-dp # lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}" @@ -247,10 +282,12 @@ # health_timeout: 10 # health_type: tcp # health_monitor_port: 55552 +# ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" # when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) # - name: Create IBM Cloud Load Balancer Back-end Pool for SAP NetWeaver ERS - Message Server sapms process -# register: __ibmcloud_lb_pool_nwas_ers2 +# no_log: "{{ __sap_vm_provision_no_log }}" +# register: __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ers2 # ibm.cloudcollection.ibm_is_lb_pool: # name: lb-sap-ha-nwas-ers-pool-ms # lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}" @@ -261,10 +298,12 @@ # health_timeout: 10 # health_type: tcp # health_monitor_port: 55552 +# ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" # when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - name: Create IBM Cloud Load Balancer Back-end Pool for SAP NetWeaver ERS - Enqueue Replication Server sapenqr process - register: __ibmcloud_lb_pool_nwas_ers3 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ers3 ibm.cloudcollection.ibm_is_lb_pool: name: lb-sap-ha-nwas-ers-pool-enqr lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}" @@ -275,10 +314,12 @@ health_timeout: 10 health_type: tcp health_monitor_port: 55552 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - name: Create IBM Cloud Load Balancer Back-end Pool for SAP NetWeaver ERS - SAP Start Service (SAPControl SOAP) HTTP sapctrl process - register: __ibmcloud_lb_pool_nwas_ers4 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ers4 ibm.cloudcollection.ibm_is_lb_pool: name: lb-sap-ha-nwas-ers-pool-sapctrl lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}" @@ -289,10 +330,12 @@ health_timeout: 10 health_type: tcp health_monitor_port: 55552 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - name: Create IBM Cloud Load Balancer Back-end Pool for SAP NetWeaver ERS - SAP Start Service (SAPControl SOAP) HTTPS (Secure) sapctrls - register: __ibmcloud_lb_pool_nwas_ers5 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ers5 ibm.cloudcollection.ibm_is_lb_pool: name: lb-sap-ha-nwas-ers-pool-sapctrls lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}" @@ -303,15 +346,18 @@ health_timeout: 10 health_type: tcp health_monitor_port: 55552 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) # Identify the provisioned IBM Cloud Load Balancer Back-end Pools - name: Identify IBM Cloud Load Balancer Back-end Pools - register: __ibmcloud_lb_pools + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pools ibm.cloudcollection.ibm_is_lb_pools_info: lb: "{{ item }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ ibmcloud_lbs_all_info | map(attribute='id') }}" @@ -319,634 +365,726 @@ # Primary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP HANA - System DB SQL - Member 1 - register: __ibmcloud_lb_pool_members_hana1 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_hana1 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-hana'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-sysdb-sql'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-sysdb-sql'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('3' + sap_system_hana_db_instance_nr + '13') | int }}" weight: 100 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['hana_primary'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['hana_secondary'] is defined and (groups['hana_secondary'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_hana1.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_hana1.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_hana1.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_hana1.stderr # Secondary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP HANA - System DB SQL - Member 2 (Failover/Secondary) - register: __ibmcloud_lb_pool_members_hana2 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_hana2 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-hana'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-sysdb-sql'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-sysdb-sql'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('3' + sap_system_hana_db_instance_nr + '13') | int }}" weight: 1 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['hana_secondary'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['hana_secondary'] is defined and (groups['hana_secondary'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_hana2.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_hana2.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_hana2.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_hana2.stderr # Primary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP HANA - MDC Tenant 1 SQL - Member 1 - register: __ibmcloud_lb_pool_members_hana3 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_hana3 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-hana'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-mdc1-sql'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-mdc1-sql'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('3' + sap_system_hana_db_instance_nr + '15') | int }}" weight: 100 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['hana_primary'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['hana_secondary'] is defined and (groups['hana_secondary'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_hana3.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_hana3.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_hana3.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_hana3.stderr # Secondary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP HANA - MDC Tenant 1 SQL - Member 2 (Failover/Secondary) - register: __ibmcloud_lb_pool_members_hana4 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_hana4 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-hana'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-mdc1-sql'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-mdc1-sql'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('3' + sap_system_hana_db_instance_nr + '15') | int }}" weight: 1 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['hana_secondary'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['hana_secondary'] is defined and (groups['hana_secondary'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_hana4.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_hana4.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_hana4.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_hana4.stderr # Primary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP HANA - startsrv HTTP - Member 1 - register: __ibmcloud_lb_pool_members_hana5 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_hana5 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-hana'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-startsrv-http'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-startsrv-http'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('5' + sap_system_hana_db_instance_nr + '13') | int }}" weight: 100 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['hana_primary'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['hana_secondary'] is defined and (groups['hana_secondary'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_hana5.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_hana5.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_hana5.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_hana5.stderr # Secondary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP HANA - startsrv HTTP - Member 2 (Failover/Secondary) - register: __ibmcloud_lb_pool_members_hana6 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_hana6 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-hana'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-startsrv-http'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-startsrv-http'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('5' + sap_system_hana_db_instance_nr + '13') | int }}" weight: 1 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['hana_secondary'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['hana_secondary'] is defined and (groups['hana_secondary'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_hana6.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_hana6.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_hana6.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_hana6.stderr # Primary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP HANA - startsrv HTTPS - Member 1 - register: __ibmcloud_lb_pool_members_hana7 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_hana7 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-hana'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-startsrv-https'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-startsrv-https'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('5' + sap_system_hana_db_instance_nr + '14') | int }}" weight: 100 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['hana_primary'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['hana_secondary'] is defined and (groups['hana_secondary'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_hana7.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_hana7.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_hana7.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_hana7.stderr # Secondary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP HANA - startsrv HTTPS - Member 2 (Failover/Secondary) - register: __ibmcloud_lb_pool_members_hana8 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_hana8 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-hana'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-startsrv-https'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-startsrv-https'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('5' + sap_system_hana_db_instance_nr + '14') | int }}" weight: 1 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['hana_secondary'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['hana_secondary'] is defined and (groups['hana_secondary'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_hana8.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_hana8.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_hana8.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_hana8.stderr # Primary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP AnyDB - IBM Db2 Communication Port - Member 1 - register: __ibmcloud_lb_pool_members_anydb1 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_anydb1 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-anydb'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-anydb-pool-ibmdb2'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-anydb-pool-ibmdb2'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: 5912 weight: 100 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['anydb_primary'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['anydb_secondary'] is defined and (groups['anydb_secondary'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_anydb1.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_anydb1.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_anydb1.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_anydb1.stderr # Secondary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP AnyDB - IBM Db2 Communication Port - Member 2 (Failover/Secondary) - register: __ibmcloud_lb_pool_members_anydb2 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_anydb2 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-anydb'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-anydb-pool-ibmdb2'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-anydb-pool-ibmdb2'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: 5912 weight: 1 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['anydb_secondary'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['anydb_secondary'] is defined and (groups['anydb_secondary'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_anydb2.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_anydb2.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_anydb2.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_anydb2.stderr # Primary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP NetWeaver ASCS - Dispatcher sapdp process - Member 1 - register: __ibmcloud_lb_pool_members_nwas_ascs1 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs1 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-dp'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-dp'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('32' + sap_system_nwas_abap_ascs_instance_nr) | int }}" weight: 100 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['nwas_ascs'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_nwas_ascs1.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_nwas_ascs1.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs1.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs1.stderr # Secondary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP NetWeaver ASCS - Dispatcher sapdp process - Member 2 (Failover/Secondary) - register: __ibmcloud_lb_pool_members_nwas_ascs2 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs2 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-dp'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-dp'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('32' + sap_system_nwas_abap_ascs_instance_nr) | int }}" weight: 1 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['nwas_ers'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_nwas_ascs2.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_nwas_ascs2.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs2.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs2.stderr # Primary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP NetWeaver ASCS - Message Server sapms process - Member 1 - register: __ibmcloud_lb_pool_members_nwas_ascs3 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs3 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-ms'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-ms'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('36' + sap_system_nwas_abap_ascs_instance_nr) | int }}" weight: 100 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['nwas_ascs'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_nwas_ascs3.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_nwas_ascs3.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs3.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs3.stderr # Secondary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP NetWeaver ASCS - Message Server sapms process - Member 2 (Failover/Secondary) - register: __ibmcloud_lb_pool_members_nwas_ascs4 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs4 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-ms'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-ms'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('36' + sap_system_nwas_abap_ascs_instance_nr) | int }}" weight: 1 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['nwas_ers'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_nwas_ascs4.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_nwas_ascs4.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs4.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs4.stderr # Primary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP NetWeaver ASCS - Enqueue Server sapenq process - Member 1 - register: __ibmcloud_lb_pool_members_nwas_ascs5 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs5 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-enq'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-enq'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('39' + sap_system_nwas_abap_ascs_instance_nr) | int }}" weight: 100 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['nwas_ascs'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_nwas_ascs5.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_nwas_ascs5.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs5.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs5.stderr # Secondary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP NetWeaver ASCS - Enqueue Server sapenq process - Member 2 (Failover/Secondary) - register: __ibmcloud_lb_pool_members_nwas_ascs6 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs6 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-enq'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-enq'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('39' + sap_system_nwas_abap_ascs_instance_nr) | int }}" weight: 1 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['nwas_ers'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_nwas_ascs6.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_nwas_ascs6.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs6.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs6.stderr # Primary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP NetWeaver ASCS - SAP Start Service (SAPControl SOAP) HTTP sapctrl process - Member 1 - register: __ibmcloud_lb_pool_members_nwas_ascs7 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs7 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-sapctrl'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-sapctrl'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('5' + sap_system_nwas_abap_ascs_instance_nr + '13') | int }}" weight: 100 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['nwas_ascs'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_nwas_ascs7.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_nwas_ascs7.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs7.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs7.stderr # Secondary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP NetWeaver ASCS - SAP Start Service (SAPControl SOAP) HTTP sapctrl process - Member 2 (Failover/Secondary) - register: __ibmcloud_lb_pool_members_nwas_ascs8 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs8 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-sapctrl'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-sapctrl'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('5' + sap_system_nwas_abap_ascs_instance_nr + '13') | int }}" weight: 1 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['nwas_ers'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_nwas_ascs8.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_nwas_ascs8.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs8.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs8.stderr # Primary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP NetWeaver ASCS - SAP Start Service (SAPControl SOAP) HTTPS (Secure) sapctrls - Member 1 - register: __ibmcloud_lb_pool_members_nwas_ascs9 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs9 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-sapctrls'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-sapctrls'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('5' + sap_system_nwas_abap_ascs_instance_nr + '14') | int }}" weight: 100 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['nwas_ascs'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_nwas_ascs9.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_nwas_ascs9.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs9.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs9.stderr # Secondary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP NetWeaver ASCS - SAP Start Service (SAPControl SOAP) HTTPS (Secure) sapctrls - Member 2 (Failover/Secondary) - register: __ibmcloud_lb_pool_members_nwas_ascs10 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs10 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-sapctrls'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-sapctrls'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('5' + sap_system_nwas_abap_ascs_instance_nr + '14') | int }}" weight: 1 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['nwas_ers'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_nwas_ascs10.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_nwas_ascs10.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs10.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ascs10.stderr # Primary # - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP NetWeaver ERS - Dispatcher sapdp process - Member 1 -# register: __ibmcloud_lb_pool_members_nwas_ers1 +# no_log: "{{ __sap_vm_provision_no_log }}" +# register: __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers1 # ibm.cloudcollection.ibm_is_lb_pool_member: # lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}" -# pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-dp'))[0].id }}" -# target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" +# pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-dp'))[0].id }}" +# target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" # port: "{{ ('32' + sap_system_nwas_abap_ers_instance_nr) | int }}" # weight: 100 +# ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" # loop: "{{ (groups['nwas_ers'] | default([]) ) }}" # loop_control: # loop_var: host_node # when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) -# failed_when: not __ibmcloud_lb_pool_members_nwas_ers1.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_nwas_ers1.stderr +# failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers1.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers1.stderr # Secondary # - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP NetWeaver ERS - Dispatcher sapdp process - Member 2 (Failover/Secondary) -# register: __ibmcloud_lb_pool_members_nwas_ers2 +# no_log: "{{ __sap_vm_provision_no_log }}" +# register: __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers2 # ibm.cloudcollection.ibm_is_lb_pool_member: # lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}" -# pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-dp'))[0].id }}" -# target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" +# pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-dp'))[0].id }}" +# target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" # port: "{{ ('32' + sap_system_nwas_abap_ers_instance_nr) | int }}" # weight: 1 +# ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" # loop: "{{ (groups['nwas_ascs'] | default([]) ) }}" # loop_control: # loop_var: host_node # when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) -# failed_when: not __ibmcloud_lb_pool_members_nwas_ers2.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_nwas_ers2.stderr +# failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers2.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers2.stderr # Primary # - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP NetWeaver ERS - Message Server sapms process - Member 1 -# register: __ibmcloud_lb_pool_members_nwas_ers3 +# no_log: "{{ __sap_vm_provision_no_log }}" +# register: __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers3 # ibm.cloudcollection.ibm_is_lb_pool_member: # lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}" -# pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-ms'))[0].id }}" -# target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" +# pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-ms'))[0].id }}" +# target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" # port: "{{ ('36' + sap_system_nwas_abap_ers_instance_nr) | int }}" # weight: 100 +# ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" # loop: "{{ (groups['nwas_ers'] | default([]) ) }}" # loop_control: # loop_var: host_node # when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) -# failed_when: not __ibmcloud_lb_pool_members_nwas_ers3.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_nwas_ers3.stderr +# failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers3.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers3.stderr # Secondary # - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP NetWeaver ERS - Message Server sapms process - Member 2 (Failover/Secondary) -# register: __ibmcloud_lb_pool_members_nwas_ers4 +# no_log: "{{ __sap_vm_provision_no_log }}" +# register: __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers4 # ibm.cloudcollection.ibm_is_lb_pool_member: # lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}" -# pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-ms'))[0].id }}" -# target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" +# pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-ms'))[0].id }}" +# target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" # port: "{{ ('36' + sap_system_nwas_abap_ers_instance_nr) | int }}" # weight: 1 +# ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" # loop: "{{ (groups['nwas_ascs'] | default([]) ) }}" # loop_control: # loop_var: host_node # when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) -# failed_when: not __ibmcloud_lb_pool_members_nwas_ers4.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_nwas_ers4.stderr +# failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers4.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers4.stderr # Primary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP NetWeaver ERS - Enqueue Replication Server sapenqr process - Member 1 - register: __ibmcloud_lb_pool_members_nwas_ers5 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers5 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-enqr'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-enqr'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('39' + sap_system_nwas_abap_ers_instance_nr) | int }}" weight: 100 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['nwas_ers'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_nwas_ers5.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_nwas_ers5.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers5.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers5.stderr # Secondary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP NetWeaver ERS - Enqueue Replication Server sapenqr process - Member 2 (Failover/Secondary) - register: __ibmcloud_lb_pool_members_nwas_ers6 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers6 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-enqr'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-enqr'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('39' + sap_system_nwas_abap_ers_instance_nr) | int }}" weight: 1 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['nwas_ascs'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_nwas_ers6.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_nwas_ers6.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers6.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers6.stderr # Primary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP NetWeaver ERS - SAP Start Service (SAPControl SOAP) HTTP sapctrl process - Member 1 - register: __ibmcloud_lb_pool_members_nwas_ers7 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers7 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-sapctrl'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-sapctrl'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('5' + sap_system_nwas_abap_ers_instance_nr + '13') | int }}" weight: 100 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['nwas_ers'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_nwas_ers7.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_nwas_ers7.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers7.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers7.stderr # Secondary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP NetWeaver ERS - SAP Start Service (SAPControl SOAP) HTTP sapctrl process - Member 2 (Failover/Secondary) - register: __ibmcloud_lb_pool_members_nwas_ers8 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers8 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-sapctrl'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-sapctrl'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('5' + sap_system_nwas_abap_ers_instance_nr + '13') | int }}" weight: 1 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['nwas_ascs'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_nwas_ers8.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_nwas_ers8.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers8.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers8.stderr # Primary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP NetWeaver ERS - SAP Start Service (SAPControl SOAP) HTTPS (Secure) sapctrls - Member 1 - register: __ibmcloud_lb_pool_members_nwas_ers9 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers9 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-sapctrls'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-sapctrls'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('5' + sap_system_nwas_abap_ers_instance_nr + '14') | int }}" weight: 100 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['nwas_ers'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_nwas_ers9.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_nwas_ers9.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers9.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers9.stderr # Secondary - name: Create IBM Cloud Load Balancer Back-end Pool Members for SAP NetWeaver ERS - SAP Start Service (SAPControl SOAP) HTTPS (Secure) sapctrls - Member 2 (Failover/Secondary) - register: __ibmcloud_lb_pool_members_nwas_ers10 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers10 ibm.cloudcollection.ibm_is_lb_pool_member: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}" - pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-sapctrls'))[0].id }}" - target_address: "{{ (ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" + pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-sapctrls'))[0].id }}" + target_address: "{{ (__sap_vm_provision_task_ibmcloud_vs_all_info.resource.instances | selectattr('name', '==', host_node))[0].primary_network_interface[0].primary_ipv4_address }}" port: "{{ ('5' + sap_system_nwas_abap_ers_instance_nr + '14') | int }}" weight: 1 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" loop: "{{ (groups['nwas_ascs'] | default([]) ) }}" loop_control: loop_var: host_node when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_pool_members_nwas_ers10.rc == 0 and not 'already exists in a pool' in __ibmcloud_lb_pool_members_nwas_ers10.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers10.rc == 0 and not 'already exists in a pool' in __sap_vm_provision_task_ibmcloud_lb_pool_members_nwas_ers10.stderr # Create IBM Cloud Load Balancer Front-end Listeners (open port for Virtual IPs) - name: Create IBM Cloud Load Balancer Front-end Listener for SAP HANA - System DB SQL - register: __ibmcloud_lb_frontend_listener_hana1 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_frontend_listener_hana1 ibm.cloudcollection.ibm_is_lb_listener: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-hana'))[0].id }}" - default_pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-sysdb-sql'))[0].id }}" + default_pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-sysdb-sql'))[0].id }}" protocol: tcp port: "{{ ('3' + sap_system_hana_db_instance_nr + '13') | int }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['hana_secondary'] is defined and (groups['hana_secondary'] | length>0)) - failed_when: not __ibmcloud_lb_frontend_listener_hana1.rc == 0 and not 'listener_duplicate_port' in __ibmcloud_lb_frontend_listener_hana1.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_frontend_listener_hana1.rc == 0 and not 'listener_duplicate_port' in __sap_vm_provision_task_ibmcloud_lb_frontend_listener_hana1.stderr - name: Create IBM Cloud Load Balancer Front-end Listener for SAP HANA - MDC Tenant 1 SQL - register: __ibmcloud_lb_frontend_listener_hana2 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_frontend_listener_hana2 ibm.cloudcollection.ibm_is_lb_listener: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-hana'))[0].id }}" - default_pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-mdc1-sql'))[0].id }}" + default_pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-mdc1-sql'))[0].id }}" protocol: tcp port: "{{ ('3' + sap_system_hana_db_instance_nr + '15') | int }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['hana_secondary'] is defined and (groups['hana_secondary'] | length>0)) - failed_when: not __ibmcloud_lb_frontend_listener_hana2.rc == 0 and not 'listener_duplicate_port' in __ibmcloud_lb_frontend_listener_hana2.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_frontend_listener_hana2.rc == 0 and not 'listener_duplicate_port' in __sap_vm_provision_task_ibmcloud_lb_frontend_listener_hana2.stderr - name: Create IBM Cloud Load Balancer Front-end Listener for SAP HANA - startsrv HTTP - register: __ibmcloud_lb_frontend_listener_hana3 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_frontend_listener_hana3 ibm.cloudcollection.ibm_is_lb_listener: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-hana'))[0].id }}" - default_pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-startsrv-http'))[0].id }}" + default_pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-startsrv-http'))[0].id }}" protocol: tcp port: "{{ ('5' + sap_system_hana_db_instance_nr + '13') | int }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['hana_secondary'] is defined and (groups['hana_secondary'] | length>0)) - failed_when: not __ibmcloud_lb_frontend_listener_hana3.rc == 0 and not 'listener_duplicate_port' in __ibmcloud_lb_frontend_listener_hana3.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_frontend_listener_hana3.rc == 0 and not 'listener_duplicate_port' in __sap_vm_provision_task_ibmcloud_lb_frontend_listener_hana3.stderr - name: Create IBM Cloud Load Balancer Front-end Listener for SAP HANA - startsrv HTTPS - register: __ibmcloud_lb_frontend_listener_hana4 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_frontend_listener_hana4 ibm.cloudcollection.ibm_is_lb_listener: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-hana'))[0].id }}" - default_pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-startsrv-https'))[0].id }}" + default_pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-hana-pool-startsrv-https'))[0].id }}" protocol: tcp port: "{{ ('5' + sap_system_hana_db_instance_nr + '14') | int }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['hana_secondary'] is defined and (groups['hana_secondary'] | length>0)) - failed_when: not __ibmcloud_lb_frontend_listener_hana4.rc == 0 and not 'listener_duplicate_port' in __ibmcloud_lb_frontend_listener_hana4.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_frontend_listener_hana4.rc == 0 and not 'listener_duplicate_port' in __sap_vm_provision_task_ibmcloud_lb_frontend_listener_hana4.stderr - name: Create IBM Cloud Load Balancer Front-end Listener for SAP AnyDB - IBM Db2 Communication Port - register: __ibmcloud_lb_frontend_listener_anydb1 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_frontend_listener_anydb1 ibm.cloudcollection.ibm_is_lb_listener: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-anydb'))[0].id }}" - default_pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-anydb-pool-ibmdb2'))[0].id }}" + default_pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-anydb-pool-ibmdb2'))[0].id }}" protocol: tcp port: 5912 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['anydb_secondary'] is defined and (groups['anydb_secondary'] | length>0)) - failed_when: not __ibmcloud_lb_frontend_listener_anydb1.rc == 0 and not 'listener_duplicate_port' in __ibmcloud_lb_frontend_listener_anydb1.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_frontend_listener_anydb1.rc == 0 and not 'listener_duplicate_port' in __sap_vm_provision_task_ibmcloud_lb_frontend_listener_anydb1.stderr - name: Create IBM Cloud Load Balancer Front-end Listener for SAP NetWeaver ASCS - Dispatcher sapdp process - register: __ibmcloud_lb_frontend_listener_ascs1 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ascs1 ibm.cloudcollection.ibm_is_lb_listener: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}" - default_pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-dp'))[0].id }}" + default_pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-dp'))[0].id }}" protocol: tcp port: "{{ ('32' + sap_system_nwas_abap_ascs_instance_nr) | int }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_frontend_listener_ascs1.rc == 0 and not 'listener_duplicate_port' in __ibmcloud_lb_frontend_listener_ascs1.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ascs1.rc == 0 and not 'listener_duplicate_port' in __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ascs1.stderr - name: Create IBM Cloud Load Balancer Front-end Listener for SAP NetWeaver ASCS - Message Server sapms process - register: __ibmcloud_lb_frontend_listener_ascs2 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ascs2 ibm.cloudcollection.ibm_is_lb_listener: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}" - default_pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-ms'))[0].id }}" + default_pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-ms'))[0].id }}" protocol: tcp port: "{{ ('36' + sap_system_nwas_abap_ascs_instance_nr) | int }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_frontend_listener_ascs2.rc == 0 and not 'listener_duplicate_port' in __ibmcloud_lb_frontend_listener_ascs2.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ascs2.rc == 0 and not 'listener_duplicate_port' in __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ascs2.stderr - name: Create IBM Cloud Load Balancer Front-end Listener for SAP NetWeaver ASCS - Enqueue Server sapenq process - register: __ibmcloud_lb_frontend_listener_ascs3 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ascs3 ibm.cloudcollection.ibm_is_lb_listener: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}" - default_pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-enq'))[0].id }}" + default_pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-enq'))[0].id }}" protocol: tcp port: "{{ ('39' + sap_system_nwas_abap_ascs_instance_nr) | int }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_frontend_listener_ascs3.rc == 0 and not 'listener_duplicate_port' in __ibmcloud_lb_frontend_listener_ascs3.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ascs3.rc == 0 and not 'listener_duplicate_port' in __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ascs3.stderr - name: Create IBM Cloud Load Balancer Front-end Listener for SAP NetWeaver ASCS - SAP Start Service (SAPControl SOAP) HTTP sapctrl process - register: __ibmcloud_lb_frontend_listener_ascs4 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ascs4 ibm.cloudcollection.ibm_is_lb_listener: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}" - default_pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-sapctrl'))[0].id }}" + default_pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-sapctrl'))[0].id }}" protocol: tcp port: "{{ ('5' + sap_system_nwas_abap_ascs_instance_nr + '13') | int }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_frontend_listener_ascs4.rc == 0 and not 'listener_duplicate_port' in __ibmcloud_lb_frontend_listener_ascs4.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ascs4.rc == 0 and not 'listener_duplicate_port' in __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ascs4.stderr - name: Create IBM Cloud Load Balancer Front-end Listener for SAP NetWeaver ASCS - SAP Start Service (SAPControl SOAP) HTTPS (Secure) sapctrls - register: __ibmcloud_lb_frontend_listener_ascs5 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ascs5 ibm.cloudcollection.ibm_is_lb_listener: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}" - default_pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-sapctrls'))[0].id }}" + default_pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-sapctrls'))[0].id }}" protocol: tcp port: "{{ ('5' + sap_system_nwas_abap_ascs_instance_nr + '14') | int }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_frontend_listener_ascs5.rc == 0 and not 'listener_duplicate_port' in __ibmcloud_lb_frontend_listener_ascs5.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ascs5.rc == 0 and not 'listener_duplicate_port' in __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ascs5.stderr # - name: Create IBM Cloud Load Balancer Front-end Listener for SAP NetWeaver ERS - Dispatcher sapdp process -# register: __ibmcloud_lb_frontend_listener_ers1 -# ibm.cloudcollection.ibm_is_lb_listener: -# lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}" -# default_pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-dp'))[0].id }}" -# protocol: tcp -# port: "{{ ('32' + sap_system_nwas_abap_ers_instance_nr) | int }}" +# no_log: "{{ __sap_vm_provision_no_log }}" +# register: __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ers1 +# ibm.cloudcollection.ibm_is_lb_listener: +# lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}" +# default_pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-dp'))[0].id }}" +# protocol: tcp +# port: "{{ ('32' + sap_system_nwas_abap_ers_instance_nr) | int }}" +# ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" # when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) -# failed_when: not __ibmcloud_lb_frontend_listener_ers1.rc == 0 and not 'listener_duplicate_port' in __ibmcloud_lb_frontend_listener_ers1.stderr +# failed_when: not __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ers1.rc == 0 and not 'listener_duplicate_port' in __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ers1.stderr # - name: Create IBM Cloud Load Balancer Front-end Listener for SAP NetWeaver ERS - Message Server sapms process -# register: __ibmcloud_lb_frontend_listener_ers2 -# ibm.cloudcollection.ibm_is_lb_listener: -# lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}" -# default_pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-ms'))[0].id }}" -# protocol: tcp -# port: "{{ ('36' + sap_system_nwas_abap_ers_instance_nr) | int }}" +# no_log: "{{ __sap_vm_provision_no_log }}" +# register: __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ers2 +# ibm.cloudcollection.ibm_is_lb_listener: +# lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}" +# default_pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-ms'))[0].id }}" +# protocol: tcp +# port: "{{ ('36' + sap_system_nwas_abap_ers_instance_nr) | int }}" +# ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" # when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) -# failed_when: not __ibmcloud_lb_frontend_listener_ers2.rc == 0 and not 'listener_duplicate_port' in __ibmcloud_lb_frontend_listener_ers2.stderr +# failed_when: not __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ers2.rc == 0 and not 'listener_duplicate_port' in __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ers2.stderr - name: Create IBM Cloud Load Balancer Front-end Listener for SAP NetWeaver ERS - Enqueue Replication Server sapenqr process - register: __ibmcloud_lb_frontend_listener_ers3 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ers3 ibm.cloudcollection.ibm_is_lb_listener: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}" - default_pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-enqr'))[0].id }}" + default_pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-enqr'))[0].id }}" protocol: tcp port: "{{ ('39' + sap_system_nwas_abap_ers_instance_nr) | int }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_frontend_listener_ers3.rc == 0 and not 'listener_duplicate_port' in __ibmcloud_lb_frontend_listener_ers3.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ers3.rc == 0 and not 'listener_duplicate_port' in __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ers3.stderr - name: Create IBM Cloud Load Balancer Front-end Listener for SAP NetWeaver ERS - SAP Start Service (SAPControl SOAP) HTTP sapctrl process - register: __ibmcloud_lb_frontend_listener_ers4 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ers4 ibm.cloudcollection.ibm_is_lb_listener: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}" - default_pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-sapctrl'))[0].id }}" + default_pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-sapctrl'))[0].id }}" protocol: tcp port: "{{ ('5' + sap_system_nwas_abap_ers_instance_nr + '13') | int }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_frontend_listener_ers4.rc == 0 and not 'listener_duplicate_port' in __ibmcloud_lb_frontend_listener_ers4.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ers4.rc == 0 and not 'listener_duplicate_port' in __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ers4.stderr - name: Create IBM Cloud Load Balancer Front-end Listener for SAP NetWeaver ERS - SAP Start Service (SAPControl SOAP) HTTPS (Secure) sapctrls - register: __ibmcloud_lb_frontend_listener_ers5 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ers5 ibm.cloudcollection.ibm_is_lb_listener: lb: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}" - default_pool: "{{ (__ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-sapctrls'))[0].id }}" + default_pool: "{{ (__sap_vm_provision_task_ibmcloud_lb_pools.results | json_query('[*].resource.pools') | flatten | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-sapctrls'))[0].id }}" protocol: tcp port: "{{ ('5' + sap_system_nwas_abap_ers_instance_nr + '14') | int }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - failed_when: not __ibmcloud_lb_frontend_listener_ers5.rc == 0 and not 'listener_duplicate_port' in __ibmcloud_lb_frontend_listener_ers5.stderr + failed_when: not __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ers5.rc == 0 and not 'listener_duplicate_port' in __sap_vm_provision_task_ibmcloud_lb_frontend_listener_ers5.stderr # Set DNS A Record for Virtual IP (use the first of the IBM Cloud Load Balancer instance assigned Private IPs in the VPC Subnet Range) - name: IBM Cloud Private DNS Record for SAP HANA HA Virtual Hostname - register: register_ibmcloud_pdns_record_ha_hana + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_pdns_record_ha_hana ibm.cloudcollection.ibm_dns_resource_record: - instance_id: "{{ register_ibmcloud_pdns_service_instance.resource.guid }}" - zone_id: "{{ (register_ibmcloud_pdns.resource.dns_zones | selectattr('name', '==', sap_vm_provision_dns_root_domain) | first).zone_id }}" + instance_id: "{{ __sap_vm_provision_task_ibmcloud_pdns_service_instance.resource.guid }}" + zone_id: "{{ (__sap_vm_provision_task_ibmcloud_pdns.resource.dns_zones | selectattr('name', '==', sap_vm_provision_dns_root_domain) | first).zone_id }}" name: "{{ sap_swpm_db_host }}.{{ hostvars[host_node].sap_vm_provision_dns_root_domain }}" # Host FQDN rdata: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-hana'))[0].private_ips[0].address }}" # IP Address type: A ttl: 7200 - failed_when: not register_ibmcloud_pdns_record.rc == 0 and not 'The record already exists' in register_ibmcloud_pdns_record.stderr + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" + failed_when: not __sap_vm_provision_task_ibmcloud_pdns_record.rc == 0 and not 'The record already exists' in __sap_vm_provision_task_ibmcloud_pdns_record.stderr loop: "{{ (groups['hana_primary'] | default([])) }}" loop_control: loop_var: host_node @@ -954,15 +1092,17 @@ - groups["hana_secondary"] is defined and (groups["hana_secondary"]|length>0) - name: IBM Cloud Private DNS Record for SAP AnyDB HA Virtual Hostname - register: register_ibmcloud_pdns_record_ha_anydb + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_pdns_record_ha_anydb ibm.cloudcollection.ibm_dns_resource_record: - instance_id: "{{ register_ibmcloud_pdns_service_instance.resource.guid }}" - zone_id: "{{ (register_ibmcloud_pdns.resource.dns_zones | selectattr('name', '==', sap_vm_provision_dns_root_domain) | first).zone_id }}" + instance_id: "{{ __sap_vm_provision_task_ibmcloud_pdns_service_instance.resource.guid }}" + zone_id: "{{ (__sap_vm_provision_task_ibmcloud_pdns.resource.dns_zones | selectattr('name', '==', sap_vm_provision_dns_root_domain) | first).zone_id }}" name: "{{ sap_swpm_db_host }}.{{ hostvars[host_node].sap_vm_provision_dns_root_domain }}" # Host FQDN rdata: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-anydb'))[0].private_ips[0].address }}" # IP Address type: A ttl: 7200 - failed_when: not register_ibmcloud_pdns_record.rc == 0 and not 'The record already exists' in register_ibmcloud_pdns_record.stderr + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" + failed_when: not __sap_vm_provision_task_ibmcloud_pdns_record.rc == 0 and not 'The record already exists' in __sap_vm_provision_task_ibmcloud_pdns_record.stderr loop: "{{ (groups['anydb_primary'] | default([])) }}" loop_control: loop_var: host_node @@ -970,15 +1110,17 @@ - groups["anydb_secondary"] is defined and (groups["anydb_secondary"]|length>0) - name: IBM Cloud Private DNS Record for SAP NetWeaver ASCS HA Virtual Hostname - register: register_ibmcloud_pdns_record_ha_nwas_ascs + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_pdns_record_ha_nwas_ascs ibm.cloudcollection.ibm_dns_resource_record: - instance_id: "{{ register_ibmcloud_pdns_service_instance.resource.guid }}" - zone_id: "{{ (register_ibmcloud_pdns.resource.dns_zones | selectattr('name', '==', sap_vm_provision_dns_root_domain) | first).zone_id }}" + instance_id: "{{ __sap_vm_provision_task_ibmcloud_pdns_service_instance.resource.guid }}" + zone_id: "{{ (__sap_vm_provision_task_ibmcloud_pdns.resource.dns_zones | selectattr('name', '==', sap_vm_provision_dns_root_domain) | first).zone_id }}" name: "{{ sap_swpm_ascs_instance_hostname }}.{{ hostvars[host_node].sap_vm_provision_dns_root_domain }}" # Host FQDN rdata: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].private_ips[0].address }}" # IP Address type: A ttl: 7200 - failed_when: not register_ibmcloud_pdns_record.rc == 0 and not 'The record already exists' in register_ibmcloud_pdns_record.stderr + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" + failed_when: not __sap_vm_provision_task_ibmcloud_pdns_record.rc == 0 and not 'The record already exists' in __sap_vm_provision_task_ibmcloud_pdns_record.stderr loop: "{{ (groups['nwas_ascs'] | default([])) }}" loop_control: loop_var: host_node @@ -986,15 +1128,17 @@ - groups["nwas_ers"] is defined and (groups["nwas_ers"]|length>0) - name: IBM Cloud Private DNS Record for SAP NetWeaver ERS HA Virtual Hostname - register: register_ibmcloud_pdns_record_ha_nwas_ers + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_pdns_record_ha_nwas_ers ibm.cloudcollection.ibm_dns_resource_record: - instance_id: "{{ register_ibmcloud_pdns_service_instance.resource.guid }}" - zone_id: "{{ (register_ibmcloud_pdns.resource.dns_zones | selectattr('name', '==', sap_vm_provision_dns_root_domain) | first).zone_id }}" + instance_id: "{{ __sap_vm_provision_task_ibmcloud_pdns_service_instance.resource.guid }}" + zone_id: "{{ (__sap_vm_provision_task_ibmcloud_pdns.resource.dns_zones | selectattr('name', '==', sap_vm_provision_dns_root_domain) | first).zone_id }}" name: "{{ sap_swpm_ers_instance_hostname }}.{{ hostvars[host_node].sap_vm_provision_dns_root_domain }}" # Host FQDN rdata: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].private_ips[0].address }}" # IP Address type: A ttl: 7200 - failed_when: not register_ibmcloud_pdns_record.rc == 0 and not 'The record already exists' in register_ibmcloud_pdns_record.stderr + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" + failed_when: not __sap_vm_provision_task_ibmcloud_pdns_record.rc == 0 and not 'The record already exists' in __sap_vm_provision_task_ibmcloud_pdns_record.stderr loop: "{{ (groups['nwas_ers'] | default([])) }}" loop_control: loop_var: host_node diff --git a/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_vs/post_deployment_execute.yml b/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_vs/post_deployment_execute.yml index 93afaa0..e665532 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_vs/post_deployment_execute.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/ibmcloud_vs/post_deployment_execute.yml @@ -13,8 +13,8 @@ delegate_to: localhost run_once: true environment: - IC_API_KEY: "{{ sap_vm_provision_ibmcloud_api_key }}" # For legacy Ansible Collection - IBMCLOUD_API_KEY: "{{ sap_vm_provision_ibmcloud_api_key }}" # For IBM Cloud CLI quiet login + # IC_API_KEY: "{{ sap_vm_provision_ibmcloud_api_key }}" # For legacy Ansible Collection + # IBMCLOUD_API_KEY: "{{ sap_vm_provision_ibmcloud_api_key }}" # For IBM Cloud CLI quiet login IC_REGION: "{{ sap_vm_provision_ibmcloud_region }}" when: - sap_ha_pacemaker_cluster_ibmcloud_region is defined @@ -54,7 +54,7 @@ # Workaround for bug which populates region and ibmcloud_api_key as TF arguments for ibm_is_lbs_info Ansible Module in legacy Ansible Collection - name: IBM Cloud CLI execution to list Load Balancer/s info - register: ibmcloud_lbs_all_info_shell + register: __sap_vm_provision_task_ibmcloud_lb_all_info_shell ansible.builtin.shell: | ibmcloud config --quiet --check-version false && ibmcloud login -g {{ sap_vm_provision_ibmcloud_resource_group_name }} -r {{ sap_vm_provision_ibmcloud_region }} --quiet #ibmcloud plugin install infrastructure-service -f --quiet @@ -62,7 +62,7 @@ - name: Set fact for IBM Cloud Load Balancer/s info ansible.builtin.set_fact: - ibmcloud_lbs_all_info: "{{ ibmcloud_lbs_all_info_shell.stdout | split('Space:') | last | trim | from_json }}" + ibmcloud_lbs_all_info: "{{ __sap_vm_provision_task_ibmcloud_lb_all_info_shell.stdout | split('Space:') | last | trim | from_json }}" - name: Set fact for IBM Cloud Load Balancer Back-end Pools to target ansible.builtin.set_fact: @@ -77,9 +77,11 @@ when: "('lb-sap-ha-hana' in item.name) or ('lb-sap-ha-anydb' in item.name) or ('lb-sap-ha-nwas-ascs' in item.name) or ('lb-sap-ha-nwas-ers' in item.name)" # - name: Identify IBM Cloud Load Balancer Back-end Pools - # register: __ibmcloud_lb_pools + # no_log: "{{ __sap_vm_provision_no_log }}" + # register: __sap_vm_provision_task_ibmcloud_lb_pools # ibm.cloudcollection.ibm_is_lb_pools_info: # lb: "{{ item.id }}" + # ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" # loop: "{{ ibmcloud_lbs_all_info }}" # loop_control: # label: "{{ item.name }}" @@ -87,7 +89,8 @@ - name: Update IBM Cloud Load Balancer Back-end Pool Health Check Port to Linux Pacemaker controlled listening port for SAP HANA - System DB SQL - register: __ibmcloud_lb_pool_hana1 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_hana1 ibm.cloudcollection.ibm_is_lb_pool: id: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-hana'))[0].id }}/{{ ((ibmcloud_lbs_all_info | json_query('[*].pools') | flatten) | selectattr('name', '==', 'lb-sap-ha-hana-pool-sysdb-sql') | first).id }}" name: lb-sap-ha-hana-pool-sysdb-sql @@ -99,10 +102,12 @@ health_timeout: 10 health_type: tcp health_monitor_port: "{{ ibmcloud_lb_pool_healthcheck_hana }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['hana_secondary'] is defined and (groups['hana_secondary'] | length>0)) - name: Update IBM Cloud Load Balancer Back-end Pool Health Check Port to Linux Pacemaker controlled listening port for SAP HANA - MDC Tenant 1 SQL - register: __ibmcloud_lb_pool_hana2 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_hana2 ibm.cloudcollection.ibm_is_lb_pool: id: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-hana'))[0].id }}/{{ ((ibmcloud_lbs_all_info | json_query('[*].pools') | flatten) | selectattr('name', '==', 'lb-sap-ha-hana-pool-mdc1-sql') | first).id }}" name: lb-sap-ha-hana-pool-mdc1-sql @@ -114,10 +119,12 @@ health_timeout: 10 health_type: tcp health_monitor_port: "{{ ibmcloud_lb_pool_healthcheck_hana }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['hana_secondary'] is defined and (groups['hana_secondary'] | length>0)) - name: Update IBM Cloud Load Balancer Back-end Pool Health Check Port to Linux Pacemaker controlled listening port for SAP HANA - startsrv HTTP - register: __ibmcloud_lb_pool_hana3 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_hana3 ibm.cloudcollection.ibm_is_lb_pool: id: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-hana'))[0].id }}/{{ ((ibmcloud_lbs_all_info | json_query('[*].pools') | flatten) | selectattr('name', '==', 'lb-sap-ha-hana-pool-startsrv-http') | first).id }}" name: lb-sap-ha-hana-pool-startsrv-http @@ -129,10 +136,12 @@ health_timeout: 10 health_type: tcp health_monitor_port: "{{ ibmcloud_lb_pool_healthcheck_hana }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['hana_secondary'] is defined and (groups['hana_secondary'] | length>0)) - name: Update IBM Cloud Load Balancer Back-end Pool Health Check Port to Linux Pacemaker controlled listening port for SAP HANA - startsrv HTTPS - register: __ibmcloud_lb_pool_hana4 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_hana4 ibm.cloudcollection.ibm_is_lb_pool: id: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-hana'))[0].id }}/{{ ((ibmcloud_lbs_all_info | json_query('[*].pools') | flatten) | selectattr('name', '==', 'lb-sap-ha-hana-pool-startsrv-https') | first).id }}" name: lb-sap-ha-hana-pool-startsrv-https @@ -144,9 +153,11 @@ health_timeout: 10 health_type: tcp health_monitor_port: "{{ ibmcloud_lb_pool_healthcheck_hana }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['hana_secondary'] is defined and (groups['hana_secondary'] | length>0)) - name: Update IBM Cloud Load Balancer Back-end Pool Health Check Port to Linux Pacemaker controlled listening port for SAP AnyDB - IBM Db2 Communication Port + no_log: "{{ __sap_vm_provision_no_log }}" ibm.cloudcollection.ibm_is_lb_pool: id: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-anydb'))[0].id }}/{{ ((ibmcloud_lbs_all_info | json_query('[*].pools') | flatten) | selectattr('name', '==', 'lb-sap-ha-anydb-pool-ibmdb2') | first).id }}" name: lb-sap-ha-anydb-pool-ibmdb2 @@ -158,10 +169,12 @@ health_timeout: 10 health_type: tcp health_monitor_port: 62700 + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['anydb_secondary'] is defined and (groups['anydb_secondary'] | length>0)) - name: Update IBM Cloud Load Balancer Back-end Pool Health Check Port to Linux Pacemaker controlled listening port for SAP NetWeaver ASCS - Dispatcher sapdp process - register: __ibmcloud_lb_pool_nwas_ascs1 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ascs1 ibm.cloudcollection.ibm_is_lb_pool: id: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}/{{ ((ibmcloud_lbs_all_info | json_query('[*].pools') | flatten) | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-dp') | first).id }}" name: lb-sap-ha-nwas-ascs-pool-dp @@ -173,10 +186,12 @@ health_timeout: 10 health_type: tcp health_monitor_port: "{{ ibmcloud_lb_pool_healthcheck_nwas_ascs }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - name: Update IBM Cloud Load Balancer Back-end Pool Health Check Port to Linux Pacemaker controlled listening port for SAP NetWeaver ASCS - Message Server sapms process - register: __ibmcloud_lb_pool_nwas_ascs2 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ascs2 ibm.cloudcollection.ibm_is_lb_pool: id: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}/{{ ((ibmcloud_lbs_all_info | json_query('[*].pools') | flatten) | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-ms') | first).id }}" name: lb-sap-ha-nwas-ascs-pool-ms @@ -188,10 +203,12 @@ health_timeout: 10 health_type: tcp health_monitor_port: "{{ ibmcloud_lb_pool_healthcheck_nwas_ascs }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - name: Update IBM Cloud Load Balancer Back-end Pool Health Check Port to Linux Pacemaker controlled listening port for SAP NetWeaver ASCS - Enqueue Server sapenq process - register: __ibmcloud_lb_pool_nwas_ascs3 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ascs3 ibm.cloudcollection.ibm_is_lb_pool: id: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}/{{ ((ibmcloud_lbs_all_info | json_query('[*].pools') | flatten) | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-enq') | first).id }}" name: lb-sap-ha-nwas-ascs-pool-enq @@ -203,10 +220,12 @@ health_timeout: 10 health_type: tcp health_monitor_port: "{{ ibmcloud_lb_pool_healthcheck_nwas_ascs }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - name: Update IBM Cloud Load Balancer Back-end Pool Health Check Port to Linux Pacemaker controlled listening port for SAP NetWeaver ASCS - SAP Start Service (SAPControl SOAP) HTTP sapctrl process - register: __ibmcloud_lb_pool_nwas_ascs4 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ascs4 ibm.cloudcollection.ibm_is_lb_pool: id: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}/{{ ((ibmcloud_lbs_all_info | json_query('[*].pools') | flatten) | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-sapctrl') | first).id }}" name: lb-sap-ha-nwas-ascs-pool-sapctrl @@ -218,10 +237,12 @@ health_timeout: 10 health_type: tcp health_monitor_port: "{{ ibmcloud_lb_pool_healthcheck_nwas_ascs }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - name: Update IBM Cloud Load Balancer Back-end Pool Health Check Port to Linux Pacemaker controlled listening port for SAP NetWeaver ASCS - SAP Start Service (SAPControl SOAP) HTTPS (Secure) sapctrls - register: __ibmcloud_lb_pool_nwas_ascs5 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ascs5 ibm.cloudcollection.ibm_is_lb_pool: id: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ascs'))[0].id }}/{{ ((ibmcloud_lbs_all_info | json_query('[*].pools') | flatten) | selectattr('name', '==', 'lb-sap-ha-nwas-ascs-pool-sapctrls') | first).id }}" name: lb-sap-ha-nwas-ascs-pool-sapctrls @@ -233,10 +254,12 @@ health_timeout: 10 health_type: tcp health_monitor_port: "{{ ibmcloud_lb_pool_healthcheck_nwas_ascs }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) # - name: Update IBM Cloud Load Balancer Back-end Pool Health Check Port to Linux Pacemaker controlled listening port for SAP NetWeaver ERS - Dispatcher sapdp process - # register: __ibmcloud_lb_pool_nwas_ers1 + # no_log: "{{ __sap_vm_provision_no_log }}" + # register: __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ers1 # ibm.cloudcollection.ibm_is_lb_pool: # id: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}/{{ ((ibmcloud_lbs_all_info | json_query('[*].pools') | flatten) | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-dp') | first).id }}" # name: lb-sap-ha-nwas-ers-pool-dp @@ -248,10 +271,12 @@ # health_timeout: 10 # health_type: tcp # health_monitor_port: "{{ ibmcloud_lb_pool_healthcheck_nwas_ers }}" + # ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" # when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) # - name: Update IBM Cloud Load Balancer Back-end Pool Health Check Port to Linux Pacemaker controlled listening port for SAP NetWeaver ERS - Message Server sapms process - # register: __ibmcloud_lb_pool_nwas_ers2 + # no_log: "{{ __sap_vm_provision_no_log }}" + # register: __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ers2 # ibm.cloudcollection.ibm_is_lb_pool: # id: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}/{{ ((ibmcloud_lbs_all_info | json_query('[*].pools') | flatten) | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-ms') | first).id }}" # name: lb-sap-ha-nwas-ers-pool-ms @@ -263,10 +288,12 @@ # health_timeout: 10 # health_type: tcp # health_monitor_port: "{{ ibmcloud_lb_pool_healthcheck_nwas_ers }}" + # ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" # when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - name: Update IBM Cloud Load Balancer Back-end Pool Health Check Port to Linux Pacemaker controlled listening port for SAP NetWeaver ERS - Enqueue Replication Server sapenqr process - register: __ibmcloud_lb_pool_nwas_ers3 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ers3 ibm.cloudcollection.ibm_is_lb_pool: id: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}/{{ ((ibmcloud_lbs_all_info | json_query('[*].pools') | flatten) | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-enqr') | first).id }}" name: lb-sap-ha-nwas-ers-pool-enqr @@ -278,10 +305,12 @@ health_timeout: 10 health_type: tcp health_monitor_port: "{{ ibmcloud_lb_pool_healthcheck_nwas_ers }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - name: Update IBM Cloud Load Balancer Back-end Pool Health Check Port to Linux Pacemaker controlled listening port for SAP NetWeaver ERS - SAP Start Service (SAPControl SOAP) HTTP sapctrl process - register: __ibmcloud_lb_pool_nwas_ers4 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ers4 ibm.cloudcollection.ibm_is_lb_pool: id: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}/{{ ((ibmcloud_lbs_all_info | json_query('[*].pools') | flatten) | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-sapctrl') | first).id }}" name: lb-sap-ha-nwas-ers-pool-sapctrl @@ -293,10 +322,12 @@ health_timeout: 10 health_type: tcp health_monitor_port: "{{ ibmcloud_lb_pool_healthcheck_nwas_ers }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) - name: Update IBM Cloud Load Balancer Back-end Pool Health Check Port to Linux Pacemaker controlled listening port for SAP NetWeaver ERS - SAP Start Service (SAPControl SOAP) HTTPS (Secure) sapctrls - register: __ibmcloud_lb_pool_nwas_ers5 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmcloud_lb_pool_nwas_ers5 ibm.cloudcollection.ibm_is_lb_pool: id: "{{ (ibmcloud_lbs_all_info | selectattr('name', '==', 'lb-sap-ha-nwas-ers'))[0].id }}/{{ ((ibmcloud_lbs_all_info | json_query('[*].pools') | flatten) | selectattr('name', '==', 'lb-sap-ha-nwas-ers-pool-sapctrls') | first).id }}" name: lb-sap-ha-nwas-ers-pool-sapctrls @@ -308,4 +339,5 @@ health_timeout: 10 health_type: tcp health_monitor_port: "{{ ibmcloud_lb_pool_healthcheck_nwas_ers }}" + ibmcloud_api_key: "{{ sap_vm_provision_ibmcloud_api_key }}" when: (groups['nwas_ers'] is defined and (groups['nwas_ers'] | length>0)) diff --git a/roles/sap_vm_provision/tasks/platform_ansible/ibmpowervm_vm/execute_main.yml b/roles/sap_vm_provision/tasks/platform_ansible/ibmpowervm_vm/execute_main.yml index f878904..023dc59 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/ibmpowervm_vm/execute_main.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/ibmpowervm_vm/execute_main.yml @@ -1,82 +1,126 @@ --- -# Method 1 for auth, set fact and reuse with validate_certs on each Ansible Task -- name: Openstack Authentication - Method 1 - ansible.builtin.set_fact: - openstack_auth: - auth_url: "{{ sap_vm_provision_ibmpowervm_vc_auth_endpoint }}" - username: "{{ sap_vm_provision_ibmpowervm_vc_user }}" - password: "{{ sap_vm_provision_ibmpowervm_vc_user_password }}" - project_name: "{{ sap_vm_provision_ibmpowervm_vc_project_name }}" - project_domain_name: "default" # If blank will cause error "Expecting to find domain in project" - user_domain_name: "default" # If blank will cause error "Expecting to find domain in user" - -# Method 2 for auth, obtain token and subsequently set each task with environment e.g. OS_TOKEN: "{{ openstack_session.auth_token }}" -# Use if requiring direct API call or CLI commands -# - name: Openstack Authentication - Method 2 -# openstack.cloud.auth: -# auth: -# auth_url: "{{ sap_vm_provision_ibmpowervm_vc_auth_endpoint }}" -# username: "{{ sap_vm_provision_ibmpowervm_vc_user }}" -# password: "{{ sap_vm_provision_ibmpowervm_vc_user_password }}" -# project_name: "{{ sap_vm_provision_ibmpowervm_vc_project_name }}" -# project_domain_name: "default" # If blank will cause error "Expecting to find domain in project" -# user_domain_name: "default" # If blank will cause error "Expecting to find domain in user" -# interface: internal # internal, public, admin -# validate_certs: false # Allow Self-Signed Certificate -# wait: true -# when: openstack_auth is undefined or not openstack_auth -# register: openstack_session - -- name: Set fact to hold loop variables from include_tasks - ansible.builtin.set_fact: - register_provisioned_host_all: [] - -- name: Create IBM PowerVM SSH Key Pair - openstack.cloud.keypair: - auth: "{{ openstack_auth }}" - validate_certs: false # Allow Self-Signed Certificate - state: present - name: "{{ sap_vm_provision_ibmpowervm_key_pair_name_ssh_host_public_key }}" - public_key: "{{ lookup('ansible.builtin.file', sap_vm_provision_ssh_host_public_key_file_path ) }}" - throttle: 1 - -- name: Provision hosts to IBM PowerVM - register: register_provisioned_hosts - ansible.builtin.include_tasks: - file: "{{ 'platform_' + sap_vm_provision_iac_type }}/{{ sap_vm_provision_iac_platform }}/execute_provision.yml" - vars: - openstack_auth_delegate: "{{ openstack_auth }}" - -- name: Add hosts provisioned to the Ansible Inventory - register: register_add_hosts - ansible.builtin.add_host: - name: "{{ add_item[0].host_node }}" - groups: "{{ add_item[0].sap_system_type + '_' if (add_item[0].sap_system_type != '') }}{{ add_item[0].sap_host_type }}" - ansible_host: "{{ add_item[0].access_ipv4 }}" - ansible_user: "root" - ansible_ssh_private_key_file: "{{ sap_vm_provision_ssh_host_private_key_file_path }}" - ansible_ssh_common_args: -o ConnectTimeout=180 -o ControlMaster=auto -o ControlPersist=3600s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ForwardX11=no - loop: "{{ ansible_play_hosts | map('extract', hostvars, 'register_provisioned_host_all') }}" - loop_control: - label: "{{ add_item[0].host_node }}" - loop_var: add_item +- name: Ansible Task block for looped provisioning of IBM PowerVM Virtual Machines + any_errors_fatal: true + # Using environment, no_log is ineffective and log will show 'EXEC /bin/sh -c 'ENV_VAR=value python3 /AnsiballZ_ansible_module_name.py && sleep 0' + # Therefore do not use environment for secrets, use only for non-sensitive values as this will reduce Ansible Task parameters. + # environment: + block: + + # Method 1 for auth, set fact and reuse with validate_certs on each Ansible Task + - name: Openstack Authentication - Method 1 + no_log: "{{ __sap_vm_provision_no_log }}" + ansible.builtin.set_fact: + __sap_vm_provision_task_ibmpowervm_openstack_auth: + auth_url: "{{ sap_vm_provision_ibmpowervm_vc_auth_endpoint }}" + username: "{{ sap_vm_provision_ibmpowervm_vc_user }}" + password: "{{ sap_vm_provision_ibmpowervm_vc_user_password }}" + project_name: "{{ sap_vm_provision_ibmpowervm_vc_project_name }}" + project_domain_name: "default" # If blank will cause error "Expecting to find domain in project" + user_domain_name: "default" # If blank will cause error "Expecting to find domain in user" + + # Method 2 for auth, obtain token and subsequently set each task with environment e.g. OS_TOKEN: "{{ __sap_vm_provision_task_ibmpowervm_openstack_session.auth_token }}" + # Use if requiring direct API call or CLI commands + # - name: Openstack Authentication - Method 2 + # no_log: "{{ __sap_vm_provision_no_log }}" + # register: __sap_vm_provision_task_ibmpowervm_openstack_session + # openstack.cloud.auth: + # auth: + # auth_url: "{{ sap_vm_provision_ibmpowervm_vc_auth_endpoint }}" + # username: "{{ sap_vm_provision_ibmpowervm_vc_user }}" + # password: "{{ sap_vm_provision_ibmpowervm_vc_user_password }}" + # project_name: "{{ sap_vm_provision_ibmpowervm_vc_project_name }}" + # project_domain_name: "default" # If blank will cause error "Expecting to find domain in project" + # user_domain_name: "default" # If blank will cause error "Expecting to find domain in user" + # interface: internal # internal, public, admin + # validate_certs: false # Allow Self-Signed Certificate + # wait: true + # when: __sap_vm_provision_task_ibmpowervm_openstack_auth is undefined or not __sap_vm_provision_task_ibmpowervm_openstack_auth + + - name: Set fact to hold loop variables from include_tasks + ansible.builtin.set_fact: + register_provisioned_host_all: [] + + - name: Create IBM PowerVM SSH Key Pair + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ibmpowervm_ssh_public_key + openstack.cloud.keypair: + state: present + name: "{{ sap_vm_provision_ibmpowervm_key_pair_name_ssh_host_public_key }}" + public_key: "{{ lookup('ansible.builtin.file', sap_vm_provision_ssh_host_public_key_file_path ) }}" + validate_certs: false # Allow Self-Signed Certificate + auth: "{{ __sap_vm_provision_task_ibmpowervm_openstack_auth }}" + throttle: 1 + + - name: Provision hosts to IBM PowerVM + register: __sap_vm_provision_task_provision_host_all_run + ansible.builtin.include_tasks: + file: "{{ 'platform_' + sap_vm_provision_iac_type }}/{{ sap_vm_provision_iac_platform }}/execute_provision.yml" + vars: + __sap_vm_provision_task_ibmpowervm_openstack_auth_delegate: "{{ __sap_vm_provision_task_ibmpowervm_openstack_auth }}" + + - name: Add hosts provisioned to the Ansible Inventory + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_all_add + ansible.builtin.add_host: + name: "{{ add_item[0].host_node }}" + groups: "{{ add_item[0].sap_system_type + '_' if (add_item[0].sap_system_type != '') }}{{ add_item[0].sap_host_type }}" + ansible_host: "{{ add_item[0].access_ipv4 }}" + ansible_user: "root" + ansible_ssh_private_key_file: "{{ sap_vm_provision_ssh_host_private_key_file_path }}" + ansible_ssh_common_args: -o ConnectTimeout=180 -o ControlMaster=auto -o ControlPersist=3600s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ForwardX11=no + loop: "{{ ansible_play_hosts | map('extract', hostvars, 'register_provisioned_host_all') }}" + loop_control: + label: "{{ add_item[0].host_node }}" + loop_var: add_item # Cannot override any variables from extravars input, see https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#understanding-variable-precedence # Ensure no default value exists for any prompted variable before execution of Ansible Playbook -- name: Set fact to hold all inventory hosts in all groups - ansible.builtin.set_fact: - groups_merged_list: "{{ [ [ groups['hana_primary'] | default([]) ] , [ groups['hana_secondary'] | default([]) ] , [ groups['nwas_ascs'] | default([]) ] , [ groups['nwas_ers'] | default([]) ] , [ groups['nwas_pas'] | default([]) ] , [ groups['nwas_aas'] | default([]) ] ] | flatten | select() }}" + - name: Set fact to hold all inventory hosts in all groups + ansible.builtin.set_fact: + groups_merged_list: "{{ [ [ groups['hana_primary'] | default([]) ] , [ groups['hana_secondary'] | default([]) ] , [ groups['nwas_ascs'] | default([]) ] , [ groups['nwas_ers'] | default([]) ] , [ groups['nwas_pas'] | default([]) ] , [ groups['nwas_aas'] | default([]) ] ] | flatten | select() }}" -- name: Set Ansible Vars - register: register_set_ansible_vars - ansible.builtin.include_tasks: - file: common/set_ansible_vars.yml + - name: Set Ansible Vars + register: __sap_vm_provision_task_ansible_vars_set + ansible.builtin.include_tasks: + file: common/set_ansible_vars.yml # - ansible.builtin.debug: - # var: register_add_hosts.results + # var: __sap_vm_provision_task_provision_host_all_add.results + + rescue: + # This requires no_log set on each Ansible Task, and not set on the Ansible Task Block + # This requires an Ansible Task Block containing the Ansible Tasks for calling + # Infrastructure Platform APIs (via Ansible Modules) + - name: Show errors in task outputs + ansible.builtin.fail: + msg: "{{ lookup('ansible.builtin.vars', loop_item) }}" + loop: + - __sap_vm_provision_task_ibmpowervm_ssh_public_key + - __sap_vm_provision_task_provision_host_all_run + - __sap_vm_provision_task_provision_host_single_check_exists + - __sap_vm_provision_task_ibmpowervm_os_image_info + - __sap_vm_provision_task_ibmpowervm_network + - __sap_vm_provision_task_ibmpowervm_compute_template + - __sap_vm_provision_task_provision_host_single + - __sap_vm_provision_task_provision_host_single_vnic + - __sap_vm_provision_task_ansible_facts_host_disks_info + - __sap_vm_provision_task_provision_host_single_volumes + - __sap_vm_provision_task_provision_host_single_volume_attachments + - __sap_vm_provision_task_os_rescan_scsi_bus_output + - __sap_vm_provision_task_provision_host_single_info + - __sap_vm_provision_task_provision_host_all_add + loop_control: + loop_var: loop_item + index_var: loop_item_index + label: "{{ 'Variable No. ' + (loop_item_index | string) }}" + when: + - lookup('ansible.builtin.vars', loop_item, default='') | length > 0 + - not lookup('ansible.builtin.vars', loop_item, default='') is skipped + - lookup('ansible.builtin.vars', loop_item, default='') is failed + - name: Ansible Task block to execute on target inventory hosts delegate_to: "{{ inventory_hostname }}" @@ -95,33 +139,33 @@ name: "{{ inventory_hostname_short }}" - name: Set /etc/hosts - register: register_etc_hosts_file + register: __sap_vm_provision_task_os_etc_hosts ansible.builtin.include_tasks: file: common/set_etc_hosts.yml - name: Set /etc/hosts for HA - register: register_etc_hosts_file_ha + register: __sap_vm_provision_task_os_etc_hosts_ha ansible.builtin.include_tasks: file: common/set_etc_hosts_ha.yml when: - (groups["hana_secondary"] is defined and (groups["hana_secondary"] | length>0)) or (groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0)) or (groups["anydb_secondary"] is defined and (groups["anydb_secondary"] | length>0)) - name: Set /etc/hosts for Scale-Out - register: register_etc_hosts_file_scaleout + register: __sap_vm_provision_task_os_etc_hosts_scaleout ansible.builtin.include_tasks: file: common/set_etc_hosts_scaleout.yml when: - - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_hana_scaleout_active_coordinator is defined or sap_hana_scaleout_active_worker is defined or sap_hana_scaleout_standby is defined) + - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined or sap_vm_provision_calculate_sap_hana_scaleout_active_worker is defined or sap_vm_provision_calculate_sap_hana_scaleout_standby is defined) - name: Set vars for sap_storage_setup Ansible Role - register: register_ansible_vars_storage + register: __sap_vm_provision_task_ansible_vars_storage ansible.builtin.include_tasks: file: common/set_ansible_vars_storage.yml - - name: Register Package Repositories - ansible.builtin.include_tasks: - file: common/register_os.yml - - name: Register Web Forward Proxy ansible.builtin.include_tasks: file: common/register_proxy.yml + + - name: Register Package Repositories + ansible.builtin.include_tasks: + file: common/register_os.yml diff --git a/roles/sap_vm_provision/tasks/platform_ansible/ibmpowervm_vm/execute_provision.yml b/roles/sap_vm_provision/tasks/platform_ansible/ibmpowervm_vm/execute_provision.yml index 31ba15b..9103db1 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/ibmpowervm_vm/execute_provision.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/ibmpowervm_vm/execute_provision.yml @@ -1,6 +1,11 @@ --- # The tasks in this file are executed in a loop over the defined hosts +- name: Ensure short hostname is not longer than 13 characters (see SAP Note 611361) + ansible.builtin.assert: + that: (inventory_hostname | length | int) <= (13 | int) + fail_msg: "FAIL: The length of the hostname is {{ inventory_hostname | length | int }} but must be less or equal to 13 characters!" + # NOTE: Pre-requisite to create IBM PowerVC Storage Templates (OpenStack Cinder Volume Type), which is not possible from Ansible Collection for Openstack # https://www.ibm.com/docs/en/powervc/1.4.3?topic=apis-supported-volume-type-extra-specs ### Show IBM PowerVC Storage list @@ -13,29 +18,29 @@ ansible.builtin.set_fact: scaleout_origin_host_spec: "{{ inventory_hostname | regex_replace('^(.+?)\\d*$', '\\1') }}" when: - - sap_hana_scaleout_active_coordinator is defined + - sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined - not inventory_hostname in lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan].keys() - name: Check if VM exists - register: register_check_vm_exists + register: __sap_vm_provision_task_provision_host_single_check_exists openstack.cloud.server_info: - auth: "{{ openstack_auth_delegate }}" - validate_certs: false # Allow Self-Signed Certificate name: "{{ inventory_hostname }}" + validate_certs: false # Allow Self-Signed Certificate + auth: "{{ __sap_vm_provision_task_ibmpowervm_openstack_auth_delegate }}" - name: Check OS Image available in IBM PowerVM - register: register_ibmpowervm_available_os + register: __sap_vm_provision_task_ibmpowervm_os_image_info openstack.cloud.image_info: - auth: "{{ openstack_auth_delegate }}" - validate_certs: false # Allow Self-Signed Certificate image: "{{ sap_vm_provision_ibmpowervm_vm_host_os_image }}" + validate_certs: false # Allow Self-Signed Certificate + auth: "{{ __sap_vm_provision_task_ibmpowervm_openstack_auth_delegate }}" - name: Check network available in IBM PowerVM + register: __sap_vm_provision_task_ibmpowervm_network openstack.cloud.networks_info: - auth: "{{ openstack_auth }}" - validate_certs: false # Allow Self-Signed Certificate name: "{{ sap_vm_provision_ibmpowervm_network_name }}" - register: register_ibmpowervm_available_network + validate_certs: false # Allow Self-Signed Certificate + auth: "{{ __sap_vm_provision_task_ibmpowervm_openstack_auth }}" # VM creation block: @@ -43,16 +48,14 @@ # - name: Block that provisions the VM when: - - register_check_vm_exists.servers is defined - - register_check_vm_exists.servers | length == 0 + - __sap_vm_provision_task_provision_host_single_check_exists.servers is defined + - __sap_vm_provision_task_provision_host_single_check_exists.servers | length == 0 block: # See documented IBM PowerVM Compute Template (OpenStack Flavor) extra specs - https://www.ibm.com/docs/en/powervc-cloud/latest?topic=apis-flavors-extra-specs - name: Create IBM PowerVM Compute Template - register: register_ibmpowervm_compute_template + register: __sap_vm_provision_task_ibmpowervm_compute_template openstack.cloud.compute_flavor: - auth: "{{ openstack_auth }}" - validate_certs: false # Allow Self-Signed Certificate state: present name: "{{ inventory_hostname }}-compute-template" @@ -97,12 +100,13 @@ "powervm:secure_boot": 0 # "Disabled" "powervm:srr_capability": "false" # Disable the Simplified Remote Restart + validate_certs: false # Allow Self-Signed Certificate + auth: "{{ __sap_vm_provision_task_ibmpowervm_openstack_auth }}" + - name: Provision IBM PowerVM vNIC (Network Port) - register: register_provisioned_host_vnic_single + register: __sap_vm_provision_task_provision_host_single_vnic openstack.cloud.port: - auth: "{{ openstack_auth }}" - validate_certs: false # Allow Self-Signed Certificate state: present name: "{{ inventory_hostname }}-vnic0" network: "{{ sap_vm_provision_ibmpowervm_network_name }}" @@ -125,12 +129,12 @@ }]) -%} {%- endif -%} {{ vnic_config[0] }} + validate_certs: false # Allow Self-Signed Certificate + auth: "{{ __sap_vm_provision_task_ibmpowervm_openstack_auth }}" - name: Provision IBM PowerVM Virtual Machine (LPAR) - register: register_provisioned_host_single + register: __sap_vm_provision_task_provision_host_single openstack.cloud.server: - auth: "{{ openstack_auth }}" - validate_certs: false # Allow Self-Signed Certificate ## Virtual Machine target Hypervisor definition availability_zone: "{{ sap_vm_provision_ibmpowervm_host_group_name }}" # IBM PowerVM Hypervisor Cluster Host Group Name @@ -144,7 +148,7 @@ description: "{{ inventory_hostname }} created by Ansible Playbook for SAP" ## Virtual Machine main resources definition - flavor: "{{ register_ibmpowervm_compute_template.flavor.id }}" + flavor: "{{ __sap_vm_provision_task_ibmpowervm_compute_template.flavor.id }}" image: "{{ sap_vm_provision_ibmpowervm_vm_host_os_image }}" # Do not set boot_from_volume, boot_volume or volumes parameters when cloning OS Image template terminate_volume: true key_name: "{{ sap_vm_provision_ibmpowervm_key_pair_name_ssh_host_public_key }}" @@ -160,11 +164,14 @@ hostname: "{{ inventory_hostname }}" #userdata: | # cloud-init userdata + validate_certs: false # Allow Self-Signed Certificate + auth: "{{ __sap_vm_provision_task_ibmpowervm_openstack_auth }}" + # Report VM provisioning complete, only after status is Active (not Building) # If provisioning error occurs (e.g. 'Could not find image XYZ with exclude (deprecated)') then - # will show error as 'The conditional check register_provisioned_host_single.server.status == "ACTIVE" failed + # will show error as 'The conditional check __sap_vm_provision_task_provision_host_single.server.status == "ACTIVE" failed # and the actual error will be hidden unless the 'until' is commented-out - until: register_provisioned_host_single.server.status is defined and register_provisioned_host_single.server.status == "ACTIVE" + until: __sap_vm_provision_task_provision_host_single.server.status is defined and __sap_vm_provision_task_provision_host_single.server.status == "ACTIVE" retries: 120 delay: 5 @@ -172,16 +179,15 @@ - name: Collect info on IBM PowerVM vNIC (Network Port) - register: register_provisioned_host_vnic_single + register: __sap_vm_provision_task_provision_host_single_vnic openstack.cloud.port_info: - auth: "{{ openstack_auth }}" - validate_certs: false # Allow Self-Signed Certificate name: "{{ inventory_hostname }}-vnic0" - + validate_certs: false # Allow Self-Signed Certificate + auth: "{{ __sap_vm_provision_task_ibmpowervm_openstack_auth }}" - name: Create fact for delegate host IP ansible.builtin.set_fact: - provisioned_private_ip: "{{ register_provisioned_host_vnic_single.ports[0].fixed_ips[0].ip_address }}" + provisioned_private_ip: "{{ __sap_vm_provision_task_provision_host_single_vnic.ports[0].fixed_ips[0].ip_address }}" # OpenStack APIs cannot query the IBM PowerVC APIs directly, @@ -198,7 +204,7 @@ timeout: 600 - name: Collect only facts about hardware - register: host_disks_info + register: __sap_vm_provision_task_ansible_facts_host_disks_info ansible.builtin.setup: gather_subset: - hardware @@ -217,14 +223,14 @@ #- name: Debug Ansible Facts devices used list # ansible.builtin.debug: -# msg: "{{ host_disks_info.ansible_facts.ansible_device_links.ids.keys() | list }}" +# msg: "{{ __sap_vm_provision_task_ansible_facts_host_disks_info.ansible_facts.ansible_device_links.ids.keys() | list }}" - name: Set fact for available storage volume device names ansible.builtin.set_fact: available_volumes: |- {% set letters = 'bcdefghijklmnopqrstuvwxyz' %} - {% set ansible_facts_devices_used_list = host_disks_info.ansible_facts.ansible_device_links.ids.keys() | list %} + {% set ansible_facts_devices_used_list = __sap_vm_provision_task_ansible_facts_host_disks_info.ansible_facts.ansible_device_links.ids.keys() | list %} {% set volumes = [] %} {%- for letter in letters -%} {% for device in ansible_facts_devices_used_list -%} @@ -277,9 +283,9 @@ # The volume creation task requires the above task to define the parameter # which contains the calculated unique device names. - name: Provision Virtual Disk volumes for IBM PowerVM VM filesystems + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_volumes openstack.cloud.volume: - auth: "{{ openstack_auth_delegate }}" - validate_certs: false # Allow Self-Signed Certificate state: present name: "{{ inventory_hostname }}-vol_{{ vol_item.name }}" # availability_zone: "" @@ -291,6 +297,8 @@ volume_type: "{{ sap_vm_provision_ibmpowervm_storage_template_name }}" is_multiattach: false is_bootable: false + validate_certs: false # Allow Self-Signed Certificate + auth: "{{ __sap_vm_provision_task_ibmpowervm_openstack_auth }}" loop: "{{ filesystem_volume_map }}" loop_control: loop_var: vol_item @@ -299,16 +307,17 @@ when: - vol_item.fstype is defined - vol_item.size > 0 - register: volume_provisioning - name: Attach Virtual Disk volumes to the IBM PowerVM VM + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_volume_attachments openstack.cloud.server_volume: - auth: "{{ openstack_auth_delegate }}" - validate_certs: false # Allow Self-Signed Certificate state: present server: "{{ inventory_hostname }}" volume: "{{ virtual_disk_item.volume.id }}" - loop: "{{ volume_provisioning.results }}" + validate_certs: false # Allow Self-Signed Certificate + auth: "{{ __sap_vm_provision_task_ibmpowervm_openstack_auth }}" + loop: "{{ __sap_vm_provision_task_provision_host_single_volumes.results }}" loop_control: loop_var: virtual_disk_item index_var: virtual_disk_item_index @@ -317,9 +326,10 @@ delay: 5 - name: Re-scan IBM PowerVM VM SCSI Bus + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_os_rescan_scsi_bus_output ansible.builtin.command: "/usr/bin/rescan-scsi-bus.sh" - register: rescan_scsi_bus_output - changed_when: rescan_scsi_bus_output.rc != 0 + changed_when: __sap_vm_provision_task_os_rescan_scsi_bus_output.rc != 0 remote_user: root become: true become_user: root @@ -336,11 +346,12 @@ - name: Check VM status - register: register_provisioned_host_single_info + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_info openstack.cloud.server_info: - auth: "{{ openstack_auth_delegate }}" - validate_certs: false # Allow Self-Signed Certificate name: "{{ inventory_hostname }}" + validate_certs: false # Allow Self-Signed Certificate + auth: "{{ __sap_vm_provision_task_ibmpowervm_openstack_auth }}" # Note: openstack.cloud.server_info Ansible Module can provide: # servers[0].metadata.original_host / servers[0].compute_host / servers[0].hypervisor_hostname for IBM PowerVM HMC System 'Machine Type Machine Serial' (MTMS) @@ -350,8 +361,8 @@ - name: Append loop value to register ansible.builtin.set_fact: - register_provisioned_host_single: "{{ register_provisioned_host_single_info.servers[0] | combine( { 'host_node' : inventory_hostname } , { 'sap_host_type' : lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_host_type } , { 'sap_system_type' : (lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_system_type | default('')) } ) }}" + __sap_vm_provision_task_provision_host_single: "{{ __sap_vm_provision_task_provision_host_single_info.servers[0] | combine( { 'host_node' : inventory_hostname } , { 'sap_host_type' : lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_host_type } , { 'sap_system_type' : (lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_system_type | default('')) } ) }}" - name: Append output to merged register ansible.builtin.set_fact: - register_provisioned_host_all: "{{ register_provisioned_host_all + [register_provisioned_host_single] }}" + register_provisioned_host_all: "{{ register_provisioned_host_all + [__sap_vm_provision_task_provision_host_single] }}" diff --git a/roles/sap_vm_provision/tasks/platform_ansible/kubevirt_vm/execute_main.yml b/roles/sap_vm_provision/tasks/platform_ansible/kubevirt_vm/execute_main.yml index fa883bf..7563763 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/kubevirt_vm/execute_main.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/kubevirt_vm/execute_main.yml @@ -1,71 +1,105 @@ --- -- name: Set fact to hold loop variables from include_tasks - ansible.builtin.set_fact: - register_provisioned_host_all: [] - -- name: Set fact for auth - defaults - ansible.builtin.set_fact: - api_version: "kubevirt.io/v1" - validate_certs: "{{ default(lookup('env', 'K8S_AUTH_VERIFY_SSL')) | default(false) }}" - persist_config: "{{ default(lookup('env', 'K8S_AUTH_PERSIST_CONFIG')) | default(true) }}" - host: "{{ sap_vm_provision_kubevirt_cluster_url | default(lookup('env', 'K8S_AUTH_HOST')) | default(omit) }}" # Target Hypervisor Node - -- name: Set fact for auth - Kubeconfig - ansible.builtin.set_fact: - kubeconfig: "{{ sap_vm_provision_kubevirt_kubeconfig_path | default(lookup('env', 'K8S_AUTH_KUBECONFIG')) | default(lookup('env', 'KUBECONFIG')) | default(omit) }}" - -- name: Set fact for auth - API Key - ansible.builtin.set_fact: - api_key: "{{ sap_vm_provision_kubevirt_api_key | default(lookup('env', 'K8S_AUTH_API_KEY')) | default(omit) }}" - when: kubeconfig is defined - -- name: Set fact for auth - Username and Passwords - ansible.builtin.set_fact: - username: "{{ sap_vm_provision_kubevirt_username | default(lookup('env', 'K8S_AUTH_USERNAME')) | default(omit) }}" - password: "{{ sap_vm_provision_kubevirt_username | default(lookup('env', 'K8S_AUTH_PASSWORD')) | default(omit) }}" - -# - name: Set fact for auth - Alternative -# ansible.builtin.set_fact: -# ca_cert: "{{ default(lookup('env', 'K8S_AUTH_SSL_CA_CERT')) | default(omit) }}" -# client_cert: "{{ default(lookup('env', 'K8S_AUTH_CERT_FILE')) | default(omit) }}" -# client_key: "{{ default(lookup('env', 'K8S_AUTH_KEY_FILE')) | default(omit) }}" -# context: "{{ default(lookup('env', 'K8S_AUTH_CONTEXT')) | default(omit) }}" - -- name: Provision hosts to KubeVirt - register: register_provisioned_hosts - ansible.builtin.include_tasks: - file: "{{ 'platform_' + sap_vm_provision_iac_type }}/{{ sap_vm_provision_iac_platform }}/execute_provision.yml" - -- name: Add hosts provisioned to the Ansible Inventory - register: register_add_hosts - ansible.builtin.add_host: - name: "{{ add_item[0].host_node }}" - groups: "{{ add_item[0].sap_system_type + '_' if (add_item[0].sap_system_type != '') }}{{ add_item[0].sap_host_type }}" - ansible_host: "{{ add_item[0].reported_devices[0].ips[0].address }}" - ansible_user: "root" - ansible_ssh_private_key_file: "{{ sap_vm_provision_ssh_host_private_key_file_path }}" - ansible_ssh_common_args: -o ConnectTimeout=180 -o ControlMaster=auto -o ControlPersist=3600s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ForwardX11=no - loop: "{{ ansible_play_hosts | map('extract', hostvars, 'register_provisioned_host_all') }}" - loop_control: - label: "{{ add_item[0].host_node }}" - loop_var: add_item +- name: Ansible Task block for looped provisioning of KubeVirt Virtual Machines + any_errors_fatal: true + # Using environment, no_log is ineffective and log will show 'EXEC /bin/sh -c 'ENV_VAR=value python3 /AnsiballZ_ansible_module_name.py && sleep 0' + # Therefore do not use environment for secrets, use only for non-sensitive values as this will reduce Ansible Task parameters. + # environment: + block: + + - name: Set fact to hold loop variables from include_tasks + ansible.builtin.set_fact: + register_provisioned_host_all: [] + + - name: Set fact for auth - defaults + ansible.builtin.set_fact: + api_version: "kubevirt.io/v1" + validate_certs: "{{ default(lookup('env', 'K8S_AUTH_VERIFY_SSL')) | default(false) }}" + persist_config: "{{ default(lookup('env', 'K8S_AUTH_PERSIST_CONFIG')) | default(true) }}" + host: "{{ sap_vm_provision_kubevirt_cluster_url | default(lookup('env', 'K8S_AUTH_HOST')) | default(omit) }}" # Target Hypervisor Node + + - name: Set fact for auth - Kubeconfig + no_log: "{{ __sap_vm_provision_no_log }}" + ansible.builtin.set_fact: + kubeconfig: "{{ sap_vm_provision_kubevirt_kubeconfig_path | default(lookup('env', 'K8S_AUTH_KUBECONFIG')) | default(lookup('env', 'KUBECONFIG')) | default(omit) }}" + + - name: Set fact for auth - API Key + no_log: "{{ __sap_vm_provision_no_log }}" + ansible.builtin.set_fact: + api_key: "{{ sap_vm_provision_kubevirt_api_key | default(lookup('env', 'K8S_AUTH_API_KEY')) | default(omit) }}" + when: kubeconfig is defined + + - name: Set fact for auth - Username and Passwords + no_log: "{{ __sap_vm_provision_no_log }}" + ansible.builtin.set_fact: + username: "{{ sap_vm_provision_kubevirt_username | default(lookup('env', 'K8S_AUTH_USERNAME')) | default(omit) }}" + password: "{{ sap_vm_provision_kubevirt_username | default(lookup('env', 'K8S_AUTH_PASSWORD')) | default(omit) }}" + + # - name: Set fact for auth - Alternative + # no_log: "{{ __sap_vm_provision_no_log }}" + # ansible.builtin.set_fact: + # ca_cert: "{{ default(lookup('env', 'K8S_AUTH_SSL_CA_CERT')) | default(omit) }}" + # client_cert: "{{ default(lookup('env', 'K8S_AUTH_CERT_FILE')) | default(omit) }}" + # client_key: "{{ default(lookup('env', 'K8S_AUTH_KEY_FILE')) | default(omit) }}" + # context: "{{ default(lookup('env', 'K8S_AUTH_CONTEXT')) | default(omit) }}" + + - name: Provision hosts to KubeVirt + register: __sap_vm_provision_task_provision_host_all_run + ansible.builtin.include_tasks: + file: "{{ 'platform_' + sap_vm_provision_iac_type }}/{{ sap_vm_provision_iac_platform }}/execute_provision.yml" + + - name: Add hosts provisioned to the Ansible Inventory + register: __sap_vm_provision_task_provision_host_all_add + ansible.builtin.add_host: + name: "{{ add_item[0].host_node }}" + groups: "{{ add_item[0].sap_system_type + '_' if (add_item[0].sap_system_type != '') }}{{ add_item[0].sap_host_type }}" + ansible_host: "{{ add_item[0].reported_devices[0].ips[0].address }}" + ansible_user: "root" + ansible_ssh_private_key_file: "{{ sap_vm_provision_ssh_host_private_key_file_path }}" + ansible_ssh_common_args: -o ConnectTimeout=180 -o ControlMaster=auto -o ControlPersist=3600s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ForwardX11=no + loop: "{{ ansible_play_hosts | map('extract', hostvars, 'register_provisioned_host_all') }}" + loop_control: + label: "{{ add_item[0].host_node }}" + loop_var: add_item # Cannot override any variables from extravars input, see https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#understanding-variable-precedence # Ensure no default value exists for any prompted variable before execution of Ansible Playbook -- name: Set fact to hold all inventory hosts in all groups - ansible.builtin.set_fact: - groups_merged_list: "{{ [ [ groups['hana_primary'] | default([]) ] , [ groups['hana_secondary'] | default([]) ] , [ groups['nwas_ascs'] | default([]) ] , [ groups['nwas_ers'] | default([]) ] , [ groups['nwas_pas'] | default([]) ] , [ groups['nwas_aas'] | default([]) ] ] | flatten | select() }}" + - name: Set fact to hold all inventory hosts in all groups + ansible.builtin.set_fact: + groups_merged_list: "{{ [ [ groups['hana_primary'] | default([]) ] , [ groups['hana_secondary'] | default([]) ] , [ groups['nwas_ascs'] | default([]) ] , [ groups['nwas_ers'] | default([]) ] , [ groups['nwas_pas'] | default([]) ] , [ groups['nwas_aas'] | default([]) ] ] | flatten | select() }}" -- name: Set Ansible Vars - register: register_set_ansible_vars - ansible.builtin.include_tasks: - file: common/set_ansible_vars.yml + - name: Set Ansible Vars + register: __sap_vm_provision_task_ansible_vars_set + ansible.builtin.include_tasks: + file: common/set_ansible_vars.yml # - ansible.builtin.debug: - # var: register_add_hosts.results + # var: __sap_vm_provision_task_provision_host_all_add.results + + rescue: + # This requires no_log set on each Ansible Task, and not set on the Ansible Task Block + # This requires an Ansible Task Block containing the Ansible Tasks for calling + # Infrastructure Platform APIs (via Ansible Modules) + - name: Show errors in task outputs + ansible.builtin.fail: + msg: "{{ lookup('ansible.builtin.vars', loop_item) }}" + loop: + - __sap_vm_provision_task_provision_host_all_run + - __sap_vm_provision_task_provision_host_single + - __sap_vm_provision_task_provision_host_single_info + - __sap_vm_provision_task_ansible_facts_host_disks_info + - __sap_vm_provision_task_provision_host_all_add + loop_control: + loop_var: loop_item + index_var: loop_item_index + label: "{{ 'Variable No. ' + (loop_item_index | string) }}" + when: + - lookup('ansible.builtin.vars', loop_item, default='') | length > 0 + - not lookup('ansible.builtin.vars', loop_item, default='') is skipped + - lookup('ansible.builtin.vars', loop_item, default='') is failed + - name: Ansible Task block to execute on target inventory hosts delegate_to: "{{ inventory_hostname }}" @@ -84,33 +118,33 @@ name: "{{ inventory_hostname_short }}" - name: Set /etc/hosts - register: register_etc_hosts_file + register: __sap_vm_provision_task_os_etc_hosts ansible.builtin.include_tasks: file: common/set_etc_hosts.yml - name: Set /etc/hosts for HA - register: register_etc_hosts_file_ha + register: __sap_vm_provision_task_os_etc_hosts_ha ansible.builtin.include_tasks: file: common/set_etc_hosts_ha.yml when: - (groups["hana_secondary"] is defined and (groups["hana_secondary"] | length>0)) or (groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0)) or (groups["anydb_secondary"] is defined and (groups["anydb_secondary"] | length>0)) - name: Set /etc/hosts for Scale-Out - register: register_etc_hosts_file_scaleout + register: __sap_vm_provision_task_os_etc_hosts_scaleout ansible.builtin.include_tasks: file: common/set_etc_hosts_scaleout.yml when: - - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_hana_scaleout_active_coordinator is defined or sap_hana_scaleout_active_worker is defined or sap_hana_scaleout_standby is defined) + - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined or sap_vm_provision_calculate_sap_hana_scaleout_active_worker is defined or sap_vm_provision_calculate_sap_hana_scaleout_standby is defined) - name: Set vars for sap_storage_setup Ansible Role - register: register_ansible_vars_storage + register: __sap_vm_provision_task_ansible_vars_storage ansible.builtin.include_tasks: file: common/set_ansible_vars_storage.yml - - name: Register Package Repositories - ansible.builtin.include_tasks: - file: common/register_os.yml - - name: Register Web Forward Proxy ansible.builtin.include_tasks: file: common/register_proxy.yml + + - name: Register Package Repositories + ansible.builtin.include_tasks: + file: common/register_os.yml diff --git a/roles/sap_vm_provision/tasks/platform_ansible/kubevirt_vm/execute_provision.yml b/roles/sap_vm_provision/tasks/platform_ansible/kubevirt_vm/execute_provision.yml index 7b10c3b..e068c90 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/kubevirt_vm/execute_provision.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/kubevirt_vm/execute_provision.yml @@ -1,12 +1,17 @@ --- # The tasks in this file are executed in a loop over the defined hosts +- name: Ensure short hostname is not longer than 13 characters (see SAP Note 611361) + ansible.builtin.assert: + that: (inventory_hostname | length | int) <= (13 | int) + fail_msg: "FAIL: The length of the hostname is {{ inventory_hostname | length | int }} but must be less or equal to 13 characters!" + # When SAP HANA Scale-Out is used, if host name is not in original specifications then strip suffix node number from host name - name: Set fact when performing SAP HANA Scale-Out ansible.builtin.set_fact: scaleout_origin_host_spec: "{{ inventory_hostname | regex_replace('^(.+?)\\d*$', '\\1') }}" when: - - sap_hana_scaleout_active_coordinator is defined + - sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined - not inventory_hostname in lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan].keys() @@ -141,7 +146,11 @@ - name: Provision KubeVirt Virtual Machine + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single kubevirt.core.kubevirt_vm: + + ## Hypervisor Control Plane definition and credentials api_version: "{{ api_version | default(omit) }}" validate_certs: "{{ validate_certs | default(omit) }}" persist_config: "{{ persist_config | default(omit) }}" @@ -228,7 +237,8 @@ - name: Check VM status - register: register_provisioned_host_single_info + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_info kubevirt.core.kubevirt_vm_info: name: "{{ inventory_hostname }}" namespace: "{{ sap_vm_provision_kubevirt_target_namespace }}" @@ -236,11 +246,11 @@ - name: Create fact for delegate host IP ansible.builtin.set_fact: - provisioned_private_ip: "{{ register_provisioned_host_single_info.spec.UNKNOWN_VARIABLE_FOR_PRIVATE_IP_HERE }}" + provisioned_private_ip: "{{ __sap_vm_provision_task_provision_host_single_info.spec.UNKNOWN_VARIABLE_FOR_PRIVATE_IP_HERE }}" - name: Collect only facts about hardware - register: host_disks_info + register: __sap_vm_provision_task_ansible_facts_host_disks_info ansible.builtin.setup: gather_subset: - hardware @@ -258,13 +268,13 @@ #- name: Debug Ansible Facts devices used list # ansible.builtin.debug: -# msg: "{{ host_disks_info.ansible_facts.ansible_device_links.ids.keys() | list }}" +# msg: "{{ __sap_vm_provision_task_ansible_facts_host_disks_info.ansible_facts.ansible_device_links.ids.keys() | list }}" - name: Append loop value to register ansible.builtin.set_fact: - register_provisioned_host_single: "{{ register_provisioned_host_single_info.spec.UKNOWN_VARIABLE_HERE | combine( { 'host_node' : inventory_hostname } , { 'sap_host_type' : lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_host_type } , { 'sap_system_type' : (lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_system_type | default('')) } ) }}" + __sap_vm_provision_task_provision_host_single: "{{ __sap_vm_provision_task_provision_host_single_info.spec.UKNOWN_VARIABLE_HERE | combine( { 'host_node' : inventory_hostname } , { 'sap_host_type' : lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_host_type } , { 'sap_system_type' : (lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_system_type | default('')) } ) }}" - name: Append output to merged register ansible.builtin.set_fact: - register_provisioned_host_all: "{{ register_provisioned_host_all + [register_provisioned_host_single] }}" + register_provisioned_host_all: "{{ register_provisioned_host_all + [__sap_vm_provision_task_provision_host_single] }}" diff --git a/roles/sap_vm_provision/tasks/platform_ansible/msazure_vm/execute_main.yml b/roles/sap_vm_provision/tasks/platform_ansible/msazure_vm/execute_main.yml index fd6bca6..6f5a96a 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/msazure_vm/execute_main.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/msazure_vm/execute_main.yml @@ -1,36 +1,73 @@ --- - name: Ansible Task block for looped provisioning of MS Azure VMs + any_errors_fatal: true + # Using environment, no_log is ineffective and log will show 'EXEC /bin/sh -c 'ENV_VAR=value python3 /AnsiballZ_ansible_module_name.py && sleep 0' + # Therefore do not use environment for secrets, use only for non-sensitive values as this will reduce Ansible Task parameters. environment: - ANSIBLE_AZURE_AUTH_SOURCE: "env" - AZURE_SUBSCRIPTION_ID: "{{ sap_vm_provision_msazure_subscription_id }}" - AZURE_TENANT: "{{ sap_vm_provision_msazure_tenant_id }}" - AZURE_CLIENT_ID: "{{ sap_vm_provision_msazure_app_client_id }}" - AZURE_SECRET: "{{ sap_vm_provision_msazure_app_client_secret }}" + ANSIBLE_AZURE_AUTH_SOURCE: "auto" # Set to auto to use module parameters + # AZURE_SUBSCRIPTION_ID: "{{ sap_vm_provision_msazure_subscription_id }}" + # AZURE_TENANT: "{{ sap_vm_provision_msazure_tenant_id }}" + # AZURE_CLIENT_ID: "{{ sap_vm_provision_msazure_app_client_id }}" + # AZURE_SECRET: "{{ sap_vm_provision_msazure_app_client_secret }}" block: - name: Set fact to hold loop variables from include_tasks ansible.builtin.set_fact: register_provisioned_host_all: [] + # Ansible Module name parameter, requires resource_group parameter + # We cannot assume Resource Group if the SSH Public Key is managed by Administrators + # Therefore use without any parameter to retrieve list of all SSH Public Keys and filter in Ansible + - name: Get all SSH Public Keys in MS Azure + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_msazure_key_pair_name_ssh_host_public_keys + azure.azcollection.azure_rm_sshpublickey_info: + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" + + - name: Set fact for selected SSH Public Key in MS Azure + ansible.builtin.set_fact: + __sap_vm_provision_task_msazure_key_pair_name_ssh_host_public_key_value: "{{ (__sap_vm_provision_task_msazure_key_pair_name_ssh_host_public_keys.ssh_keys | selectattr('name', '==', sap_vm_provision_msazure_key_pair_name_ssh_host_public_key))[0].public_key }}" + + - name: Get Private DNS Zone Virtual Network Links + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_msazure_private_dns_virtual_network_links + azure.azcollection.azure_rm_privatednszonelink_info: + # DNS may exist in separate Resource Group. Use empty string var (or default false if undefined) to evaluate to false boolean, and use Python or logic operator + resource_group: "{{ (sap_vm_provision_msazure_private_dns_resource_group_name | default(false)) or sap_vm_provision_msazure_resource_group_name }}" + zone_name: "{{ sap_vm_provision_dns_root_domain }}" + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" + + - name: Set boolean fact for Auto Registration of DNS Records from Private DNS Zone Virtual Network Link + ansible.builtin.set_fact: + __sap_vm_provision_task_msazure_private_dns_auto_register_records: "{{ (__sap_vm_provision_task_msazure_private_dns_virtual_network_links.virtualnetworklinks | selectattr('virtual_network.id', 'search', sap_vm_provision_msazure_vnet_name))[0].registration_enabled }}" + - name: Provision hosts to MS Azure - register: register_provisioned_hosts + register: __sap_vm_provision_task_provision_host_all_run ansible.builtin.include_tasks: file: "{{ 'platform_' + sap_vm_provision_iac_type }}/{{ sap_vm_provision_iac_platform }}/execute_provision.yml" apply: environment: - ANSIBLE_AZURE_AUTH_SOURCE: "env" - AZURE_SUBSCRIPTION_ID: "{{ sap_vm_provision_msazure_subscription_id }}" - AZURE_TENANT: "{{ sap_vm_provision_msazure_tenant_id }}" - AZURE_CLIENT_ID: "{{ sap_vm_provision_msazure_app_client_id }}" - AZURE_SECRET: "{{ sap_vm_provision_msazure_app_client_secret }}" + ANSIBLE_AZURE_AUTH_SOURCE: "auto" # Set to auto to use module parameters + # AZURE_SUBSCRIPTION_ID: "{{ sap_vm_provision_msazure_subscription_id }}" + # AZURE_TENANT: "{{ sap_vm_provision_msazure_tenant_id }}" + # AZURE_CLIENT_ID: "{{ sap_vm_provision_msazure_app_client_id }}" + # AZURE_SECRET: "{{ sap_vm_provision_msazure_app_client_secret }}" - name: Add hosts provisioned to the Ansible Inventory - register: register_add_hosts + register: __sap_vm_provision_task_provision_host_all_add ansible.builtin.add_host: name: "{{ add_item[0].host_node }}" groups: "{{ add_item[0].sap_system_type + '_' if (add_item[0].sap_system_type != '') }}{{ add_item[0].sap_host_type }}" - ansible_host: "{{ add_item[0].ansible_facts.azure_vm.properties.networkProfile.networkInterfaces[0].properties.ipConfigurations[0].properties.privateIPAddress }}" + ansible_host: "{{ add_item[0].ansible_facts.azure_vm.network_profile.network_interfaces[0].properties.ip_configurations[0].private_ip_address }}" ansible_user: "root" ansible_ssh_private_key_file: "{{ sap_vm_provision_ssh_host_private_key_file_path }}" ansible_ssh_common_args: -o ConnectTimeout=180 -o ControlMaster=auto -o ControlPersist=3600s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ForwardX11=no -o ProxyCommand='ssh -W %h:%p {{ sap_vm_provision_bastion_user }}@{{ sap_vm_provision_bastion_public_ip }} -p {{ sap_vm_provision_bastion_ssh_port }} -i {{ sap_vm_provision_ssh_bastion_private_key_file_path }} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' @@ -48,22 +85,58 @@ groups_merged_list: "{{ [ [ groups['hana_primary'] | default([]) ] , [ groups['hana_secondary'] | default([]) ] , [ groups['nwas_ascs'] | default([]) ] , [ groups['nwas_ers'] | default([]) ] , [ groups['nwas_pas'] | default([]) ] , [ groups['nwas_aas'] | default([]) ] ] | flatten | select() }}" - name: Set Ansible Vars - register: register_set_ansible_vars + register: __sap_vm_provision_task_ansible_vars_set ansible.builtin.include_tasks: file: common/set_ansible_vars.yml # Create "A" (IPv4 Address) Resource Record to map IPv4 address as hostname / subdomain of the root domain name - name: Ansible MS Azure Private DNS Records for hosts + no_log: "{{ __sap_vm_provision_no_log }}" azure.azcollection.azure_rm_privatednsrecordset: - resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" + # DNS may exist in separate Resource Group. Use empty string var (or default false if undefined) to evaluate to false boolean, and use Python or logic operator + resource_group: "{{ (sap_vm_provision_msazure_private_dns_resource_group_name | default(false)) or sap_vm_provision_msazure_resource_group_name }}" zone_name: "{{ hostvars[inventory_hostname].sap_vm_provision_dns_root_domain }}" relative_name: "{{ inventory_hostname }}" record_type: A records: - entry: "{{ hostvars[inventory_hostname].ansible_host }}" + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" + when: not __sap_vm_provision_task_msazure_private_dns_auto_register_records # - ansible.builtin.debug: - # var: register_add_hosts.results + # var: __sap_vm_provision_task_provision_host_all_add.results + + rescue: + # This requires no_log set on each Ansible Task, and not set on the Ansible Task Block + # This requires an Ansible Task Block containing the Ansible Tasks for calling + # Infrastructure Platform APIs (via Ansible Modules) + - name: Show errors in task outputs + ansible.builtin.fail: + msg: "{{ lookup('ansible.builtin.vars', loop_item) }}" + loop: + - __sap_vm_provision_task_msazure_key_pair_name_ssh_host_public_keys + - __sap_vm_provision_task_msazure_private_dns_virtual_network_links + - __sap_vm_provision_task_provision_host_all_run + - __sap_vm_provision_task_provision_host_single_vnic_info + - __sap_vm_provision_task_provision_host_single_vnic + - __sap_vm_provision_task_provision_host_single + - __sap_vm_provision_task_provision_host_single_info + - __sap_vm_provision_task_ansible_facts_host_disks_info + - __sap_vm_provision_task_provision_host_single_volumes + - __sap_vm_provision_task_provision_host_all_add + loop_control: + loop_var: loop_item + index_var: loop_item_index + label: "{{ 'Variable No. ' + (loop_item_index | string) }}" + when: + - lookup('ansible.builtin.vars', loop_item, default='') | length > 0 + - not lookup('ansible.builtin.vars', loop_item, default='') is skipped + - lookup('ansible.builtin.vars', loop_item, default='') is failed + - name: Ansible Task block to execute on target inventory hosts delegate_to: "{{ inventory_hostname }}" @@ -82,26 +155,26 @@ name: "{{ inventory_hostname_short }}" - name: Set /etc/hosts - register: register_etc_hosts_file + register: __sap_vm_provision_task_os_etc_hosts ansible.builtin.include_tasks: file: common/set_etc_hosts.yml - name: Set /etc/hosts for HA - register: register_etc_hosts_file_ha + register: __sap_vm_provision_task_os_etc_hosts_ha ansible.builtin.include_tasks: file: common/set_etc_hosts_ha.yml when: - (groups["hana_secondary"] is defined and (groups["hana_secondary"] | length>0)) or (groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0)) or (groups["anydb_secondary"] is defined and (groups["anydb_secondary"] | length>0)) - name: Set /etc/hosts for Scale-Out - register: register_etc_hosts_file_scaleout + register: __sap_vm_provision_task_os_etc_hosts_scaleout ansible.builtin.include_tasks: file: common/set_etc_hosts_scaleout.yml when: - - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_hana_scaleout_active_coordinator is defined or sap_hana_scaleout_active_worker is defined or sap_hana_scaleout_standby is defined) + - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined or sap_vm_provision_calculate_sap_hana_scaleout_active_worker is defined or sap_vm_provision_calculate_sap_hana_scaleout_standby is defined) - name: Set vars for sap_storage_setup Ansible Role - register: register_ansible_vars_storage + register: __sap_vm_provision_task_ansible_vars_storage ansible.builtin.include_tasks: file: common/set_ansible_vars_storage.yml @@ -131,25 +204,28 @@ # Ensure Primary Active Network Interface is used for Linux Pacemaker configuration (e.g. eth0), see documentation for Accelerated Networking - name: Identify Primary Active Network Interface - register: __msazure_primary_active_vnic + register: __sap_vm_provision_task_os_primary_active_vnic ansible.builtin.shell: | set -o pipefail && ip route show default 0.0.0.0/0 | awk '/default/ {print $5}' - name: Set facts on each host - Primary Active Network Interface for HA/DR ansible.builtin.set_fact: - sap_ha_pacemaker_cluster_vip_client_interface: "{{ __msazure_primary_active_vnic.stdout }}" - when: __msazure_primary_active_vnic is defined + sap_ha_pacemaker_cluster_vip_client_interface: "{{ __sap_vm_provision_task_os_primary_active_vnic.stdout }}" + when: __sap_vm_provision_task_os_primary_active_vnic is defined - name: Ansible Task block for provisioning of High Availability resources for MS Azure VMs delegate_to: localhost + any_errors_fatal: true run_once: true + # Using environment, no_log is ineffective and log will show 'EXEC /bin/sh -c 'ENV_VAR=value python3 /AnsiballZ_ansible_module_name.py && sleep 0' + # Therefore do not use environment for secrets, use only for non-sensitive values as this will reduce Ansible Task parameters. environment: - ANSIBLE_AZURE_AUTH_SOURCE: "env" - AZURE_SUBSCRIPTION_ID: "{{ sap_vm_provision_msazure_subscription_id }}" - AZURE_TENANT: "{{ sap_vm_provision_msazure_tenant_id }}" - AZURE_CLIENT_ID: "{{ sap_vm_provision_msazure_app_client_id }}" - AZURE_SECRET: "{{ sap_vm_provision_msazure_app_client_secret }}" + ANSIBLE_AZURE_AUTH_SOURCE: "auto" # Set to auto to use module parameters + # AZURE_SUBSCRIPTION_ID: "{{ sap_vm_provision_msazure_subscription_id }}" + # AZURE_TENANT: "{{ sap_vm_provision_msazure_tenant_id }}" + # AZURE_CLIENT_ID: "{{ sap_vm_provision_msazure_app_client_id }}" + # AZURE_SECRET: "{{ sap_vm_provision_msazure_app_client_secret }}" when: - sap_ha_pacemaker_cluster_msazure_resource_group is defined - (groups["hana_secondary"] is defined and (groups["hana_secondary"] | length>0)) or (groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0)) or (groups["anydb_secondary"] is defined and (groups["anydb_secondary"] | length>0)) @@ -160,8 +236,39 @@ file: "{{ 'platform_' + sap_vm_provision_iac_type }}/{{ sap_vm_provision_iac_platform }}/execute_setup_ha.yml" apply: environment: - ANSIBLE_AZURE_AUTH_SOURCE: "env" - AZURE_SUBSCRIPTION_ID: "{{ sap_vm_provision_msazure_subscription_id }}" - AZURE_TENANT: "{{ sap_vm_provision_msazure_tenant_id }}" - AZURE_CLIENT_ID: "{{ sap_vm_provision_msazure_app_client_id }}" - AZURE_SECRET: "{{ sap_vm_provision_msazure_app_client_secret }}" + ANSIBLE_AZURE_AUTH_SOURCE: "auto" # Set to auto to use module parameters + # AZURE_SUBSCRIPTION_ID: "{{ sap_vm_provision_msazure_subscription_id }}" + # AZURE_TENANT: "{{ sap_vm_provision_msazure_tenant_id }}" + # AZURE_CLIENT_ID: "{{ sap_vm_provision_msazure_app_client_id }}" + # AZURE_SECRET: "{{ sap_vm_provision_msazure_app_client_secret }}" + + rescue: + # This requires no_log set on each Ansible Task, and not set on the Ansible Task Block + # This requires an Ansible Task Block containing the Ansible Tasks for calling + # Infrastructure Platform APIs (via Ansible Modules) + - name: Show errors in task outputs + ansible.builtin.fail: + msg: "{{ lookup('ansible.builtin.vars', loop_item) }}" + loop: + - __sap_vm_provision_task_msazure_vnet_subnet_rt_info + - __sap_vm_provision_task_msazure_vnet_subnet_rt_route_sap_hana + - __sap_vm_provision_task_msazure_vnet_subnet_rt_route_sap_netweaver_ascs + - __sap_vm_provision_task_msazure_vnet_subnet_rt_route_sap_netweaver_ers + - __sap_vm_provision_task_msazure_vnet_subnet_rt_route_sap_netweaver_pas + - __sap_vm_provision_task_msazure_vnet_subnet_rt_route_sap_netweaver_aas + - __sap_vm_provision_task_msazure_iam_role_fencing + - __sap_vm_provision_task_msazure_vm_info_collect + - __sap_vm_provision_task_msazure_vnet_subnet_info + - __sap_vm_provision_task_msazure_lb1a_info + - __sap_vm_provision_task_msazure_lb1b_info + - __sap_vm_provision_task_msazure_lb2_info + - __sap_vm_provision_task_provision_host_single_vnic1 + - __sap_vm_provision_task_provision_host_single_vnic2 + loop_control: + loop_var: loop_item + index_var: loop_item_index + label: "{{ 'Variable No. ' + (loop_item_index | string) }}" + when: + - lookup('ansible.builtin.vars', loop_item, default='') | length > 0 + - not lookup('ansible.builtin.vars', loop_item, default='') is skipped + - lookup('ansible.builtin.vars', loop_item, default='') is failed diff --git a/roles/sap_vm_provision/tasks/platform_ansible/msazure_vm/execute_provision.yml b/roles/sap_vm_provision/tasks/platform_ansible/msazure_vm/execute_provision.yml index a1df0ee..bf25c1d 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/msazure_vm/execute_provision.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/msazure_vm/execute_provision.yml @@ -1,22 +1,34 @@ --- # The tasks in this file are executed in a loop over the defined hosts +- name: Ensure short hostname is not longer than 13 characters (see SAP Note 611361) + ansible.builtin.assert: + that: (inventory_hostname | length | int) <= (13 | int) + fail_msg: "FAIL: The length of the hostname is {{ inventory_hostname | length | int }} but must be less or equal to 13 characters!" + # When SAP HANA Scale-Out is used, if host name is not in original specifications then strip suffix node number from host name - name: Set fact when performing SAP HANA Scale-Out ansible.builtin.set_fact: scaleout_origin_host_spec: "{{ inventory_hostname | regex_replace('^(.+?)\\d*$', '\\1') }}" when: - - sap_hana_scaleout_active_coordinator is defined + - sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined - not inventory_hostname in lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan].keys() - name: Verify if network interface for MS Azure VM already exists (i.e. re-run) - register: register_provisioned_vnic_info + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_vnic_info azure.azcollection.azure_rm_networkinterface_info: resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" name: "{{ inventory_hostname }}-nic" + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" - name: Provision network interface for MS Azure VM - register: register_provisioned_vnic + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_vnic azure.azcollection.azure_rm_networkinterface: resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" location: "{{ sap_vm_provision_msazure_location_region }}" @@ -30,10 +42,16 @@ #private_ip_allocation_method: "Static" # When static, must define the specific IP Address enable_accelerated_networking: true enable_ip_forwarding: "{{ lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].disable_ip_anti_spoofing }}" # When disable the Anti IP Spoofing = true, then Enable IP Forwarding = true - when: not (register_provisioned_vnic_info.networkinterfaces | length) > 0 + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" + when: not (__sap_vm_provision_task_provision_host_single_vnic_info.networkinterfaces | length) > 0 - name: Provision MS Azure VM - register: register_provisioned_host_single + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single azure.azcollection.azure_rm_virtualmachine: resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" location: "{{ sap_vm_provision_msazure_location_region }}" @@ -42,7 +60,7 @@ ssh_password_enabled: false ssh_public_keys: - path: /home/azureadmin/.ssh/authorized_keys - key_data: "{{ lookup('ansible.builtin.file', sap_vm_provision_ssh_host_public_key_file_path ) }}" # Replace with import/lookup via Ansible Module azure_rm_ssh_public_key/azure_rm_sshpublickey_info + key_data: "{{ __sap_vm_provision_task_msazure_key_pair_name_ssh_host_public_key_value }}" vm_size: "{{ lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].virtual_machine_profile }}" image: publisher: "{{ lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_os_image_dictionary')[sap_vm_provision_msazure_vm_host_os_image].publisher }}" @@ -53,26 +71,44 @@ public_ip_allocation_method: "Disabled" managed_disk_type: StandardSSD_LRS remove_on_absent: ["all"] - vm_identity: "SystemAssigned" + vm_identity: + type: SystemAssigned state: "present" started: true + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" - name: Read MS Azure VM information - register: api_host_info + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_info azure.azcollection.azure_rm_virtualmachine_info: resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" name: "{{ inventory_hostname }}" + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" - name: Read MS Azure VM attached disks information - register: api_host_disks_info + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ansible_facts_host_disks_info azure.azcollection.azure_rm_manageddisk_info: - managed_by: "{{ api_host_info.vms[0].id }}" + managed_by: "{{ __sap_vm_provision_task_provision_host_single_info.vms[0].id }}" + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" - name: Create fact for delegate host IP ansible.builtin.set_fact: - provisioned_private_ip: "{{ register_provisioned_host_single.ansible_facts.azure_vm.properties.networkProfile.networkInterfaces[0].properties.ipConfigurations[0].properties.privateIPAddress }}" + provisioned_private_ip: "{{ __sap_vm_provision_task_provision_host_single.ansible_facts.azure_vm.network_profile.network_interfaces[0].properties.ip_configurations[0].private_ip_address }}" - name: Copy facts to delegate host @@ -86,7 +122,7 @@ delegate_sap_vm_provision_ssh_host_private_key_file_path: "{{ sap_vm_provision_ssh_host_private_key_file_path }}" - name: Collect only facts about hardware - register: host_disks_info + register: __sap_vm_provision_task_ansible_facts_host_disks_info ansible.builtin.setup: gather_subset: - hardware @@ -105,14 +141,14 @@ #- name: Debug Ansible Facts devices used list # ansible.builtin.debug: -# msg: "{{ host_disks_info.ansible_facts.ansible_device_links.ids.keys() | list }}" +# msg: "{{ __sap_vm_provision_task_ansible_facts_host_disks_info.ansible_facts.ansible_device_links.ids.keys() | list }}" - name: Set fact for available storage volume device names ansible.builtin.set_fact: available_volumes: |- {% set letters = 'bcdefghijklmnopqrstuvwxyz' %} - {% set ansible_facts_devices_used_list = host_disks_info.ansible_facts.ansible_device_links.ids.keys() | list %} + {% set ansible_facts_devices_used_list = __sap_vm_provision_task_ansible_facts_host_disks_info.ansible_facts.ansible_device_links.ids.keys() | list %} {% set volumes = [] %} {%- for letter in letters -%} {% for device in ansible_facts_devices_used_list -%} @@ -165,6 +201,8 @@ # The volume creation task requires the above task to define the parameter # which contains the calculated unique device names. - name: Provision Azure Managed Disk volumes for Azure VM filesystems + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_volumes azure.azcollection.azure_rm_manageddisk: resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" location: "{{ sap_vm_provision_msazure_location_region }}" @@ -175,6 +213,11 @@ resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" # Premium SSD size (P), Standard SSD size (E), Standard HDD size (S) storage_account_type: "{% if vol_item.type | regex_search('^P.*') %}Premium_LRS{% elif vol_item.type | regex_search('^E.*') %}StandardSSD_LRS{% elif vol_item.type | regex_search('^S.*') %}Standard_LRS{% else %}StandardSSD_LRS{% endif %}" # Standard_LRS, StandardSSD_LRS, Premium_LRS, UltraSSD_LRS + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" loop: "{{ filesystem_volume_map }}" loop_control: loop_var: vol_item @@ -183,20 +226,19 @@ when: - vol_item.fstype is defined - vol_item.size > 0 - register: volume_provisioning - failed_when: "(volume_provisioning.msg is defined) and ('already exists' not in volume_provisioning.msg)" + failed_when: "(__sap_vm_provision_task_provision_host_single_volumes.msg is defined) and ('already exists' not in __sap_vm_provision_task_provision_host_single_volumes.msg)" - name: Add host facts ansible.builtin.set_fact: filesystem_volume_map: "{{ filesystem_volume_map }}" - volume_provisioning: "{{ volume_provisioning }}" + __sap_vm_provision_task_provision_host_single_volumes: "{{ __sap_vm_provision_task_provision_host_single_volumes }}" delegate_to: "{{ inventory_hostname }}" delegate_facts: true - name: Create fact for delegate host IP ansible.builtin.set_fact: - provisioned_private_ip: "{{ register_provisioned_host_single.ansible_facts.azure_vm.properties.networkProfile.networkInterfaces[0].properties.ipConfigurations[0].properties.privateIPAddress }}" + provisioned_private_ip: "{{ __sap_vm_provision_task_provision_host_single.ansible_facts.azure_vm.network_profile.network_interfaces[0].properties.ip_configurations[0].private_ip_address }}" - name: Copy facts to delegate host delegate_to: "{{ provisioned_private_ip }}" @@ -207,10 +249,9 @@ delegate_sap_vm_provision_bastion_ssh_port: "{{ sap_vm_provision_bastion_ssh_port }}" delegate_sap_vm_provision_ssh_bastion_private_key_file_path: "{{ sap_vm_provision_ssh_bastion_private_key_file_path }}" delegate_sap_vm_provision_ssh_host_private_key_file_path: "{{ sap_vm_provision_ssh_host_private_key_file_path }}" - delegate_private_ip: "{{ register_provisioned_host_single.ansible_facts.azure_vm.properties.networkProfile.networkInterfaces[0].properties.ipConfigurations[0].properties.privateIPAddress }}" + delegate_private_ip: "{{ __sap_vm_provision_task_provision_host_single.ansible_facts.azure_vm.network_profile.network_interfaces[0].properties.ip_configurations[0].private_ip_address }}" delegate_hostname: "{{ inventory_hostname }}" delegate_sap_vm_provision_dns_root_domain_name: "{{ sap_vm_provision_dns_root_domain }}" - delegate_sap_vm_provision_ssh_host_public_key_file_path: "{{ lookup('ansible.builtin.file', sap_vm_provision_ssh_host_public_key_file_path ) }}" # Replace with import/lookup via Ansible Module azure_rm_ssh_public_key/azure_rm_sshpublickey_info ### begin block, parameters will be applied to each task within the block @@ -233,26 +274,26 @@ replace: 'ssh-rsa' - name: Permit root login + register: __sap_vm_provision_task_os_sshd_config ansible.builtin.replace: path: /etc/ssh/sshd_config regexp: '(^PermitRootLogin no)' replace: 'PermitRootLogin yes' - register: sshd_config - name: Reload sshd service ansible.builtin.service: name: sshd state: reloaded when: - - sshd_config.changed + - __sap_vm_provision_task_os_sshd_config.changed ### end of block - name: Append loop value to register ansible.builtin.set_fact: - register_provisioned_host_single: "{{ register_provisioned_host_single | combine( { 'host_node' : inventory_hostname } , { 'sap_host_type' : lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_host_type } , { 'sap_system_type' : (lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_system_type | default('')) } ) }}" + __sap_vm_provision_task_provision_host_single: "{{ __sap_vm_provision_task_provision_host_single | combine( { 'host_node' : inventory_hostname } , { 'sap_host_type' : lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_host_type } , { 'sap_system_type' : (lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_system_type | default('')) } ) }}" - name: Append output to merged register ansible.builtin.set_fact: - register_provisioned_host_all: "{{ register_provisioned_host_all + [register_provisioned_host_single] }}" + register_provisioned_host_all: "{{ register_provisioned_host_all + [__sap_vm_provision_task_provision_host_single] }}" diff --git a/roles/sap_vm_provision/tasks/platform_ansible/msazure_vm/execute_setup_ha.yml b/roles/sap_vm_provision/tasks/platform_ansible/msazure_vm/execute_setup_ha.yml index bc48e5f..89d9c8a 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/msazure_vm/execute_setup_ha.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/msazure_vm/execute_setup_ha.yml @@ -1,34 +1,53 @@ --- # - name: Gather information about MS Azure Route Table for the VNet Subnet +# register: __sap_vm_provision_task_msazure_vnet_subnet_rt_info +# no_log: "{{ __sap_vm_provision_no_log }}" # azure.azcollection.azure_rm_routetable_info: # resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" # name: "name-here" -# register: msazure_vnet_subnet_rt_info +# # Azure credentials +# subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" +# tenant: "{{ sap_vm_provision_msazure_tenant_id }}" +# client_id: "{{ sap_vm_provision_msazure_app_client_id }}" +# secret: "{{ sap_vm_provision_msazure_app_client_secret }}" # - name: Ansible MS Azure Route Table append route for SAP HANA HA +# no_log: "{{ __sap_vm_provision_no_log }}" +# register: __sap_vm_provision_task_msazure_vnet_subnet_rt_route_sap_hana # azure.azcollection.azure_rm_route: # resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" -# route_table_name: "{{ msazure_vnet_subnet_rt_info.route_tables[0].id }}" +# route_table_name: "{{ __sap_vm_provision_task_msazure_vnet_subnet_rt_info.route_tables[0].id }}" # name: "{{ sap_swpm_db_host }}-rt" # address_prefix: "{{ sap_ha_pacemaker_cluster_vip_hana_primary_ip_address | default('192.168.1.90/32') }}" # next_hop_type: "virtual_appliance" # next_hop_ip_address: "{{ hostvars[host_node].ansible_host }}" +# # Azure credentials +# subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" +# tenant: "{{ sap_vm_provision_msazure_tenant_id }}" +# client_id: "{{ sap_vm_provision_msazure_app_client_id }}" +# secret: "{{ sap_vm_provision_msazure_app_client_secret }}" # loop: "{{ (groups['hana_primary'] | default([])) }}" # loop_control: # loop_var: host_node -# register: msazure_vnet_subnet_rt_route_sap_hana # when: # - groups["hana_secondary"] is defined and (groups["hana_secondary"] | length>0) - name: Ansible MS Azure Private DNS Records for SAP HANA HA Virtual Hostname + no_log: "{{ __sap_vm_provision_no_log }}" azure.azcollection.azure_rm_privatednsrecordset: - resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" + # DNS may exist in separate Resource Group. Use empty string var (or default false if undefined) to evaluate to false boolean, and use Python or logic operator + resource_group: "{{ (sap_vm_provision_msazure_private_dns_resource_group_name | default(false)) or sap_vm_provision_msazure_resource_group_name }}" zone_name: "{{ hostvars[host_node].sap_vm_provision_dns_root_domain }}" relative_name: "{{ sap_swpm_db_host }}" record_type: A records: - entry: "{{ (sap_ha_pacemaker_cluster_vip_hana_primary_ip_address | default('192.168.1.90/32')) | regex_replace('/.*', '') }}" + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" loop: "{{ (groups['hana_primary'] | default([])) }}" loop_control: loop_var: host_node @@ -37,28 +56,41 @@ # - name: Ansible MS Azure Route Table append route for SAP NetWeaver ASCS HA +# no_log: "{{ __sap_vm_provision_no_log }}" +# register: __sap_vm_provision_task_msazure_vnet_subnet_rt_route_sap_netweaver_ascs # azure.azcollection.azure_rm_route: # resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" -# route_table_name: "{{ msazure_vnet_subnet_rt_info.route_tables[0].id }}" +# route_table_name: "{{ __sap_vm_provision_task_msazure_vnet_subnet_rt_info.route_tables[0].id }}" # name: "{{ sap_swpm_ascs_instance_hostname }}-rt" # address_prefix: "{{ sap_ha_pacemaker_cluster_vip_nwas_abap_ascs_ip_address | default('192.168.2.10/32') }}" # next_hop_type: "virtual_appliance" # next_hop_ip_address: "{{ hostvars[host_node].ansible_host }}" +# # Azure credentials +# subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" +# tenant: "{{ sap_vm_provision_msazure_tenant_id }}" +# client_id: "{{ sap_vm_provision_msazure_app_client_id }}" +# secret: "{{ sap_vm_provision_msazure_app_client_secret }}" # loop: "{{ (groups['nwas_ascs'] | default([])) }}" # loop_control: # loop_var: host_node -# register: msazure_vnet_subnet_rt_route_sap_netweaver_ascs # when: # - groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0) - name: Ansible MS Azure Private DNS Records for SAP NetWeaver ASCS HA Virtual Hostname + no_log: "{{ __sap_vm_provision_no_log }}" azure.azcollection.azure_rm_privatednsrecordset: - resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" + # DNS may exist in separate Resource Group. Use empty string var (or default false if undefined) to evaluate to false boolean, and use Python or logic operator + resource_group: "{{ (sap_vm_provision_msazure_private_dns_resource_group_name | default(false)) or sap_vm_provision_msazure_resource_group_name }}" zone_name: "{{ hostvars[host_node].sap_vm_provision_dns_root_domain }}" relative_name: "{{ sap_swpm_ascs_instance_hostname }}" record_type: A records: - entry: "{{ (sap_ha_pacemaker_cluster_vip_nwas_abap_ascs_ip_address | default('192.168.2.10/32')) | regex_replace('/.*', '') }}" + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" loop: "{{ (groups['nwas_ascs'] | default([])) }}" loop_control: loop_var: host_node @@ -67,28 +99,41 @@ # - name: Ansible MS Azure Route Table append route for SAP NetWeaver ERS HA +# no_log: "{{ __sap_vm_provision_no_log }}" +# register: __sap_vm_provision_task_msazure_vnet_subnet_rt_route_sap_netweaver_ers # azure.azcollection.azure_rm_route: # resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" -# route_table_name: "{{ msazure_vnet_subnet_rt_info.route_tables[0].id }}" +# route_table_name: "{{ __sap_vm_provision_task_msazure_vnet_subnet_rt_info.route_tables[0].id }}" # name: "{{ sap_swpm_ers_instance_hostname }}-rt" # address_prefix: "{{ sap_ha_pacemaker_cluster_vip_nwas_abap_ers_ip_address | default('192.168.2.11/32') }}" # next_hop_type: "virtual_appliance" # next_hop_ip_address: "{{ hostvars[host_node].ansible_host }}" +# # Azure credentials +# subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" +# tenant: "{{ sap_vm_provision_msazure_tenant_id }}" +# client_id: "{{ sap_vm_provision_msazure_app_client_id }}" +# secret: "{{ sap_vm_provision_msazure_app_client_secret }}" # loop: "{{ (groups['nwas_ers'] | default([])) }}" # loop_control: # loop_var: host_node -# register: msazure_vnet_subnet_rt_route_sap_netweaver_ers # when: # - groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0) - name: Ansible MS Azure Private DNS Records for SAP NetWeaver ERS HA Virtual Hostname + no_log: "{{ __sap_vm_provision_no_log }}" azure.azcollection.azure_rm_privatednsrecordset: - resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" + # DNS may exist in separate Resource Group. Use empty string var (or default false if undefined) to evaluate to false boolean, and use Python or logic operator + resource_group: "{{ (sap_vm_provision_msazure_private_dns_resource_group_name | default(false)) or sap_vm_provision_msazure_resource_group_name }}" zone_name: "{{ hostvars[host_node].sap_vm_provision_dns_root_domain }}" relative_name: "{{ sap_swpm_ers_instance_hostname }}" record_type: A records: - entry: "{{ (sap_ha_pacemaker_cluster_vip_nwas_abap_ers_ip_address | default('192.168.2.11/32')) | regex_replace('/.*', '') }}" + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" loop: "{{ (groups['nwas_ers'] | default([])) }}" loop_control: loop_var: host_node @@ -98,29 +143,42 @@ ## For HA of PAS and AAS, if required -# - name: Ansible MS Azure Route Table append route for SAP NetWeaver PAS HA -# azure.azcollection.azure_rm_route: -# resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" -# route_table_name: "{{ msazure_vnet_subnet_rt_info.route_tables[0].id }}" -# name: "{{ sap_swpm_pas_instance_hostname }}-rt" -# address_prefix: "{{ sap_ha_pacemaker_cluster_vip_nwas_abap_pas_ip_address | default('192.168.2.12/32') }}" -# next_hop_type: "virtual_appliance" -# next_hop_ip_address: "{{ hostvars[host_node].ansible_host }}" -# loop: "{{ (groups['nwas_pas'] | default([])) }}" -# loop_control: -# loop_var: host_node -# register: msazure_vnet_subnet_rt_route_sap_netweaver_pas -# when: -# - groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0) +# - name: Ansible MS Azure Route Table append route for SAP NetWeaver PAS HA +# no_log: "{{ __sap_vm_provision_no_log }}" +# register: __sap_vm_provision_task_msazure_vnet_subnet_rt_route_sap_netweaver_pas +# azure.azcollection.azure_rm_route: +# resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" +# route_table_name: "{{ __sap_vm_provision_task_msazure_vnet_subnet_rt_info.route_tables[0].id }}" +# name: "{{ sap_swpm_pas_instance_hostname }}-rt" +# address_prefix: "{{ sap_ha_pacemaker_cluster_vip_nwas_abap_pas_ip_address | default('192.168.2.12/32') }}" +# next_hop_type: "virtual_appliance" +# next_hop_ip_address: "{{ hostvars[host_node].ansible_host }}" +# # Azure credentials +# subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" +# tenant: "{{ sap_vm_provision_msazure_tenant_id }}" +# client_id: "{{ sap_vm_provision_msazure_app_client_id }}" +# secret: "{{ sap_vm_provision_msazure_app_client_secret }}" +# loop: "{{ (groups['nwas_pas'] | default([])) }}" +# loop_control: +# loop_var: host_node +# when: +# - groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0) # - name: Ansible MS Azure Private DNS Records for SAP NetWeaver PAS HA Virtual Hostname +# no_log: "{{ __sap_vm_provision_no_log }}" # azure.azcollection.azure_rm_privatednsrecordset: -# resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" +# # DNS may exist in separate Resource Group. Use empty string var (or default false if undefined) to evaluate to false boolean, and use Python or logic operator +# resource_group: "{{ (sap_vm_provision_msazure_private_dns_resource_group_name | default(false)) or sap_vm_provision_msazure_resource_group_name }}" # zone_name: "{{ hostvars[host_node].sap_vm_provision_dns_root_domain }}" # relative_name: "{{ sap_swpm_pas_instance_hostname }}" # record_type: A # records: # - entry: "{{ (sap_ha_pacemaker_cluster_vip_nwas_abap_pas_ip_address | default('192.168.2.12/32')) | regex_replace('/.*', '') }}" +# # Azure credentials +# subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" +# tenant: "{{ sap_vm_provision_msazure_tenant_id }}" +# client_id: "{{ sap_vm_provision_msazure_app_client_id }}" +# secret: "{{ sap_vm_provision_msazure_app_client_secret }}" # loop: "{{ (groups['nwas_pas'] | default([])) }}" # loop_control: # loop_var: host_node @@ -129,28 +187,41 @@ # - name: Ansible MS Azure Route Table append route for SAP NetWeaver AAS HA +# no_log: "{{ __sap_vm_provision_no_log }}" +# register: __sap_vm_provision_task_msazure_vnet_subnet_rt_route_sap_netweaver_aas # azure.azcollection.azure_rm_route: # resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" -# route_table_name: "{{ msazure_vnet_subnet_rt_info.route_tables[0].id }}" +# route_table_name: "{{ __sap_vm_provision_task_msazure_vnet_subnet_rt_info.route_tables[0].id }}" # name: "{{ sap_swpm_aas_instance_hostname }}-rt" # address_prefix: "{{ sap_ha_pacemaker_cluster_vip_nwas_abap_aas_ip_address | default('192.168.2.13/32') }}" # next_hop_type: "virtual_appliance" # next_hop_ip_address: "{{ hostvars[host_node].ansible_host }}" +# # Azure credentials +# subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" +# tenant: "{{ sap_vm_provision_msazure_tenant_id }}" +# client_id: "{{ sap_vm_provision_msazure_app_client_id }}" +# secret: "{{ sap_vm_provision_msazure_app_client_secret }}" # loop: "{{ (groups['nwas_aas'] | default([])) }}" # loop_control: # loop_var: host_node -# register: msazure_vnet_subnet_rt_route_sap_netweaver_aas # when: # - groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0) # - name: Ansible MS Azure Private DNS Records for SAP NetWeaver AAS HA Virtual Hostname +# no_log: "{{ __sap_vm_provision_no_log }}" # azure.azcollection.azure_rm_privatednsrecordset: -# resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" +# # DNS may exist in separate Resource Group. Use empty string var (or default false if undefined) to evaluate to false boolean, and use Python or logic operator +# resource_group: "{{ (sap_vm_provision_msazure_private_dns_resource_group_name | default(false)) or sap_vm_provision_msazure_resource_group_name }}" # zone_name: "{{ hostvars[host_node].sap_vm_provision_dns_root_domain }}" # relative_name: "{{ sap_swpm_aas_instance_hostname }}" # record_type: A # records: # - entry: "{{ (sap_ha_pacemaker_cluster_vip_nwas_abap_aas_ip_address | default('192.168.2.13/32')) | regex_replace('/.*', '') }}" +# # Azure credentials +# subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" +# tenant: "{{ sap_vm_provision_msazure_tenant_id }}" +# client_id: "{{ sap_vm_provision_msazure_app_client_id }}" +# secret: "{{ sap_vm_provision_msazure_app_client_secret }}" # loop: "{{ (groups['nwas_aas'] | default([])) }}" # loop_control: # loop_var: host_node @@ -159,6 +230,8 @@ - name: MS Azure IAM Role - Definition + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_msazure_iam_role_fencing azure.azcollection.azure_rm_roledefinition: name: "Linux Fence Agent Role" description: "Allows to power-off and start virtual machines" @@ -173,28 +246,44 @@ # - data_actions: # - not_actions: # - not_data_actions: - register: msazure_iam_role_fencing + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" - name: MS Azure - GenericRestClient call to Virtual Machine API to identify Managed Service Identity (MSI) + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_msazure_vm_info_collect azure.azcollection.azure_rm_resource_info: resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" provider: Compute resource_type: virtualMachines resource_name: "{{ host_node }}" - register: msazure_vm_info_collect + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" loop: "{{ groups_merged_list }}" loop_control: loop_var: host_node # Assign to the MSI Object ID (Service Principal ID) - name: MS Azure IAM Role - Assignment to MS Azure Managed Service Identity (MSI) + no_log: "{{ __sap_vm_provision_no_log }}" azure.azcollection.azure_rm_roleassignment: #auth_source: msi role_definition_id: - "{{ msazure_iam_role_fencing.id }}" + "{{ __sap_vm_provision_task_msazure_iam_role_fencing.id }}" scope: "/subscriptions/{{ sap_vm_provision_msazure_subscription_id }}" assignee_object_id: "{{ host_node.response[0].identity.principalId | default(none) }}" - loop: "{{ msazure_vm_info_collect.results }}" + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" + loop: "{{ __sap_vm_provision_task_msazure_vm_info_collect.results }}" loop_control: loop_var: host_node label: "{{ host_node.response[0].name | default(none) }}" # Use default to avoid "Failed to template 'dict object' has no attribute 'response'" @@ -226,24 +315,31 @@ - name: Ansible Task block for provisioning of Load Balancer for High Availability delegate_to: localhost run_once: true + # Using environment, no_log is ineffective and log will show 'EXEC /bin/sh -c 'ENV_VAR=value python3 /AnsiballZ_ansible_module_name.py && sleep 0' + # Therefore do not use environment for secrets, use only for non-sensitive values as this will reduce Ansible Task parameters. environment: - ANSIBLE_AZURE_AUTH_SOURCE: "env" - AZURE_SUBSCRIPTION_ID: "{{ sap_vm_provision_msazure_subscription_id }}" - AZURE_TENANT: "{{ sap_vm_provision_msazure_tenant_id }}" - AZURE_CLIENT_ID: "{{ sap_vm_provision_msazure_app_client_id }}" - AZURE_SECRET: "{{ sap_vm_provision_msazure_app_client_secret }}" + ANSIBLE_AZURE_AUTH_SOURCE: "auto" # Set to auto to use module parameters + # AZURE_SUBSCRIPTION_ID: "{{ sap_vm_provision_msazure_subscription_id }}" + # AZURE_TENANT: "{{ sap_vm_provision_msazure_tenant_id }}" + # AZURE_CLIENT_ID: "{{ sap_vm_provision_msazure_app_client_id }}" + # AZURE_SECRET: "{{ sap_vm_provision_msazure_app_client_secret }}" when: - sap_ha_pacemaker_cluster_msazure_resource_group is defined - (groups["hana_secondary"] is defined and (groups["hana_secondary"] | length>0)) or (groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0)) or (groups["anydb_secondary"] is defined and (groups["anydb_secondary"] | length>0)) block: - name: Gather MS Azure Subnet ID + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_msazure_vnet_subnet_info azure.azcollection.azure_rm_subnet_info: resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" virtual_network_name: "{{ sap_vm_provision_msazure_vnet_name }}" name: "{{ sap_vm_provision_msazure_vnet_subnet_name }}" - register: msazure_vnet_subnet_info - + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" - name: Define Ansible Variables for Azure Load Balancer - VIP for SAP HANA ansible.builtin.set_fact: @@ -253,7 +349,7 @@ name: "lb-vip-hana{{ vip_index_nr }}" private_ip_address: "{{ vip_item | regex_replace('/.*', '') }}" private_ip_allocation_method: "Static" - subnet: "{{ msazure_vnet_subnet_info.subnets[0].id }}" + subnet: "{{ __sap_vm_provision_task_msazure_vnet_subnet_info.subnets[0].id }}" zones: ["1", "2", "3"] # Zone-redundant when: - vip_item | length > 0 @@ -272,7 +368,7 @@ name: "lb-vip-anydb{{ vip_index_nr }}" private_ip_address: "{{ vip_item | regex_replace('/.*', '') }}" private_ip_allocation_method: "Static" - subnet: "{{ msazure_vnet_subnet_info.subnets[0].id }}" + subnet: "{{ __sap_vm_provision_task_msazure_vnet_subnet_info.subnets[0].id }}" zones: ["1", "2", "3"] # Zone-redundant when: - vip_item | length > 0 @@ -291,7 +387,7 @@ name: "lb-vip-nwas{{ vip_index_nr }}" private_ip_address: "{{ vip_item | regex_replace('/.*', '') }}" private_ip_allocation_method: "Static" - subnet: "{{ msazure_vnet_subnet_info.subnets[0].id }}" + subnet: "{{ __sap_vm_provision_task_msazure_vnet_subnet_info.subnets[0].id }}" zones: ["1", "2", "3"] # Zone-redundant when: - vip_item | length > 0 @@ -431,6 +527,8 @@ loop_var: rule_item - name: MS Azure Load Balancer (network L4) - Create NLB for SAP HANA with Virtual IP and Health Probe configuration + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_msazure_lb1a_info azure.azcollection.azure_rm_loadbalancer: resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" name: "lb-sap-hana-ha" # "lb-sap-ha" @@ -440,10 +538,16 @@ - name: lb-backend-pool-hana probes: "{{ (lb_probes1 | default([])) }}" # "{{ (lb_probes1 | default([])) + (lb_probes2 | default([])) }}" load_balancing_rules: "{{ (lb_rules1 | default([])) }}" # "{{ (lb_rules1 | default([])) + (lb_rules2 | default([])) }}" + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" when: (groups["hana_secondary"] is defined and (groups["hana_secondary"]|length>0)) - register: msazure_lb1a_info - name: MS Azure Load Balancer (network L4) - Create NLB for SAP AnyDB with Virtual IP and Health Probe configuration + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_msazure_lb1b_info azure.azcollection.azure_rm_loadbalancer: resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" name: "lb-sap-anydb-ha" # "lb-sap-ha" @@ -453,15 +557,21 @@ - name: lb-backend-pool-anydb probes: "{{ (lb_probes1 | default([])) }}" # "{{ (lb_probes1 | default([])) + (lb_probes2 | default([])) }}" load_balancing_rules: "{{ (lb_rules1 | default([])) }}" # "{{ (lb_rules1 | default([])) + (lb_rules2 | default([])) }}" + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" when: (groups["anydb_secondary"] is defined and (groups["anydb_secondary"]|length>0)) - register: msazure_lb1b_info - name: MS Azure Load Balancer (network L4) - Define Ansible Variable of Load Balancer for Database Server ansible.builtin.set_fact: - msazure_lb1_info: "{{ msazure_lb1a_info if (groups['hana_secondary'] is defined and (groups['hana_secondary']|length>0)) else msazure_lb1b_info if (groups['anydb_secondary'] is defined and (groups['anydb_secondary']|length>0)) }}" + __sap_vm_provision_task_msazure_lb1_info: "{{ __sap_vm_provision_task_msazure_lb1a_info if (groups['hana_secondary'] is defined and (groups['hana_secondary']|length>0)) else __sap_vm_provision_task_msazure_lb1b_info if (groups['anydb_secondary'] is defined and (groups['anydb_secondary']|length>0)) }}" when: (groups["hana_secondary"] is defined and (groups["hana_secondary"]|length>0)) or (groups["anydb_secondary"] is defined and (groups["anydb_secondary"]|length>0)) - name: MS Azure Load Balancer (network L4) - Create NLB for SAP NetWeaver with Virtual IP and Health Probe configuration + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_msazure_lb2_info azure.azcollection.azure_rm_loadbalancer: resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" name: "lb-sap-nwas-ha" @@ -471,26 +581,31 @@ - name: lb-backend-pool-nwas-ascs probes: "{{ (lb_probes2 | default([])) }}" load_balancing_rules: "{{ (lb_rules2 | default([])) }}" + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" when: (groups["nwas_ers"] is defined and (groups["nwas_ers"]|length>0)) - register: msazure_lb2_info - name: Set fact to hold loop variables from include_tasks when SAP HANA HA ansible.builtin.set_fact: - lb_ha_sap_hana: "{{ msazure_lb1_info.state.backend_address_pools | selectattr('name', '==', 'lb-backend-pool-hana') | map(attribute='id') | first }}" + lb_ha_sap_hana: "{{ __sap_vm_provision_task_msazure_lb1_info.state.backend_address_pools | selectattr('name', '==', 'lb-backend-pool-hana') | map(attribute='id') | first }}" when: (groups["hana_secondary"] is defined and (groups["hana_secondary"]|length>0)) - name: Set fact to hold loop variables from include_tasks when SAP AnyDB HA ansible.builtin.set_fact: - lb_ha_sap_anydb: "{{ msazure_lb1_info.state.backend_address_pools | selectattr('name', '==', 'lb-backend-pool-anydb') | map(attribute='id') | first }}" + lb_ha_sap_anydb: "{{ __sap_vm_provision_task_msazure_lb1_info.state.backend_address_pools | selectattr('name', '==', 'lb-backend-pool-anydb') | map(attribute='id') | first }}" when: (groups["anyb_secondary"] is defined and (groups["anydb_secondary"]|length>0)) - name: Set fact to hold loop variables from include_tasks when SAP NetWeaver HA ansible.builtin.set_fact: - lb_ha_sap_nwas: "{{ msazure_lb2_info.state.backend_address_pools | selectattr('name', '==', 'lb-backend-pool-nwas-ascs') | map(attribute='id') | first }}" + lb_ha_sap_nwas: "{{ __sap_vm_provision_task_msazure_lb2_info.state.backend_address_pools | selectattr('name', '==', 'lb-backend-pool-nwas-ascs') | map(attribute='id') | first }}" when: (groups["nwas_ers"] is defined and (groups["nwas_ers"]|length>0)) - name: Update network interfaces for MS Azure VM - for SAP HANA HA with load balancing - register: register_provisioned_vnic1 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_vnic1 azure.azcollection.azure_rm_networkinterface: resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" location: "{{ sap_vm_provision_msazure_location_region }}" @@ -506,6 +621,11 @@ - "{{ lb_ha_sap_hana }}" enable_accelerated_networking: true enable_ip_forwarding: "{{ lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].disable_ip_anti_spoofing }}" # When disable the Anti IP Spoofing = true, then Enable IP Forwarding = true + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" loop: "{{ groups_merged_list }}" loop_control: loop_var: host_node @@ -514,7 +634,8 @@ - groups["hana_secondary"] is defined and (groups["hana_secondary"]|length>0) - name: Update network interfaces for MS Azure VM - for SAP AnyDB HA with load balancing - register: register_provisioned_vnic1 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_vnic1 azure.azcollection.azure_rm_networkinterface: resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" location: "{{ sap_vm_provision_msazure_location_region }}" @@ -530,6 +651,11 @@ - "{{ lb_ha_sap_anydb }}" enable_accelerated_networking: true enable_ip_forwarding: "{{ lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].disable_ip_anti_spoofing }}" # When disable the Anti IP Spoofing = true, then Enable IP Forwarding = true + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" loop: "{{ groups_merged_list }}" loop_control: loop_var: host_node @@ -538,7 +664,8 @@ - groups["anydb_secondary"] is defined and (groups["anydb_secondary"]|length>0) - name: Update network interfaces for MS Azure VM - for SAP NetWeaver HA ASCS/ERS with load balancing - register: register_provisioned_vnic2 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_vnic2 azure.azcollection.azure_rm_networkinterface: resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" location: "{{ sap_vm_provision_msazure_location_region }}" @@ -554,6 +681,11 @@ - "{{ lb_ha_sap_nwas }}" enable_accelerated_networking: true enable_ip_forwarding: "{{ lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].disable_ip_anti_spoofing }}" # When disable the Anti IP Spoofing = true, then Enable IP Forwarding = true + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" loop: "{{ groups_merged_list }}" loop_control: loop_var: host_node diff --git a/roles/sap_vm_provision/tasks/platform_ansible/msazure_vm/post_deployment_execute.yml b/roles/sap_vm_provision/tasks/platform_ansible/msazure_vm/post_deployment_execute.yml index e14f006..36845b8 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/msazure_vm/post_deployment_execute.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/msazure_vm/post_deployment_execute.yml @@ -3,12 +3,14 @@ - name: Ansible Task block for amending Load Balancer ports for High Availability - after provisioning MS Azure VM delegate_to: localhost run_once: true + # Using environment, no_log is ineffective and log will show 'EXEC /bin/sh -c 'ENV_VAR=value python3 /AnsiballZ_ansible_module_name.py && sleep 0' + # Therefore do not use environment for secrets, use only for non-sensitive values as this will reduce Ansible Task parameters. environment: - ANSIBLE_AZURE_AUTH_SOURCE: "env" - AZURE_SUBSCRIPTION_ID: "{{ sap_vm_provision_msazure_subscription_id }}" - AZURE_TENANT: "{{ sap_vm_provision_msazure_tenant_id }}" - AZURE_CLIENT_ID: "{{ sap_vm_provision_msazure_app_client_id }}" - AZURE_SECRET: "{{ sap_vm_provision_msazure_app_client_secret }}" + ANSIBLE_AZURE_AUTH_SOURCE: "auto" # Set to auto to use module parameters + # AZURE_SUBSCRIPTION_ID: "{{ sap_vm_provision_msazure_subscription_id }}" + # AZURE_TENANT: "{{ sap_vm_provision_msazure_tenant_id }}" + # AZURE_CLIENT_ID: "{{ sap_vm_provision_msazure_app_client_id }}" + # AZURE_SECRET: "{{ sap_vm_provision_msazure_app_client_secret }}" when: - sap_ha_pacemaker_cluster_msazure_resource_group is defined - (groups["hana_secondary"] is defined and (groups["hana_secondary"] | length>0)) or (groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0)) or (groups["anydb_secondary"] is defined and (groups["anydb_secondary"] | length>0)) @@ -45,12 +47,17 @@ when: not sap_ha_pacemaker_cluster_healthcheck_nwas_abap_ers_port is defined - name: Gather MS Azure Subnet ID + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_msazure_vnet_subnet_info azure.azcollection.azure_rm_subnet_info: resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" virtual_network_name: "{{ sap_vm_provision_msazure_vnet_name }}" name: "{{ sap_vm_provision_msazure_vnet_subnet_name }}" - register: msazure_vnet_subnet_info - + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" - name: Define Ansible Variables for Azure Load Balancer - VIP for SAP HANA ansible.builtin.set_fact: @@ -60,7 +67,7 @@ name: "lb-vip-hana{{ vip_index_nr }}" private_ip_address: "{{ vip_item | regex_replace('/.*', '') }}" private_ip_allocation_method: "Static" - subnet: "{{ msazure_vnet_subnet_info.subnets[0].id }}" + subnet: "{{ __sap_vm_provision_task_msazure_vnet_subnet_info.subnets[0].id }}" zones: ["1", "2", "3"] # Zone-redundant when: - vip_item | length > 0 @@ -79,7 +86,7 @@ name: "lb-vip-anydb{{ vip_index_nr }}" private_ip_address: "{{ vip_item | regex_replace('/.*', '') }}" private_ip_allocation_method: "Static" - subnet: "{{ msazure_vnet_subnet_info.subnets[0].id }}" + subnet: "{{ __sap_vm_provision_task_msazure_vnet_subnet_info.subnets[0].id }}" zones: ["1", "2", "3"] # Zone-redundant when: - vip_item | length > 0 @@ -98,7 +105,7 @@ name: "lb-vip-nwas{{ vip_index_nr }}" private_ip_address: "{{ vip_item | regex_replace('/.*', '') }}" private_ip_allocation_method: "Static" - subnet: "{{ msazure_vnet_subnet_info.subnets[0].id }}" + subnet: "{{ __sap_vm_provision_task_msazure_vnet_subnet_info.subnets[0].id }}" zones: ["1", "2", "3"] # Zone-redundant when: - vip_item | length > 0 @@ -239,6 +246,8 @@ - name: MS Azure Load Balancer (network L4) - Update NLB for SAP HANA with Virtual IP and Health Probe configuration + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_msazure_lb1_info azure.azcollection.azure_rm_loadbalancer: resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" name: "lb-sap-hana-ha" # "lb-sap-ha" @@ -248,10 +257,16 @@ - name: lb-backend-pool-hana probes: "{{ (lb_probes1 | default([])) }}" # "{{ (lb_probes1 | default([])) + (lb_probes2 | default([])) }}" load_balancing_rules: "{{ (lb_rules1 | default([])) }}" # "{{ (lb_rules1 | default([])) + (lb_rules2 | default([])) }}" + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" when: (groups["hana_secondary"] is defined and (groups["hana_secondary"]|length>0)) - register: msazure_lb1_info - name: MS Azure Load Balancer (network L4) - Update NLB for SAP AnyDB with Virtual IP and Health Probe configuration + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_msazure_lb1_info azure.azcollection.azure_rm_loadbalancer: resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" name: "lb-sap-anydb-ha" # "lb-sap-ha" @@ -261,10 +276,16 @@ - name: lb-backend-pool-anydb probes: "{{ (lb_probes1 | default([])) }}" # "{{ (lb_probes1 | default([])) + (lb_probes2 | default([])) }}" load_balancing_rules: "{{ (lb_rules1 | default([])) }}" # "{{ (lb_rules1 | default([])) + (lb_rules2 | default([])) }}" + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" when: (groups["anydb_secondary"] is defined and (groups["anydb_secondary"]|length>0)) - register: msazure_lb1_info - name: MS Azure Load Balancer (network L4) - Update NLB for SAP NetWeaver with Virtual IP and Health Probe configuration + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_msazure_lb2_info azure.azcollection.azure_rm_loadbalancer: resource_group: "{{ sap_vm_provision_msazure_resource_group_name }}" name: "lb-sap-nwas-ha" @@ -274,5 +295,9 @@ - name: lb-backend-pool-nwas-ascs probes: "{{ (lb_probes2 | default([])) }}" load_balancing_rules: "{{ (lb_rules2 | default([])) }}" + # Azure credentials + subscription_id: "{{ sap_vm_provision_msazure_subscription_id }}" + tenant: "{{ sap_vm_provision_msazure_tenant_id }}" + client_id: "{{ sap_vm_provision_msazure_app_client_id }}" + secret: "{{ sap_vm_provision_msazure_app_client_secret }}" when: (groups["nwas_ers"] is defined and (groups["nwas_ers"]|length>0)) - register: msazure_lb2_info diff --git a/roles/sap_vm_provision/tasks/platform_ansible/ovirt_vm/execute_main.yml b/roles/sap_vm_provision/tasks/platform_ansible/ovirt_vm/execute_main.yml index 61a32eb..adf33e8 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/ovirt_vm/execute_main.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/ovirt_vm/execute_main.yml @@ -1,56 +1,90 @@ --- -- name: OVirt Authentication - ovirt.ovirt.ovirt_auth: - insecure: "{{ sap_vm_provision_ovirt_engine_insecure_bool | default(true) }}" - url: "{{ sap_vm_provision_ovirt_engine_url | default(lookup('env', 'OVIRT_URL')) | default(omit) }}" - hostname: "{{ sap_vm_provision_ovirt_engine_fqdn | default(lookup('env', 'OVIRT_HOSTNAME')) | default(omit) }}" - username: "{{ sap_vm_provision_ovirt_engine_user | default(lookup('env', 'OVIRT_USERNAME')) | default(omit) }}" - password: "{{ sap_vm_provision_ovirt_engine_password | default(lookup('env', 'OVIRT_PASSWORD')) | default(omit) }}" - ca_file: "{{ sap_vm_provision_ovirt_engine_cafile | default(lookup('env', 'OVIRT_CAFILE')) | default(omit) }}" - when: ovirt_auth is undefined or not ovirt_auth - register: ovirt_session - -- name: Set fact to hold loop variables from include_tasks - ansible.builtin.set_fact: - register_provisioned_host_all: [] - -- name: Provision hosts to OVirt - register: register_provisioned_hosts - ansible.builtin.include_tasks: - file: "{{ 'platform_' + sap_vm_provision_iac_type }}/{{ sap_vm_provision_iac_platform }}/execute_provision.yml" - vars: - ovirt_auth: "{{ sap_vm_provision_ovirt_auth }}" - -- name: Add hosts provisioned to the Ansible Inventory - register: register_add_hosts - ansible.builtin.add_host: - name: "{{ add_item[0].host_node }}" - groups: "{{ add_item[0].sap_system_type + '_' if (add_item[0].sap_system_type != '') }}{{ add_item[0].sap_host_type }}" - ansible_host: "{{ add_item[0].reported_devices[0].ips[0].address }}" - ansible_user: "root" - ansible_ssh_private_key_file: "{{ sap_vm_provision_ssh_host_private_key_file_path }}" - ansible_ssh_common_args: -o ConnectTimeout=180 -o ControlMaster=auto -o ControlPersist=3600s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ForwardX11=no - loop: "{{ ansible_play_hosts | map('extract', hostvars, 'register_provisioned_host_all') }}" - loop_control: - label: "{{ add_item[0].host_node }}" - loop_var: add_item +- name: Ansible Task block for looped provisioning of OVirt Virtual Machines + any_errors_fatal: true + # Using environment, no_log is ineffective and log will show 'EXEC /bin/sh -c 'ENV_VAR=value python3 /AnsiballZ_ansible_module_name.py && sleep 0' + # Therefore do not use environment for secrets, use only for non-sensitive values as this will reduce Ansible Task parameters. + # environment: + block: + + - name: OVirt Authentication + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_ovirt_session + ovirt.ovirt.ovirt_auth: + insecure: "{{ sap_vm_provision_ovirt_engine_insecure_bool | default(true) }}" + url: "{{ sap_vm_provision_ovirt_engine_url | default(lookup('env', 'OVIRT_URL')) | default(omit) }}" + hostname: "{{ sap_vm_provision_ovirt_engine_fqdn | default(lookup('env', 'OVIRT_HOSTNAME')) | default(omit) }}" + username: "{{ sap_vm_provision_ovirt_engine_user | default(lookup('env', 'OVIRT_USERNAME')) | default(omit) }}" + password: "{{ sap_vm_provision_ovirt_engine_password | default(lookup('env', 'OVIRT_PASSWORD')) | default(omit) }}" + ca_file: "{{ sap_vm_provision_ovirt_engine_cafile | default(lookup('env', 'OVIRT_CAFILE')) | default(omit) }}" + when: ovirt_auth is undefined or not ovirt_auth + + - name: Set fact to hold loop variables from include_tasks + ansible.builtin.set_fact: + register_provisioned_host_all: [] + + - name: Provision hosts to OVirt + register: __sap_vm_provision_task_provision_host_all_run + ansible.builtin.include_tasks: + file: "{{ 'platform_' + sap_vm_provision_iac_type }}/{{ sap_vm_provision_iac_platform }}/execute_provision.yml" + vars: + ovirt_auth: "{{ sap_vm_provision_ovirt_auth }}" + + - name: Add hosts provisioned to the Ansible Inventory + register: __sap_vm_provision_task_provision_host_all_add + ansible.builtin.add_host: + name: "{{ add_item[0].host_node }}" + groups: "{{ add_item[0].sap_system_type + '_' if (add_item[0].sap_system_type != '') }}{{ add_item[0].sap_host_type }}" + ansible_host: "{{ add_item[0].reported_devices[0].ips[0].address }}" + ansible_user: "root" + ansible_ssh_private_key_file: "{{ sap_vm_provision_ssh_host_private_key_file_path }}" + ansible_ssh_common_args: -o ConnectTimeout=180 -o ControlMaster=auto -o ControlPersist=3600s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ForwardX11=no + loop: "{{ ansible_play_hosts | map('extract', hostvars, 'register_provisioned_host_all') }}" + loop_control: + label: "{{ add_item[0].host_node }}" + loop_var: add_item # Cannot override any variables from extravars input, see https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#understanding-variable-precedence # Ensure no default value exists for any prompted variable before execution of Ansible Playbook -- name: Set fact to hold all inventory hosts in all groups - ansible.builtin.set_fact: - groups_merged_list: "{{ [ [ groups['hana_primary'] | default([]) ] , [ groups['hana_secondary'] | default([]) ] , [ groups['nwas_ascs'] | default([]) ] , [ groups['nwas_ers'] | default([]) ] , [ groups['nwas_pas'] | default([]) ] , [ groups['nwas_aas'] | default([]) ] ] | flatten | select() }}" + - name: Set fact to hold all inventory hosts in all groups + ansible.builtin.set_fact: + groups_merged_list: "{{ [ [ groups['hana_primary'] | default([]) ] , [ groups['hana_secondary'] | default([]) ] , [ groups['nwas_ascs'] | default([]) ] , [ groups['nwas_ers'] | default([]) ] , [ groups['nwas_pas'] | default([]) ] , [ groups['nwas_aas'] | default([]) ] ] | flatten | select() }}" -- name: Set Ansible Vars - register: register_set_ansible_vars - ansible.builtin.include_tasks: - file: common/set_ansible_vars.yml + - name: Set Ansible Vars + register: __sap_vm_provision_task_ansible_vars_set + ansible.builtin.include_tasks: + file: common/set_ansible_vars.yml # - ansible.builtin.debug: - # var: register_add_hosts.results + # var: __sap_vm_provision_task_provision_host_all_add.results + + rescue: + # This requires no_log set on each Ansible Task, and not set on the Ansible Task Block + # This requires an Ansible Task Block containing the Ansible Tasks for calling + # Infrastructure Platform APIs (via Ansible Modules) + - name: Show errors in task outputs + ansible.builtin.fail: + msg: "{{ lookup('ansible.builtin.vars', loop_item) }}" + loop: + - __sap_vm_provision_task_provision_host_all_run + - __sap_vm_provision_task_provision_host_single_check_exists + - __sap_vm_provision_task_ovirt_os + - __sap_vm_provision_task_provision_host_single_boot_disk + - __sap_vm_provision_task_provision_host_single + - __sap_vm_provision_task_provision_host_single_info + - __sap_vm_provision_task_provision_host_single_volumes + - __sap_vm_provision_task_provision_host_all_add + loop_control: + loop_var: loop_item + index_var: loop_item_index + label: "{{ 'Variable No. ' + (loop_item_index | string) }}" + when: + - lookup('ansible.builtin.vars', loop_item, default='') | length > 0 + - not lookup('ansible.builtin.vars', loop_item, default='') is skipped + - lookup('ansible.builtin.vars', loop_item, default='') is failed + - name: Ansible Task block to execute on target inventory hosts delegate_to: "{{ inventory_hostname }}" @@ -69,33 +103,33 @@ name: "{{ inventory_hostname_short }}" - name: Set /etc/hosts - register: register_etc_hosts_file + register: __sap_vm_provision_task_os_etc_hosts ansible.builtin.include_tasks: file: common/set_etc_hosts.yml - name: Set /etc/hosts for HA - register: register_etc_hosts_file_ha + register: __sap_vm_provision_task_os_etc_hosts_ha ansible.builtin.include_tasks: file: common/set_etc_hosts_ha.yml when: - (groups["hana_secondary"] is defined and (groups["hana_secondary"] | length>0)) or (groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0)) or (groups["anydb_secondary"] is defined and (groups["anydb_secondary"] | length>0)) - name: Set /etc/hosts for Scale-Out - register: register_etc_hosts_file_scaleout + register: __sap_vm_provision_task_os_etc_hosts_scaleout ansible.builtin.include_tasks: file: common/set_etc_hosts_scaleout.yml when: - - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_hana_scaleout_active_coordinator is defined or sap_hana_scaleout_active_worker is defined or sap_hana_scaleout_standby is defined) + - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined or sap_vm_provision_calculate_sap_hana_scaleout_active_worker is defined or sap_vm_provision_calculate_sap_hana_scaleout_standby is defined) - name: Set vars for sap_storage_setup Ansible Role - register: register_ansible_vars_storage + register: __sap_vm_provision_task_ansible_vars_storage ansible.builtin.include_tasks: file: common/set_ansible_vars_storage.yml - - name: Register Package Repositories - ansible.builtin.include_tasks: - file: common/register_os.yml - - name: Register Web Forward Proxy ansible.builtin.include_tasks: file: common/register_proxy.yml + + - name: Register Package Repositories + ansible.builtin.include_tasks: + file: common/register_os.yml diff --git a/roles/sap_vm_provision/tasks/platform_ansible/ovirt_vm/execute_provision.yml b/roles/sap_vm_provision/tasks/platform_ansible/ovirt_vm/execute_provision.yml index af1db50..a5efbb1 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/ovirt_vm/execute_provision.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/ovirt_vm/execute_provision.yml @@ -1,26 +1,31 @@ --- # The tasks in this file are executed in a loop over the defined hosts +- name: Ensure short hostname is not longer than 13 characters (see SAP Note 611361) + ansible.builtin.assert: + that: (inventory_hostname | length | int) <= (13 | int) + fail_msg: "FAIL: The length of the hostname is {{ inventory_hostname | length | int }} but must be less or equal to 13 characters!" + # When SAP HANA Scale-Out is used, if host name is not in original specifications then strip suffix node number from host name - name: Set fact when performing SAP HANA Scale-Out ansible.builtin.set_fact: scaleout_origin_host_spec: "{{ inventory_hostname | regex_replace('^(.+?)\\d*$', '\\1') }}" when: - - sap_hana_scaleout_active_coordinator is defined + - sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined - not inventory_hostname in lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan].keys() - name: Check if VM exists - register: register_check_vm_exists + register: __sap_vm_provision_task_provision_host_single_check_exists ovirt.ovirt.ovirt_vm_info: - auth: "{{ ovirt_session.ansible_facts.ovirt_auth }}" pattern: name={{ inventory_hostname }} and cluster={{ sap_vm_provision_ovirt_hypervisor_cluster_name }} + auth: "{{ __sap_vm_provision_task_ovirt_session.ansible_facts.ovirt_auth }}" # For later check if the provided OS name is actually available - name: Check available OS names in OVirt + register: __sap_vm_provision_task_ovirt_os ovirt.ovirt.ovirt_vm_os_info: - auth: "{{ ovirt_session.ansible_facts.ovirt_auth }}" - register: register_ovirt_available_os + auth: "{{ __sap_vm_provision_task_ovirt_session.ansible_facts.ovirt_auth }}" # VM creation block: @@ -28,34 +33,34 @@ # - name: Block that provisions the VM when: - - register_check_vm_exists.ovirt_vms is defined - - register_check_vm_exists.ovirt_vms | length == 0 + - __sap_vm_provision_task_provision_host_single_check_exists.ovirt_vms is defined + - __sap_vm_provision_task_provision_host_single_check_exists.ovirt_vms | length == 0 block: - name: For Kickstart, provision Virtual Disk boot volume + register: __sap_vm_provision_task_provision_host_single_boot_disk ovirt.ovirt.ovirt_disk: - auth: "{{ ovirt_session.ansible_facts.ovirt_auth }}" name: "{{ inventory_hostname }}-vol_os" size: "{{ sap_vm_provision_ovirt_vm_kickstart_definition.boot_disk.size }}" format: "{{ sap_vm_provision_ovirt_vm_kickstart_definition.boot_disk.format }}" storage_domain: "{{ sap_vm_provision_ovirt_hypervisor_cluster_storage_domain_name }}" # Hypervisor Cluster's attached storage domain wait: true + auth: "{{ __sap_vm_provision_task_ovirt_session.ansible_facts.ovirt_auth }}" when: - sap_vm_provision_ovirt_vm_kickstart_definition is defined - sap_vm_provision_ovirt_vm_kickstart_definition | length > 0 - sap_vm_provision_ovirt_vm_template_name is not defined or sap_vm_provision_ovirt_vm_template_name | length == 0 - register: register_provisioned_boot_disk - until: register_provisioned_boot_disk.disk.status == 'ok' + until: __sap_vm_provision_task_provision_host_single_boot_disk.disk.status == 'ok' retries: 600 - name: Merge disk provisioning result with disk attachment definition ansible.builtin.set_fact: - merge_provisioned_boot_disk_fact: "{{ register_provisioned_boot_disk.disk | ansible.builtin.combine(sap_vm_provision_ovirt_vm_kickstart_definition.boot_disk) }}" + merge_provisioned_boot_disk_fact: "{{ __sap_vm_provision_task_provision_host_single_boot_disk.disk | ansible.builtin.combine(sap_vm_provision_ovirt_vm_kickstart_definition.boot_disk) }}" when: - sap_vm_provision_ovirt_vm_kickstart_definition is defined - sap_vm_provision_ovirt_vm_kickstart_definition | length > 0 - - register_provisioned_boot_disk is defined + - __sap_vm_provision_task_provision_host_single_boot_disk is defined - name: Convert disk provisioning result to disk attachment list ansible.builtin.set_fact: @@ -63,13 +68,12 @@ when: - sap_vm_provision_ovirt_vm_kickstart_definition is defined - sap_vm_provision_ovirt_vm_kickstart_definition | length > 0 - - register_provisioned_boot_disk is defined + - __sap_vm_provision_task_provision_host_single_boot_disk is defined - name: Provision OVirt Virtual Machine - register: register_provisioned_host_single + register: __sap_vm_provision_task_provision_host_single ovirt.ovirt.ovirt_vm: - auth: "{{ ovirt_session.ansible_facts.ovirt_auth }}" ## Virtual Machine target Hypervisor definition cluster: "{{ sap_vm_provision_ovirt_hypervisor_cluster_name }}" # Hypervisor Cluster @@ -143,8 +147,10 @@ # UI option: "Rollback this configuration during reboots" volatile: true + auth: "{{ __sap_vm_provision_task_ovirt_session.ansible_facts.ovirt_auth }}" + # Report VM back only after it is done creating the clone image. - until: register_provisioned_host_single.vm.status != "image_locked" + until: __sap_vm_provision_task_provision_host_single.vm.status != "image_locked" retries: 120 delay: 5 @@ -153,21 +159,20 @@ - name: Start the VM, if not running ovirt.ovirt.ovirt_vm: - auth: "{{ ovirt_session.ansible_facts.ovirt_auth }}" name: "{{ inventory_hostname }}" state: running + auth: "{{ __sap_vm_provision_task_ovirt_session.ansible_facts.ovirt_auth }}" - name: Remove installation ISO from the config ovirt.ovirt.ovirt_vm: - auth: "{{ ovirt_session.ansible_facts.ovirt_auth }}" name: "{{ inventory_hostname }}" cd_iso: "" + auth: "{{ __sap_vm_provision_task_ovirt_session.ansible_facts.ovirt_auth }}" when: sap_vm_provision_ovirt_vm_kickstart_definition is defined - name: Check VM status - register: register_provisioned_host_single_info + register: __sap_vm_provision_task_provision_host_single_info ovirt.ovirt.ovirt_vm_info: - auth: "{{ ovirt_session.ansible_facts.ovirt_auth }}" pattern: name={{ inventory_hostname }} and cluster={{ sap_vm_provision_ovirt_hypervisor_cluster_name }} all_content: true fetch_nested: true @@ -175,20 +180,21 @@ - ips - name - applications + auth: "{{ __sap_vm_provision_task_ovirt_session.ansible_facts.ovirt_auth }}" # Allow for 15 minutes until the VM reports devices, which include the IP and # are required in following tasks. - until: register_provisioned_host_single_info.ovirt_vms[0].reported_devices | length > 0 + until: __sap_vm_provision_task_provision_host_single_info.ovirt_vms[0].reported_devices | length > 0 retries: 180 delay: 5 - name: Create fact for delegate host IP ansible.builtin.set_fact: - provisioned_private_ip: "{{ register_provisioned_host_single_info.ovirt_vms[0].reported_devices[0].ips[0].address }}" + provisioned_private_ip: "{{ __sap_vm_provision_task_provision_host_single_info.ovirt_vms[0].reported_devices[0].ips[0].address }}" - name: Collect only facts about hardware - register: host_disks_info + register: __sap_vm_provision_task_ansible_facts_host_disks_info ansible.builtin.setup: gather_subset: - hardware @@ -206,14 +212,14 @@ #- name: Debug Ansible Facts devices used list # ansible.builtin.debug: -# msg: "{{ host_disks_info.ansible_facts.ansible_device_links.ids.keys() | list }}" +# msg: "{{ __sap_vm_provision_task_ansible_facts_host_disks_info.ansible_facts.ansible_device_links.ids.keys() | list }}" - name: Set fact for available storage volume device names ansible.builtin.set_fact: available_volumes: |- {% set letters = 'bcdefghijklmnopqrstuvwxyz' %} - {% set ansible_facts_devices_used_list = host_disks_info.ansible_facts.ansible_device_links.ids.keys() | list %} + {% set ansible_facts_devices_used_list = __sap_vm_provision_task_ansible_facts_host_disks_info.ansible_facts.ansible_device_links.ids.keys() | list %} {% set volumes = [] %} {%- for letter in letters -%} {% for device in ansible_facts_devices_used_list -%} @@ -267,8 +273,8 @@ # The volume creation task requires the above task to define the parameter # which contains the calculated unique device names. - name: Provision Virtual Disk volumes for OVirt VM filesystems + register: __sap_vm_provision_task_provision_host_single_volumes ovirt.ovirt.ovirt_disk: - auth: "{{ ovirt_session.ansible_facts.ovirt_auth }}" name: "{{ inventory_hostname }}-vol_{{ vol_item.name }}" vm_name: "{{ inventory_hostname }}" size: "{{ vol_item.size }}GiB" @@ -277,6 +283,7 @@ storage_domain: "{{ sap_vm_provision_ovirt_hypervisor_cluster_storage_domain_name }}" # Hypervisor Cluster's attached storage domain wait: true bootable: false + auth: "{{ __sap_vm_provision_task_ovirt_session.ansible_facts.ovirt_auth }}" loop: "{{ filesystem_volume_map }}" loop_control: loop_var: vol_item @@ -285,13 +292,12 @@ when: - vol_item.fstype is defined - vol_item.size > 0 - register: volume_provisioning - name: Append loop value to register ansible.builtin.set_fact: - register_provisioned_host_single: "{{ register_provisioned_host_single_info.ovirt_vms[0] | combine( { 'host_node' : inventory_hostname } , { 'sap_host_type' : lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_host_type } , { 'sap_system_type' : (lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_system_type | default('')) } ) }}" + __sap_vm_provision_task_provision_host_single: "{{ __sap_vm_provision_task_provision_host_single_info.ovirt_vms[0] | combine( { 'host_node' : inventory_hostname } , { 'sap_host_type' : lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_host_type } , { 'sap_system_type' : (lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_system_type | default('')) } ) }}" - name: Append output to merged register ansible.builtin.set_fact: - register_provisioned_host_all: "{{ register_provisioned_host_all + [register_provisioned_host_single] }}" + register_provisioned_host_all: "{{ register_provisioned_host_all + [__sap_vm_provision_task_provision_host_single] }}" diff --git a/roles/sap_vm_provision/tasks/platform_ansible/vmware_vm/execute_main.yml b/roles/sap_vm_provision/tasks/platform_ansible/vmware_vm/execute_main.yml index 1d95370..c340434 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/vmware_vm/execute_main.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/vmware_vm/execute_main.yml @@ -1,6 +1,10 @@ --- - name: Ansible Task block for looped provisioning of VMware VMs + any_errors_fatal: true + # Using environment, no_log is ineffective and log will show 'EXEC /bin/sh -c 'ENV_VAR=value python3 /AnsiballZ_ansible_module_name.py && sleep 0' + # Therefore do not use environment for secrets, use only for non-sensitive values as this will reduce Ansible Task parameters. + # environment: block: - name: Set fact to hold loop variables from include_tasks @@ -10,30 +14,23 @@ # Use vmware.vmware_rest Ansible Collection for VMware vCenter REST API, for VMware vSphere 7.0.2+ # Does not use community.vmware Ansible Collection for legacy pyvmomi Python Package for VMware vCenter SOAP API - # Use of environment avoids the need for variables in each Ansible Module call - # Hypervisor Control Plane credentials - # vcenter_hostname: "{{ sap_vm_provision_vmware_vcenter_hostname | default(lookup('env', 'VMWARE_HOST')) | default(omit) }}" - # vcenter_validate_certs: "{{ (sap_vm_provision_vmware_vcenter_validate_certs_bool | default(lookup('env', 'VMWARE_VALIDATE_CERTS'))) | bool | default(false) }}" - # vcenter_username: "{{ sap_vm_provision_vmware_vcenter_user | default(lookup('env', 'VMWARE_USER')) | default(omit) }}" - # vcenter_password: "{{ sap_vm_provision_vmware_vcenter_password | default(lookup('env', 'VMWARE_PASSWORD')) | default(omit) }}" - - name: Provision hosts to VMware vSphere - register: register_provisioned_hosts + register: __sap_vm_provision_task_provision_host_all_run ansible.builtin.include_tasks: file: "{{ 'platform_' + sap_vm_provision_iac_type }}/{{ sap_vm_provision_iac_platform }}/execute_provision.yml" - apply: - environment: - VMWARE_HOST: "{{ sap_vm_provision_vmware_vcenter_hostname | default(lookup('env', 'VMWARE_HOST')) | default(omit) }}" - VMWARE_VALIDATE_CERTS: "{{ (sap_vm_provision_vmware_vcenter_validate_certs_bool | default(lookup('env', 'VMWARE_VALIDATE_CERTS'))) | bool | default(false) }}" - VMWARE_USER: "{{ sap_vm_provision_vmware_vcenter_user | default(lookup('env', 'VMWARE_USER')) | default(omit) }}" - VMWARE_PASSWORD: "{{ sap_vm_provision_vmware_vcenter_password | default(lookup('env', 'VMWARE_PASSWORD')) | default(omit) }}" + # apply: + # environment: + # VMWARE_HOST: "{{ sap_vm_provision_vmware_vcenter_hostname | default(lookup('env', 'VMWARE_HOST')) | default(omit) }}" + # VMWARE_VALIDATE_CERTS: "{{ (sap_vm_provision_vmware_vcenter_validate_certs_bool | default(lookup('env', 'VMWARE_VALIDATE_CERTS'))) | bool | default(false) }}" + # VMWARE_USER: "{{ sap_vm_provision_vmware_vcenter_user | default(lookup('env', 'VMWARE_USER')) | default(omit) }}" + # VMWARE_PASSWORD: "{{ sap_vm_provision_vmware_vcenter_password | default(lookup('env', 'VMWARE_PASSWORD')) | default(omit) }}" - name: Add hosts provisioned to the Ansible Inventory - register: register_add_hosts + register: __sap_vm_provision_task_provision_host_all_add ansible.builtin.add_host: name: "{{ add_item[0].host_node }}" groups: "{{ add_item[0].sap_system_type + '_' if (add_item[0].sap_system_type != '') }}{{ add_item[0].sap_host_type }}" - ansible_host: "{{ add_item[0].vmware_vm_network_info.ansible_facts.ansible_default_ipv4.address }}" + ansible_host: "{{ add_item[0].__sap_vm_provision_task_vmware_vm_network_info.ansible_facts.ansible_default_ipv4.address }}" ansible_user: "root" ansible_ssh_private_key_file: "{{ sap_vm_provision_ssh_host_private_key_file_path }}" ansible_ssh_common_args: -o ConnectTimeout=180 -o ControlMaster=auto -o ControlPersist=3600s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ForwardX11=no -o ProxyCommand='ssh -W %h:%p {{ sap_vm_provision_bastion_user }}@{{ sap_vm_provision_bastion_public_ip }} -p {{ sap_vm_provision_bastion_ssh_port }} -i {{ sap_vm_provision_ssh_bastion_private_key_file_path }} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' @@ -51,12 +48,47 @@ groups_merged_list: "{{ [ [ groups['hana_primary'] | default([]) ] , [ groups['hana_secondary'] | default([]) ] , [ groups['nwas_ascs'] | default([]) ] , [ groups['nwas_ers'] | default([]) ] , [ groups['nwas_pas'] | default([]) ] , [ groups['nwas_aas'] | default([]) ] ] | flatten | select() }}" - name: Set Ansible Vars - register: register_set_ansible_vars + register: __sap_vm_provision_task_ansible_vars_set ansible.builtin.include_tasks: file: common/set_ansible_vars.yml # - ansible.builtin.debug: - # var: register_add_hosts.results + # var: __sap_vm_provision_task_provision_host_all_add.results + + rescue: + # This requires no_log set on each Ansible Task, and not set on the Ansible Task Block + # This requires an Ansible Task Block containing the Ansible Tasks for calling + # Infrastructure Platform APIs (via Ansible Modules) + - name: Show errors in task outputs + ansible.builtin.fail: + msg: "{{ lookup('ansible.builtin.vars', loop_item) }}" + loop: + - __sap_vm_provision_task_provision_host_all_run + - __sap_vm_provision_task_vmware_vm_folder + - __sap_vm_provision_task_vmware_vm_cluster + - __sap_vm_provision_task_vmware_vm_cluster_host + - __sap_vm_provision_task_vmware_vm_cluster_datastore + - __sap_vm_provision_task_vmware_vm_content_library + - __sap_vm_provision_task_vmware_vm_content_library_items + - __sap_vm_provision_task_provision_host_single_check_exists + - __sap_vm_provision_task_provision_host_single + - __sap_vm_provision_task_provision_host_single_info + - __sap_vm_provision_task_vmware_vm_power_info + - __sap_vm_provision_task_vmware_vm_info + - __sap_vm_provision_task_vmware_vm_nic_info + - __sap_vm_provision_task_ansible_facts_host_disks_info + - __sap_vm_provision_task_vmware_vm_network_info + - __sap_vm_provision_task_provision_host_single_volumes + - __sap_vm_provision_task_provision_host_all_add + loop_control: + loop_var: loop_item + index_var: loop_item_index + label: "{{ 'Variable No. ' + (loop_item_index | string) }}" + when: + - lookup('ansible.builtin.vars', loop_item, default='') | length > 0 + - not lookup('ansible.builtin.vars', loop_item, default='') is skipped + - lookup('ansible.builtin.vars', loop_item, default='') is failed + - name: Ansible Task block to execute on target inventory hosts delegate_to: "{{ inventory_hostname }}" @@ -75,33 +107,33 @@ name: "{{ inventory_hostname_short }}" - name: Set /etc/hosts - register: register_etc_hosts_file + register: __sap_vm_provision_task_os_etc_hosts ansible.builtin.include_tasks: file: common/set_etc_hosts.yml - name: Set /etc/hosts for HA - register: register_etc_hosts_file_ha + register: __sap_vm_provision_task_os_etc_hosts_ha ansible.builtin.include_tasks: file: common/set_etc_hosts_ha.yml when: - (groups["hana_secondary"] is defined and (groups["hana_secondary"] | length>0)) or (groups["nwas_ers"] is defined and (groups["nwas_ers"] | length>0)) or (groups["anydb_secondary"] is defined and (groups["anydb_secondary"] | length>0)) - name: Set /etc/hosts for Scale-Out - register: register_etc_hosts_file_scaleout + register: __sap_vm_provision_task_os_etc_hosts_scaleout ansible.builtin.include_tasks: file: common/set_etc_hosts_scaleout.yml when: - - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_hana_scaleout_active_coordinator is defined or sap_hana_scaleout_active_worker is defined or sap_hana_scaleout_standby is defined) + - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined or sap_vm_provision_calculate_sap_hana_scaleout_active_worker is defined or sap_vm_provision_calculate_sap_hana_scaleout_standby is defined) - name: Set vars for sap_storage_setup Ansible Role - register: register_ansible_vars_storage + register: __sap_vm_provision_task_ansible_vars_storage ansible.builtin.include_tasks: file: common/set_ansible_vars_storage.yml - - name: Register Package Repositories - ansible.builtin.include_tasks: - file: common/register_os.yml - - name: Register Web Forward Proxy ansible.builtin.include_tasks: file: common/register_proxy.yml + + - name: Register Package Repositories + ansible.builtin.include_tasks: + file: common/register_os.yml diff --git a/roles/sap_vm_provision/tasks/platform_ansible/vmware_vm/execute_provision.yml b/roles/sap_vm_provision/tasks/platform_ansible/vmware_vm/execute_provision.yml index ae2c144..4f8d31e 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible/vmware_vm/execute_provision.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible/vmware_vm/execute_provision.yml @@ -1,6 +1,12 @@ --- # The tasks in this file are executed in a loop over the defined hosts +- name: Ensure short hostname is not longer than 13 characters (see SAP Note 611361) + ansible.builtin.assert: + that: (inventory_hostname | length | int) <= (13 | int) + fail_msg: "FAIL: The length of the hostname is {{ inventory_hostname | length | int }} but must be less or equal to 13 characters!" + + # Use vmware.vmware_rest Ansible Collection for VMware vCenter REST API, for VMware vSphere 7.0.2+ # Does not use community.vmware Ansible Collection for legacy pyvmomi Python Package for VMware vCenter SOAP API @@ -10,80 +16,129 @@ ansible.builtin.set_fact: scaleout_origin_host_spec: "{{ inventory_hostname | regex_replace('^(.+?)\\d*$', '\\1') }}" when: - - sap_hana_scaleout_active_coordinator is defined + - sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined - not inventory_hostname in lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan].keys() - name: Identify VM Folder - register: register_vmware_vm_folder + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_vmware_vm_folder vmware.vmware_rest.vcenter_folder_info: names: "{{ sap_vm_provision_vmware_vm_folder_name }}" type: VIRTUAL_MACHINE + # Hypervisor Control Plane credentials + vcenter_hostname: "{{ sap_vm_provision_vmware_vcenter_hostname | default(lookup('env', 'VMWARE_HOST')) | default(omit) }}" + vcenter_validate_certs: "{{ (sap_vm_provision_vmware_vcenter_validate_certs_bool | default(lookup('env', 'VMWARE_VALIDATE_CERTS'))) | bool | default(false) }}" + vcenter_username: "{{ sap_vm_provision_vmware_vcenter_user | default(lookup('env', 'VMWARE_USER')) | default(omit) }}" + vcenter_password: "{{ sap_vm_provision_vmware_vcenter_password | default(lookup('env', 'VMWARE_PASSWORD')) | default(omit) }}" - name: Identify Datacenter Cluster - register: register_vmware_vm_cluster + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_vmware_vm_cluster vmware.vmware_rest.vcenter_cluster_info: names: "{{ sap_vm_provision_vmware_vm_cluster_name }}" + # Hypervisor Control Plane credentials + vcenter_hostname: "{{ sap_vm_provision_vmware_vcenter_hostname | default(lookup('env', 'VMWARE_HOST')) | default(omit) }}" + vcenter_validate_certs: "{{ (sap_vm_provision_vmware_vcenter_validate_certs_bool | default(lookup('env', 'VMWARE_VALIDATE_CERTS'))) | bool | default(false) }}" + vcenter_username: "{{ sap_vm_provision_vmware_vcenter_user | default(lookup('env', 'VMWARE_USER')) | default(omit) }}" + vcenter_password: "{{ sap_vm_provision_vmware_vcenter_password | default(lookup('env', 'VMWARE_PASSWORD')) | default(omit) }}" - name: Identify Host in Datacenter Cluster - register: register_vmware_vm_cluster_host + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_vmware_vm_cluster_host vmware.vmware_rest.vcenter_host_info: names: "{{ sap_vm_provision_vmware_vm_cluster_host_name }}" + # Hypervisor Control Plane credentials + vcenter_hostname: "{{ sap_vm_provision_vmware_vcenter_hostname | default(lookup('env', 'VMWARE_HOST')) | default(omit) }}" + vcenter_validate_certs: "{{ (sap_vm_provision_vmware_vcenter_validate_certs_bool | default(lookup('env', 'VMWARE_VALIDATE_CERTS'))) | bool | default(false) }}" + vcenter_username: "{{ sap_vm_provision_vmware_vcenter_user | default(lookup('env', 'VMWARE_USER')) | default(omit) }}" + vcenter_password: "{{ sap_vm_provision_vmware_vcenter_password | default(lookup('env', 'VMWARE_PASSWORD')) | default(omit) }}" - name: Identify Datastore - register: register_vmware_vm_cluster_datastore + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_vmware_vm_cluster_datastore vmware.vmware_rest.vcenter_datastore_info: names: "{{ sap_vm_provision_vmware_vm_cluster_datastore_name }}" + # Hypervisor Control Plane credentials + vcenter_hostname: "{{ sap_vm_provision_vmware_vcenter_hostname | default(lookup('env', 'VMWARE_HOST')) | default(omit) }}" + vcenter_validate_certs: "{{ (sap_vm_provision_vmware_vcenter_validate_certs_bool | default(lookup('env', 'VMWARE_VALIDATE_CERTS'))) | bool | default(false) }}" + vcenter_username: "{{ sap_vm_provision_vmware_vcenter_user | default(lookup('env', 'VMWARE_USER')) | default(omit) }}" + vcenter_password: "{{ sap_vm_provision_vmware_vcenter_password | default(lookup('env', 'VMWARE_PASSWORD')) | default(omit) }}" - name: Identify Content Library (to store VM Template) - register: register_vmware_vm_content_library + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_vmware_vm_content_library vmware.vmware_rest.content_locallibrary: name: "{{ sap_vm_provision_vmware_vm_content_library_name }}" + # Hypervisor Control Plane credentials + vcenter_hostname: "{{ sap_vm_provision_vmware_vcenter_hostname | default(lookup('env', 'VMWARE_HOST')) | default(omit) }}" + vcenter_validate_certs: "{{ (sap_vm_provision_vmware_vcenter_validate_certs_bool | default(lookup('env', 'VMWARE_VALIDATE_CERTS'))) | bool | default(false) }}" + vcenter_username: "{{ sap_vm_provision_vmware_vcenter_user | default(lookup('env', 'VMWARE_USER')) | default(omit) }}" + vcenter_password: "{{ sap_vm_provision_vmware_vcenter_password | default(lookup('env', 'VMWARE_PASSWORD')) | default(omit) }}" - name: List all items in Content Library - register: register_vmware_vm_content_library_items + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_vmware_vm_content_library_items vmware.vmware_rest.content_library_item_info: - library_id: "{{ register_vmware_vm_content_library.id }}" + library_id: "{{ __sap_vm_provision_task_vmware_vm_content_library.id }}" + # Hypervisor Control Plane credentials + vcenter_hostname: "{{ sap_vm_provision_vmware_vcenter_hostname | default(lookup('env', 'VMWARE_HOST')) | default(omit) }}" + vcenter_validate_certs: "{{ (sap_vm_provision_vmware_vcenter_validate_certs_bool | default(lookup('env', 'VMWARE_VALIDATE_CERTS'))) | bool | default(false) }}" + vcenter_username: "{{ sap_vm_provision_vmware_vcenter_user | default(lookup('env', 'VMWARE_USER')) | default(omit) }}" + vcenter_password: "{{ sap_vm_provision_vmware_vcenter_password | default(lookup('env', 'VMWARE_PASSWORD')) | default(omit) }}" - name: Identify VMware Template ID ansible.builtin.set_fact: - vmware_vm_template_id: "{{ (register_vmware_vm_content_library_items.value | selectattr('type', '==', 'vm-template') | selectattr('name', '==', sap_vm_provision_vmware_vm_template_name) | first).id }}" + vmware_vm_template_id: "{{ (__sap_vm_provision_task_vmware_vm_content_library_items.value | selectattr('type', '==', 'vm-template') | selectattr('name', '==', sap_vm_provision_vmware_vm_template_name) | first).id }}" - name: Check if VM exists - register: register_check_vm_exists + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_check_exists vmware.vmware_rest.vcenter_vm_info: names: "{{ inventory_hostname }}" + # Hypervisor Control Plane credentials + vcenter_hostname: "{{ sap_vm_provision_vmware_vcenter_hostname | default(lookup('env', 'VMWARE_HOST')) | default(omit) }}" + vcenter_validate_certs: "{{ (sap_vm_provision_vmware_vcenter_validate_certs_bool | default(lookup('env', 'VMWARE_VALIDATE_CERTS'))) | bool | default(false) }}" + vcenter_username: "{{ sap_vm_provision_vmware_vcenter_user | default(lookup('env', 'VMWARE_USER')) | default(omit) }}" + vcenter_password: "{{ sap_vm_provision_vmware_vcenter_password | default(lookup('env', 'VMWARE_PASSWORD')) | default(omit) }}" - name: Set VM ID - when: not register_check_vm_exists.value | length == 0 + when: not __sap_vm_provision_task_provision_host_single_check_exists.value | length == 0 ansible.builtin.set_fact: - register_vmware_vm_cluster_host_id: "{{ register_check_vm_exists.value[0].vm }}" # VM ID + __sap_vm_provision_task_vmware_vm_cluster_host_id: "{{ __sap_vm_provision_task_provision_host_single_check_exists.value[0].vm }}" # VM ID - name: Check VM status - register: register_provisioned_host_single_info - when: not register_check_vm_exists.value | length == 0 + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_info + when: not __sap_vm_provision_task_provision_host_single_check_exists.value | length == 0 vmware.vmware_rest.vcenter_vm: - vm: "{{ register_vmware_vm_cluster_host_id }}" # VM ID + vm: "{{ __sap_vm_provision_task_vmware_vm_cluster_host_id }}" # VM ID + # Hypervisor Control Plane credentials + vcenter_hostname: "{{ sap_vm_provision_vmware_vcenter_hostname | default(lookup('env', 'VMWARE_HOST')) | default(omit) }}" + vcenter_validate_certs: "{{ (sap_vm_provision_vmware_vcenter_validate_certs_bool | default(lookup('env', 'VMWARE_VALIDATE_CERTS'))) | bool | default(false) }}" + vcenter_username: "{{ sap_vm_provision_vmware_vcenter_user | default(lookup('env', 'VMWARE_USER')) | default(omit) }}" + vcenter_password: "{{ sap_vm_provision_vmware_vcenter_password | default(lookup('env', 'VMWARE_PASSWORD')) | default(omit) }}" # VM creation block: # This block is run when the VM does not exist yet. - name: Block that provisions the VM - when: register_check_vm_exists.value | length == 0 + when: __sap_vm_provision_task_provision_host_single_check_exists.value | length == 0 block: # Deploy a Virtual Machine from a VM Template in a Content Library # Doc: https://docs.vmware.com/en/VMware-vSphere/7.0/com.vmware.vsphere.vm_admin.doc/GUID-6EA309BC-9113-449C-B668-ACBB363485C3.html - name: Provision VMware Virtual Machine based upon the VM Template - register: register_provisioned_host_single + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single vmware.vmware_rest.vcenter_vmtemplate_libraryitems: ## Virtual Machine target Hypervisor definition placement: - folder: "{{ (register_vmware_vm_folder.value | first).folder }}" + folder: "{{ (__sap_vm_provision_task_vmware_vm_folder.value | first).folder }}" # resource_pool: "" - cluster: "{{ (register_vmware_vm_cluster.value | first).cluster }}" - host: "{{ (register_vmware_vm_cluster_host.value | first).host }}" + cluster: "{{ (__sap_vm_provision_task_vmware_vm_cluster.value | first).cluster }}" + host: "{{ (__sap_vm_provision_task_vmware_vm_cluster_host.value | first).host }}" ## Virtual Machine clone from VM Template definition template_library_item: '{{ vmware_vm_template_id }}' # ID of the Content Library Item with the source VM Template (not OVF) to be cloned and deployed @@ -108,11 +163,17 @@ ## Virtual Machine Storage configuration ## Boot Disk will be loaded to this datastore disk_storage: - datastore: "{{ (register_vmware_vm_cluster_datastore.value | first).datastore }}" + datastore: "{{ (__sap_vm_provision_task_vmware_vm_cluster_datastore.value | first).datastore }}" # storage_policy: + ## Hypervisor Control Plane credentials + vcenter_hostname: "{{ sap_vm_provision_vmware_vcenter_hostname | default(lookup('env', 'VMWARE_HOST')) | default(omit) }}" + vcenter_validate_certs: "{{ (sap_vm_provision_vmware_vcenter_validate_certs_bool | default(lookup('env', 'VMWARE_VALIDATE_CERTS'))) | bool | default(false) }}" + vcenter_username: "{{ sap_vm_provision_vmware_vcenter_user | default(lookup('env', 'VMWARE_USER')) | default(omit) }}" + vcenter_password: "{{ sap_vm_provision_vmware_vcenter_password | default(lookup('env', 'VMWARE_PASSWORD')) | default(omit) }}" + # # Report VM back only after it is done creating the clone image. - # until: register_provisioned_host_single.vm.status != "image_locked" + # until: __sap_vm_provision_task_provision_host_single.vm.status != "image_locked" # retries: 120 # delay: 5 @@ -120,22 +181,28 @@ - name: Set VM ID - when: register_check_vm_exists.value | length == 0 + when: __sap_vm_provision_task_provision_host_single_check_exists.value | length == 0 ansible.builtin.set_fact: - register_vmware_vm_cluster_host_id: "{{ register_provisioned_host_single.value }}" # Returned from VM provision + __sap_vm_provision_task_vmware_vm_cluster_host_id: "{{ __sap_vm_provision_task_provision_host_single.value }}" # Returned from VM provision - name: Check VM status - register: register_provisioned_host_single_info + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_info vmware.vmware_rest.vcenter_vm: - vm: "{{ register_vmware_vm_cluster_host_id }}" + vm: "{{ __sap_vm_provision_task_vmware_vm_cluster_host_id }}" + # Hypervisor Control Plane credentials + vcenter_hostname: "{{ sap_vm_provision_vmware_vcenter_hostname | default(lookup('env', 'VMWARE_HOST')) | default(omit) }}" + vcenter_validate_certs: "{{ (sap_vm_provision_vmware_vcenter_validate_certs_bool | default(lookup('env', 'VMWARE_VALIDATE_CERTS'))) | bool | default(false) }}" + vcenter_username: "{{ sap_vm_provision_vmware_vcenter_user | default(lookup('env', 'VMWARE_USER')) | default(omit) }}" + vcenter_password: "{{ sap_vm_provision_vmware_vcenter_password | default(lookup('env', 'VMWARE_PASSWORD')) | default(omit) }}" # Example https://cloudinit.readthedocs.io/en/23.4.1/reference/datasources/vmware.html#walkthrough-of-guestinfo-keys-transport # Docs https://developer.vmware.com/docs/18555/GUID-75E27FA9-2E40-4CBF-BF3D-22DCFC8F11F7.html # >> The instance-id key is required. All other keys are optional. - name: Set cloud-init variables for customization specification - when: register_provisioned_host_single_info.value.power_state is defined and register_provisioned_host_single_info.value.power_state != "POWERED_ON" + when: __sap_vm_provision_task_provision_host_single_info.value.power_state is defined and __sap_vm_provision_task_provision_host_single_info.value.power_state != "POWERED_ON" ansible.builtin.set_fact: metadata_yaml: instance-id: "{{ inventory_hostname }}" @@ -204,9 +271,10 @@ # >> metadata as JSON/YAML, userdata as no compression or base64 encoding # Error 400 com.vmware.vapi.std.errors.not_allowed_in_current_state : if the virtual machine vm is not in a powered off state. - name: Apply customization specification to the VM in Powered Off state - when: register_provisioned_host_single_info.value.power_state is defined and register_provisioned_host_single_info.value.power_state != "POWERED_ON" + no_log: "{{ __sap_vm_provision_no_log }}" + when: __sap_vm_provision_task_provision_host_single_info.value.power_state is defined and __sap_vm_provision_task_provision_host_single_info.value.power_state != "POWERED_ON" vmware.vmware_rest.vcenter_vm_guest_customization: - vm: '{{ register_vmware_vm_cluster_host_id }}' + vm: '{{ __sap_vm_provision_task_vmware_vm_cluster_host_id }}' configuration_spec: cloud_config: type: CLOUDINIT @@ -216,33 +284,56 @@ # linux_config: interfaces: [] global_DNS_settings: {} + # Hypervisor Control Plane credentials + vcenter_hostname: "{{ sap_vm_provision_vmware_vcenter_hostname | default(lookup('env', 'VMWARE_HOST')) | default(omit) }}" + vcenter_validate_certs: "{{ (sap_vm_provision_vmware_vcenter_validate_certs_bool | default(lookup('env', 'VMWARE_VALIDATE_CERTS'))) | bool | default(false) }}" + vcenter_username: "{{ sap_vm_provision_vmware_vcenter_user | default(lookup('env', 'VMWARE_USER')) | default(omit) }}" + vcenter_password: "{{ sap_vm_provision_vmware_vcenter_password | default(lookup('env', 'VMWARE_PASSWORD')) | default(omit) }}" - name: Ensure VM is Powered ON - register: register_vm_power_info + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_vmware_vm_power_info vmware.vmware_rest.vcenter_vm_power: state: start - vm: "{{ register_vmware_vm_cluster_host_id }}" + vm: "{{ __sap_vm_provision_task_vmware_vm_cluster_host_id }}" + # Hypervisor Control Plane credentials + vcenter_hostname: "{{ sap_vm_provision_vmware_vcenter_hostname | default(lookup('env', 'VMWARE_HOST')) | default(omit) }}" + vcenter_validate_certs: "{{ (sap_vm_provision_vmware_vcenter_validate_certs_bool | default(lookup('env', 'VMWARE_VALIDATE_CERTS'))) | bool | default(false) }}" + vcenter_username: "{{ sap_vm_provision_vmware_vcenter_user | default(lookup('env', 'VMWARE_USER')) | default(omit) }}" + vcenter_password: "{{ sap_vm_provision_vmware_vcenter_password | default(lookup('env', 'VMWARE_PASSWORD')) | default(omit) }}" # Wait until VM is powered on - until: (register_vm_power_info.value.error_type is defined and register_vm_power_info.value.error_type == "ALREADY_IN_DESIRED_STATE") + until: (__sap_vm_provision_task_vmware_vm_power_info.value.error_type is defined and __sap_vm_provision_task_vmware_vm_power_info.value.error_type == "ALREADY_IN_DESIRED_STATE") retries: 15 delay: 60 - name: Show VM Information - register: register_vm_info + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_vmware_vm_info vmware.vmware_rest.vcenter_vm_info: - vm: '{{ register_vmware_vm_cluster_host_id }}' + vm: '{{ __sap_vm_provision_task_vmware_vm_cluster_host_id }}' + # Hypervisor Control Plane credentials + vcenter_hostname: "{{ sap_vm_provision_vmware_vcenter_hostname | default(lookup('env', 'VMWARE_HOST')) | default(omit) }}" + vcenter_validate_certs: "{{ (sap_vm_provision_vmware_vcenter_validate_certs_bool | default(lookup('env', 'VMWARE_VALIDATE_CERTS'))) | bool | default(false) }}" + vcenter_username: "{{ sap_vm_provision_vmware_vcenter_user | default(lookup('env', 'VMWARE_USER')) | default(omit) }}" + vcenter_password: "{{ sap_vm_provision_vmware_vcenter_password | default(lookup('env', 'VMWARE_PASSWORD')) | default(omit) }}" # Wait until VM is powered on - until: register_vm_info.value.power_state == "POWERED_ON" + until: __sap_vm_provision_task_vmware_vm_info.value.power_state == "POWERED_ON" retries: 45 delay: 20 - name: Get guest networking information (wait until DHCP assigns IP Address for host) - register: register_vm_nic_info + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_vmware_vm_nic_info vmware.vmware_rest.vcenter_vm_guest_networking_interfaces_info: - vm: '{{ register_vmware_vm_cluster_host_id }}' + vm: '{{ __sap_vm_provision_task_vmware_vm_cluster_host_id }}' + # Hypervisor Control Plane credentials + vcenter_hostname: "{{ sap_vm_provision_vmware_vcenter_hostname | default(lookup('env', 'VMWARE_HOST')) | default(omit) }}" + vcenter_validate_certs: "{{ (sap_vm_provision_vmware_vcenter_validate_certs_bool | default(lookup('env', 'VMWARE_VALIDATE_CERTS'))) | bool | default(false) }}" + vcenter_username: "{{ sap_vm_provision_vmware_vcenter_user | default(lookup('env', 'VMWARE_USER')) | default(omit) }}" + vcenter_password: "{{ sap_vm_provision_vmware_vcenter_password | default(lookup('env', 'VMWARE_PASSWORD')) | default(omit) }}" # Wait until VM Tools is running - until: (register_vm_nic_info.value.error_type | default("")) != "SERVICE_UNAVAILABLE" and (register_vm_nic_info.value[0].ip.ip_addresses | length) > 0 + until: (__sap_vm_provision_task_vmware_vm_nic_info.value.error_type | default("")) != "SERVICE_UNAVAILABLE" and (__sap_vm_provision_task_vmware_vm_nic_info.value[0].ip.ip_addresses | length) > 0 retries: 45 delay: 20 @@ -250,11 +341,11 @@ # Use IP Address from the preferred vNIC - name: Create fact for delegate host IP ansible.builtin.set_fact: - provisioned_private_ip: "{{ ((register_vm_nic_info.value | map(attribute='ip.ip_addresses')) | flatten | selectattr('state', '==', 'PREFERRED') | first).ip_address }}" + provisioned_private_ip: "{{ ((__sap_vm_provision_task_vmware_vm_nic_info.value | map(attribute='ip.ip_addresses')) | flatten | selectattr('state', '==', 'PREFERRED') | first).ip_address }}" - name: Collect only facts about hardware - register: host_disks_info + register: __sap_vm_provision_task_ansible_facts_host_disks_info ansible.builtin.setup: gather_subset: - hardware @@ -268,7 +359,7 @@ ansible_ssh_common_args: -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ForwardX11=no - name: Collect only facts about network - register: vmware_vm_network_info + register: __sap_vm_provision_task_vmware_vm_network_info ansible.builtin.setup: gather_subset: - default_ipv4 @@ -288,14 +379,14 @@ #- name: Debug Ansible Facts devices used list # ansible.builtin.debug: -# msg: "{{ host_disks_info.ansible_facts.ansible_device_links.ids.keys() | list }}" +# msg: "{{ __sap_vm_provision_task_ansible_facts_host_disks_info.ansible_facts.ansible_device_links.ids.keys() | list }}" - name: Set fact for available storage volume device names ansible.builtin.set_fact: available_volumes: |- {% set letters = 'bcdefghijklmnopqrstuvwxyz' %} - {% set ansible_facts_devices_used_list = host_disks_info.ansible_facts.ansible_device_links.ids.keys() | list %} + {% set ansible_facts_devices_used_list = __sap_vm_provision_task_ansible_facts_host_disks_info.ansible_facts.ansible_device_links.ids.keys() | list %} {% set volumes = [] %} {%- for letter in letters -%} {% for device in ansible_facts_devices_used_list -%} @@ -349,14 +440,21 @@ # The volume creation task requires the above task to define the parameter # which contains the calculated unique device names. - name: Provision Virtual Disk volumes and attach to VM + no_log: "{{ __sap_vm_provision_no_log }}" + register: __sap_vm_provision_task_provision_host_single_volumes vmware.vmware_rest.vcenter_vm_hardware_disk: - vm: "{{ register_vmware_vm_cluster_host_id }}" + vm: "{{ __sap_vm_provision_task_vmware_vm_cluster_host_id }}" type: "{{ vol_item.type | upper }}" state: present label: "{{ vol_item.name }}" new_vmdk: name: "{{ inventory_hostname }}_{{ vol_item.name }}" # VMDK filename capacity: "{{ vol_item.size | human_to_bytes(default_unit='G') }}" + # Hypervisor Control Plane credentials + vcenter_hostname: "{{ sap_vm_provision_vmware_vcenter_hostname | default(lookup('env', 'VMWARE_HOST')) | default(omit) }}" + vcenter_validate_certs: "{{ (sap_vm_provision_vmware_vcenter_validate_certs_bool | default(lookup('env', 'VMWARE_VALIDATE_CERTS'))) | bool | default(false) }}" + vcenter_username: "{{ sap_vm_provision_vmware_vcenter_user | default(lookup('env', 'VMWARE_USER')) | default(omit) }}" + vcenter_password: "{{ sap_vm_provision_vmware_vcenter_password | default(lookup('env', 'VMWARE_PASSWORD')) | default(omit) }}" loop: "{{ filesystem_volume_map }}" loop_control: loop_var: vol_item @@ -365,14 +463,13 @@ when: - vol_item.fstype is defined - vol_item.size > 0 - register: volume_provisioning - failed_when: not volume_provisioning.value is defined and not 'already exists' in volume_provisioning.msg + failed_when: not __sap_vm_provision_task_provision_host_single_volumes.value is defined and not 'already exists' in __sap_vm_provision_task_provision_host_single_volumes.msg - name: Append loop value to register ansible.builtin.set_fact: - register_provisioned_host_single: "{{ register_provisioned_host_single_info | combine( { 'host_node' : inventory_hostname } , { 'vmware_vm_network_info' : vmware_vm_network_info } , { 'sap_host_type' : lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_host_type } , { 'sap_system_type' : (lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_system_type | default('')) } ) }}" + __sap_vm_provision_task_provision_host_single: "{{ __sap_vm_provision_task_provision_host_single_info | combine( { 'host_node' : inventory_hostname } , { '__sap_vm_provision_task_vmware_vm_network_info' : __sap_vm_provision_task_vmware_vm_network_info } , { 'sap_host_type' : lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_host_type } , { 'sap_system_type' : (lookup('ansible.builtin.vars', 'sap_vm_provision_' + sap_vm_provision_iac_platform + '_host_specifications_dictionary')[sap_vm_provision_host_specification_plan][scaleout_origin_host_spec | default(inventory_hostname)].sap_system_type | default('')) } ) }}" - name: Append output to merged register ansible.builtin.set_fact: - register_provisioned_host_all: "{{ register_provisioned_host_all + [register_provisioned_host_single] }}" + register_provisioned_host_all: "{{ register_provisioned_host_all + [__sap_vm_provision_task_provision_host_single] }}" diff --git a/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/aws_ec2_vs/execute_main.yml b/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/aws_ec2_vs/execute_main.yml index 11f94e9..05df174 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/aws_ec2_vs/execute_main.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/aws_ec2_vs/execute_main.yml @@ -170,7 +170,7 @@ ansible.builtin.include_tasks: file: common/set_etc_hosts_scaleout.yml when: - - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_hana_scaleout_active_coordinator is defined or sap_hana_scaleout_active_worker is defined or sap_hana_scaleout_standby is defined) + - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined or sap_vm_provision_calculate_sap_hana_scaleout_active_worker is defined or sap_vm_provision_calculate_sap_hana_scaleout_standby is defined) args: apply: delegate_to: "{{ item }}" diff --git a/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/gcp_ce_vm/execute_main.yml b/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/gcp_ce_vm/execute_main.yml index 30d716b..59f1275 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/gcp_ce_vm/execute_main.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/gcp_ce_vm/execute_main.yml @@ -166,7 +166,7 @@ ansible.builtin.include_tasks: file: common/set_etc_hosts_scaleout.yml when: - - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_hana_scaleout_active_coordinator is defined or sap_hana_scaleout_active_worker is defined or sap_hana_scaleout_standby is defined) + - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined or sap_vm_provision_calculate_sap_hana_scaleout_active_worker is defined or sap_vm_provision_calculate_sap_hana_scaleout_standby is defined) args: apply: delegate_to: "{{ item }}" diff --git a/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/ibmcloud_powervs/execute_main.yml b/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/ibmcloud_powervs/execute_main.yml index 1789ca8..f6c519a 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/ibmcloud_powervs/execute_main.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/ibmcloud_powervs/execute_main.yml @@ -166,7 +166,7 @@ ansible.builtin.include_tasks: file: common/set_etc_hosts_scaleout.yml when: - - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_hana_scaleout_active_coordinator is defined or sap_hana_scaleout_active_worker is defined or sap_hana_scaleout_standby is defined) + - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined or sap_vm_provision_calculate_sap_hana_scaleout_active_worker is defined or sap_vm_provision_calculate_sap_hana_scaleout_standby is defined) args: apply: delegate_to: "{{ item }}" diff --git a/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/ibmcloud_vs/execute_main.yml b/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/ibmcloud_vs/execute_main.yml index 1789ca8..f6c519a 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/ibmcloud_vs/execute_main.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/ibmcloud_vs/execute_main.yml @@ -166,7 +166,7 @@ ansible.builtin.include_tasks: file: common/set_etc_hosts_scaleout.yml when: - - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_hana_scaleout_active_coordinator is defined or sap_hana_scaleout_active_worker is defined or sap_hana_scaleout_standby is defined) + - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined or sap_vm_provision_calculate_sap_hana_scaleout_active_worker is defined or sap_vm_provision_calculate_sap_hana_scaleout_standby is defined) args: apply: delegate_to: "{{ item }}" diff --git a/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/ibmpowervm_vm/execute_main.yml b/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/ibmpowervm_vm/execute_main.yml index 5f0a5db..2dba5d7 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/ibmpowervm_vm/execute_main.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/ibmpowervm_vm/execute_main.yml @@ -168,7 +168,7 @@ ansible.builtin.include_tasks: file: common/set_etc_hosts_scaleout.yml when: - - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_hana_scaleout_active_coordinator is defined or sap_hana_scaleout_active_worker is defined or sap_hana_scaleout_standby is defined) + - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined or sap_vm_provision_calculate_sap_hana_scaleout_active_worker is defined or sap_vm_provision_calculate_sap_hana_scaleout_standby is defined) args: apply: delegate_to: "{{ item }}" diff --git a/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/msazure_vm/execute_main.yml b/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/msazure_vm/execute_main.yml index 649fdde..88471ae 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/msazure_vm/execute_main.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/msazure_vm/execute_main.yml @@ -171,7 +171,7 @@ ansible.builtin.include_tasks: file: common/set_etc_hosts_scaleout.yml when: - - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_hana_scaleout_active_coordinator is defined or sap_hana_scaleout_active_worker is defined or sap_hana_scaleout_standby is defined) + - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined or sap_vm_provision_calculate_sap_hana_scaleout_active_worker is defined or sap_vm_provision_calculate_sap_hana_scaleout_standby is defined) args: apply: delegate_to: "{{ item }}" diff --git a/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/vmware_vm/execute_main.yml b/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/vmware_vm/execute_main.yml index b016c0b..1d15706 100644 --- a/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/vmware_vm/execute_main.yml +++ b/roles/sap_vm_provision/tasks/platform_ansible_to_terraform/vmware_vm/execute_main.yml @@ -169,7 +169,7 @@ ansible.builtin.include_tasks: file: common/set_etc_hosts_scaleout.yml when: - - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_hana_scaleout_active_coordinator is defined or sap_hana_scaleout_active_worker is defined or sap_hana_scaleout_standby is defined) + - (groups["hana_primary"] is defined and (groups["hana_primary"] | length>0)) and (sap_vm_provision_calculate_sap_hana_scaleout_active_coordinator is defined or sap_vm_provision_calculate_sap_hana_scaleout_active_worker is defined or sap_vm_provision_calculate_sap_hana_scaleout_standby is defined) args: apply: delegate_to: "{{ item }}"