deploy/pipelines/01-deploy-control-plane.yaml (259 lines of code) (raw):

# Copyright (c) Microsoft Corporation. # Licensed under the MIT License. --- # /*---------------------------------------------------------------------------8 # | | # | This pipeline deploys the control plane | # | | # +------------------------------------4--------------------------------------*/ parameters: - name: deployer displayName: "Deployer configuration name, use the following syntax: ENV-LOCA-VNET-INFRASTRUCTURE" type: string default: MGMT-WEEU-DEP01-INFRASTRUCTURE - name: library displayName: "SAP Library configuration name, use the following syntax: ENV-LOCA-SAP_LIBRARY" type: string default: MGMT-WEEU-SAP_LIBRARY - name: environment displayName: "Environment name, MGMT, DEV, QA, etc" type: string default: MGMT - name: use_webapp_param displayName: "Deploy the configuration web application infrastructure" type: boolean default: true - name: deploy_webapp_software displayName: "Deploy the configuration web application software" type: boolean default: true - name: use_deployer displayName: Run on self hosted agent type: boolean default: false - name: sap_automation_repo_path displayName: The local path on the agent where the sap_automation repo can be found type: string - name: config_repo_path displayName: The local path on the agent where the config repo can be found type: string - name: connection_name displayName: Service Connection Name type: string - name: force_reset displayName: Force a re-install - may require multiple re-runs type: boolean stages: - stage: Prepare_Deployer condition: and(not(failed()), not(canceled())) variables: - template: variables/01-deploy-control-plane-variables.yaml parameters: deployer: ${{ parameters.deployer }} library: ${{ parameters.library }} environment: ${{ parameters.environment }} use_webapp_param: ${{ parameters.use_webapp_param }} use_deployer: ${{ parameters.use_deployer }} force_reset: ${{ parameters.force_reset }} displayName: Prepare the self hosted agent(s) jobs: - job: Prepare_Deployer displayName: Prepare the self hosted agent workspace: clean: all steps: - template: templates\download.yaml - task: PostBuildCleanup@4 # Set Variables. - task: AzureCLI@2 continueOnError: false inputs: azureSubscription: ${{parameters.connection_name}} scriptType: bash scriptLocation: 'scriptPath' scriptPath: $(System.DefaultWorkingDirectory)/sap-automation/deploy/scripts/pipeline_scripts/01-control-plane-prepare.sh addSpnToEnvironment: true visibleAzLogin: false failOnStandardError: false displayName: Prepare control plane env: CP_ARM_CLIENT_ID: $(CP_ARM_CLIENT_ID) CP_ARM_CLIENT_SECRET: $(CP_ARM_CLIENT_SECRET) ARM_SUBSCRIPTION_ID: $(CP_ARM_SUBSCRIPTION_ID) CP_ARM_TENANT_ID: $(CP_ARM_TENANT_ID) AZURE_DEVOPS_EXT_PAT: $(PAT) CONFIG_REPO_PATH: ${{ parameters.config_repo_path }}/$(Deployment_Configuration_Path) DEPLOYER_TFSTATE_KEY: "${{ parameters.deployer }}.terraform.tfstate" IS_PIPELINE_DEPLOYMENT: true POOL: $(POOL) SAP_AUTOMATION_REPO_PATH: ${{ parameters.sap_automation_repo_path }} SYSTEM_ACCESSTOKEN: $(System.AccessToken) TF_APP_REGISTRATION_APP_ID: $(APP_REGISTRATION_APP_ID) TF_IN_AUTOMATION: true TF_LOG: $(TF_LOG) TF_VAR_agent_ado_url: $(System.CollectionUri) TF_VAR_agent_pat: $(PAT) TF_VAR_agent_pool: $(POOL) TF_VAR_ansible_core_version: $(ansible_core_version) TF_VAR_app_registration_app_id: $(APP_REGISTRATION_APP_ID) TF_VAR_deployer_kv_user_arm_id: $(Deployer_Key_Vault) TF_VAR_spn_id: $(CP_ARM_OBJECT_ID) TF_VAR_tf_version: $(tf_version) TF_VAR_use_webapp: ${{ lower(parameters.use_webapp_param) }} TF_VAR_webapp_client_secret: $(WEB_APP_CLIENT_SECRET) USE_MSI: $(Use_MSI) USE_WEBAPP: ${{ lower(parameters.use_webapp_param) }} WEB_APP_CLIENT_SECRET: $(WEB_APP_CLIENT_SECRET) FORCE_RESET: ${{ lower(parameters.force_reset) }} - stage: Deploy_controlplane dependsOn: - Prepare_Deployer condition: eq(dependencies.Prepare_Deployer.result, 'Succeeded') pool: $(this_agent) variables: - template: variables/01-deploy-control-plane-variables.yaml parameters: deployer: ${{ parameters.deployer }} library: ${{ parameters.library }} environment: ${{ parameters.environment }} use_webapp_param: ${{ parameters.use_webapp_param }} use_deployer: ${{ parameters.use_deployer }} force_reset: ${{ parameters.force_reset }} displayName: Deploy the control plane jobs: - job: Deploy_controlplane displayName: Deploy the control plane workspace: clean: all steps: - task: PostBuildCleanup@4 - template: templates\download.yaml parameters: getLatestFromBranch: true - task: Bash@3 inputs: targetType: 'filePath' filePath: "$(System.DefaultWorkingDirectory)/sap-automation/deploy/scripts/pipeline_scripts/01-control-plane-deploy.sh" failOnStderr: false workingDirectory: "$(System.DefaultWorkingDirectory)" displayName: Deploy control plane Part 2 env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) CP_ARM_SUBSCRIPTION_ID: $(CP_ARM_SUBSCRIPTION_ID) CP_ARM_CLIENT_ID: $(CP_ARM_CLIENT_ID) CP_ARM_CLIENT_SECRET: $(CP_ARM_CLIENT_SECRET) CP_ARM_TENANT_ID: $(CP_ARM_TENANT_ID) TF_VAR_spn_id: $(CP_ARM_OBJECT_ID) TF_VAR_agent_pool: $(POOL) TF_VAR_agent_ado_url: $(System.CollectionUri) TF_VAR_tf_version: $(tf_version) TF_VAR_agent_pat: $(PAT) IS_PIPELINE_DEPLOYMENT: true WEB_APP_CLIENT_SECRET: $(WEB_APP_CLIENT_SECRET) APP_REGISTRATION_APP_ID: $(APP_REGISTRATION_APP_ID) keyvault: $(Deployer_Key_Vault) POOL: $(POOL) SAP_AUTOMATION_REPO_PATH: ${{ parameters.sap_automation_repo_path }} CONFIG_REPO_PATH: ${{ parameters.config_repo_path }}/$(Deployment_Configuration_Path) TF_VAR_ansible_core_version: $(ansible_core_version) TF_LOG: $(TF_LOG) TF_IN_AUTOMATION: true DEPLOYER_TFSTATE_KEY: "${{ parameters.deployer }}.terraform.tfstate" LOGON_USING_SPN: $(Logon_Using_SPN) USE_MSI: $(Use_MSI) AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) FORCE_RESET: ${{ lower(parameters.force_reset) }} - stage: Web_App_Deployment pool: $(this_agent) variables: - template: variables/01-deploy-control-plane-variables.yaml parameters: deployer: ${{ parameters.deployer }} library: ${{ parameters.library }} environment: ${{ parameters.environment }} use_webapp_param: ${{ parameters.use_webapp_param }} use_deployer: ${{ parameters.use_deployer }} displayName: Deploy SAP configuration Web App dependsOn: - Deploy_controlplane - Prepare_Deployer condition: | and ( eq(${{ parameters.use_webapp_param }}, true), eq(${{ parameters.deploy_webapp_software }}, true), eq(dependencies.Deploy_controlplane.result, 'Succeeded'), eq(dependencies.Prepare_Deployer.result, 'Succeeded') ) jobs: - job: Deploy_web_app displayName: Deploy SAP configuration Web App workspace: clean: all steps: - template: templates\download.yaml - task: PostBuildCleanup@4 - task: DotNetCoreCLI@2 displayName: "Build the Configuration Web Application" inputs: command: "build" projects: "$(System.DefaultWorkingDirectory)/sap-automation/Webapp/SDAF/*.csproj" - task: DotNetCoreCLI@2 displayName: "Publish the Configuration Web Application" inputs: command: publish projects: "**/Webapp/**/*.csproj" publishWebProjects: false arguments: "--output $(Build.ArtifactStagingDirectory)/WebApp" zipAfterPublish: true modifyOutputPath: true - task: AzureWebApp@1 displayName: "Deploy the Configuration Web Application" inputs: azureSubscription: ${{parameters.connection_name}} appType: "webApp" appName: $(WEBAPP_URL_BASE) package: "$(Build.ArtifactStagingDirectory)/WebApp/*.zip" deploymentMethod: "auto" appSettings: '-CollectionUri $(System.CollectionUri) -ProjectName "$(System.TeamProject)" -RepositoryId $(Build.Repository.ID) -SourceBranch "$(Build.SourceBranchName)" -WORKLOADZONE_PIPELINE_ID $(WORKLOADZONE_PIPELINE_ID) -SYSTEM_PIPELINE_ID $(SYSTEM_PIPELINE_ID) -SAP_INSTALL_PIPELINE_ID $(SAP_INSTALL_PIPELINE_ID) -SDAF_GENERAL_GROUP_ID $(SDAF_GENERAL_GROUP_ID) -IS_PIPELINE_DEPLOYMENT true -CONTROLPLANE_ENV $(ControlPlaneEnvironment) -CONTROLPLANE_LOC $(ControlPlaneLocation)' env: ARM_SUBSCRIPTION_ID: $(CP_ARM_SUBSCRIPTION_ID) SYSTEM_PIPELINE_ID: $(SYSTEM_PIPELINE_ID) WORKLOADZONE_PIPELINE_ID: $(WORKLOADZONE_PIPELINE_ID) SAP_INSTALL_PIPELINE_ID: $(SAP_INSTALL_PIPELINE_ID) SDAF_GENERAL_GROUP_ID: $(SDAF_GENERAL_GROUP_ID) WEBAPP_URL_BASE: $(WEBAPP_URL_BASE) WEBAPP_RESOURCE_GROUP: $(WEBAPP_RESOURCE_GROUP) WEBAPP_ID: $(WEBAPP_ID) APP_REGISTRATION_APP_ID: $(APP_REGISTRATION_APP_ID) APP_REGISTRATION_OBJECTID: $(APP_REGISTRATION_OBJECTID) APP_TENANT_ID: $(APP_TENANT_ID) AZURE_CONNECTION_NAME: ${{variables.connection_name}} - bash: | #!/bin/bash printf "Configure the Web Application authentication using the following script.\n" >"$(Build.Repository.LocalPath)/Web Application Configuration.md" printf "\n\n" >>"$(Build.Repository.LocalPath)/Web Application Configuration.md" printf "az ad app update --id %s --web-home-page-url https://%s.azurewebsites.net --web-redirect-uris https://%s.azurewebsites.net/ https://%s.azurewebsites.net/.auth/login/aad/callback\n\n" "$(APP_REGISTRATION_APP_ID)" "$(WEBAPP_URL_BASE)" "$(WEBAPP_URL_BASE)" "$(WEBAPP_URL_BASE)" >>"$(Build.Repository.LocalPath)/Web Application Configuration.md" printf "\n" >>"$(Build.Repository.LocalPath)/Web Application Configuration.md" printf "az role assignment create --assignee %s --role reader --subscription %s --scope /subscriptions/%s\n" "$(WEBAPP_IDENTITY)" "$ARM_SUBSCRIPTION_ID" "$ARM_SUBSCRIPTION_ID" >>"$(Build.Repository.LocalPath)/Web Application Configuration.md" printf "Run the above command for all subscriptions you want to use in the Web Application\n" >>"$(Build.Repository.LocalPath)/Web Application Configuration.md" printf "\n" >>"$(Build.Repository.LocalPath)/Web Application Configuration.md" printf "az role assignment create --assignee %s --role 'Storage Blob Data Contributor' --subscription %s --scope /subscriptions/%s/resourceGroups/%s\n" "$(WEBAPP_IDENTITY)" "$ARM_SUBSCRIPTION_ID" "$ARM_SUBSCRIPTION_ID" "$(Terraform_Remote_Storage_Resource_Group_Name)" >>"$(Build.Repository.LocalPath)/Web Application Configuration.md" printf "az role assignment create --assignee %s --role 'Storage Table Data Contributor' --subscription %s --scope /subscriptions/%s/resourceGroups/%s \n\n" "$(WEBAPP_IDENTITY)" "$ARM_SUBSCRIPTION_ID" "$ARM_SUBSCRIPTION_ID" "$(Terraform_Remote_Storage_Resource_Group_Name)" >>"$(Build.Repository.LocalPath)/Web Application Configuration.md" printf "\n" >>"$(Build.Repository.LocalPath)/Web Application Configuration.md" printf "az rest --method POST --uri \"https://graph.microsoft.com/beta/applications/%s/federatedIdentityCredentials\" --body \"{'name': 'ManagedIdentityFederation', 'issuer': 'https://login.microsoftonline.com/%s/v2.0', 'subject': '%s', 'audiences': [ 'api://AzureADTokenExchange' ]}\"" $(APP_REGISTRATION_OBJECTID) $(APP_TENANT_ID) $(MSI_ID) >>"$(Build.Repository.LocalPath)/Web Application Configuration.md" printf "\n" >>"$(Build.Repository.LocalPath)/Web Application Configuration.md" printf "az webapp restart --ids %s\n\n $(WEBAPP_ID)" >>"$(Build.Repository.LocalPath)/Web Application Configuration.md" printf "\n\n" >>"$(Build.Repository.LocalPath)/Web Application Configuration.md" printf "[Access the Web App](https://%s.azurewebsites.net) \n\n" $(WEBAPP_URL_BASE) >>"$(Build.Repository.LocalPath)/Web Application Configuration.md" echo "##vso[task.uploadsummary]$(Build.Repository.LocalPath)/Web Application Configuration.md" exit 0 displayName: "Documentation" env: ARM_SUBSCRIPTION_ID: $(CP_ARM_SUBSCRIPTION_ID) SYSTEM_PIPELINE_ID: $(SYSTEM_PIPELINE_ID) APP_REGISTRATION_APP_ID: $(APP_REGISTRATION_APP_ID) WEBAPP_URL_BASE: $(WEBAPP_URL_BASE) WEBAPP_ID: $(WEBAPP_ID) WEBAPP_IDENTITY: $(WEBAPP_IDENTITY)