From a9c941948d51c59c758d07bce702bcb36aee70ec Mon Sep 17 00:00:00 2001 From: Steve Keeler Date: Mon, 9 May 2022 17:11:12 -0400 Subject: [PATCH] Add environment configuration override and protect sensitive parameters (#280) --- .github/workflows/0-everything.yml | 35 +++++++++----- .github/workflows/1-management-groups.yml | 11 ++++- .github/workflows/2-roles.yml | 11 ++++- .github/workflows/3-logging.yml | 11 ++++- .github/workflows/4-policy.yml | 11 ++++- .../5-hub-network-with-azure-firewall.yml | 11 ++++- .github/workflows/5-hub-network-with-nva.yml | 15 ++++-- .github/workflows/6-subscriptions.yml | 13 +++-- .github/workflows/README.md | 2 + scripts/deployments/RunWorkflows.ps1 | 48 ++++++++++--------- 10 files changed, 116 insertions(+), 52 deletions(-) diff --git a/.github/workflows/0-everything.yml b/.github/workflows/0-everything.yml index 18c65b51..26633b8a 100644 --- a/.github/workflows/0-everything.yml +++ b/.github/workflows/0-everything.yml @@ -22,8 +22,12 @@ on: default: "HubNetworkWithAzureFirewall" subscriptionIds: type: string - description: The subscription ID(s) to use for the deployment. - required: true + description: Subscription ID(s) + required: false + environmentName: + type: string + description: Environment name + required: false defaults: run: @@ -48,7 +52,8 @@ jobs: run: | ./RunWorkflows.ps1 ` -DeployManagementGroups ` - -LoginServicePrincipalJson '${{secrets.ALZ_CREDENTIALS}}' ` + -EnvironmentName '${{github.event.inputs.environmentName}}' ` + -LoginServicePrincipalJson (ConvertTo-SecureString -String '${{secrets.ALZ_CREDENTIALS}}' -AsPlainText -Force) ` -GitHubRepo ${env:GITHUB_REPOSITORY} ` -GitHubRef ${env:GITHUB_REF} @@ -56,7 +61,8 @@ jobs: run: | ./RunWorkflows.ps1 ` -DeployRoles ` - -LoginServicePrincipalJson '${{secrets.ALZ_CREDENTIALS}}' ` + -EnvironmentName '${{github.event.inputs.environmentName}}' ` + -LoginServicePrincipalJson (ConvertTo-SecureString -String '${{secrets.ALZ_CREDENTIALS}}' -AsPlainText -Force) ` -GitHubRepo ${env:GITHUB_REPOSITORY} ` -GitHubRef ${env:GITHUB_REF} @@ -64,7 +70,8 @@ jobs: run: | ./RunWorkflows.ps1 ` -DeployLogging ` - -LoginServicePrincipalJson '${{secrets.ALZ_CREDENTIALS}}' ` + -EnvironmentName '${{github.event.inputs.environmentName}}' ` + -LoginServicePrincipalJson (ConvertTo-SecureString -String '${{secrets.ALZ_CREDENTIALS}}' -AsPlainText -Force) ` -GitHubRepo ${env:GITHUB_REPOSITORY} ` -GitHubRef ${env:GITHUB_REF} @@ -72,7 +79,8 @@ jobs: run: | ./RunWorkflows.ps1 ` -DeployPolicy ` - -LoginServicePrincipalJson '${{secrets.ALZ_CREDENTIALS}}' ` + -EnvironmentName '${{github.event.inputs.environmentName}}' ` + -LoginServicePrincipalJson (ConvertTo-SecureString -String '${{secrets.ALZ_CREDENTIALS}}' -AsPlainText -Force) ` -GitHubRepo ${env:GITHUB_REPOSITORY} ` -GitHubRef ${env:GITHUB_REF} @@ -81,7 +89,8 @@ jobs: run: | ./RunWorkflows.ps1 ` -Deploy${{github.event.inputs.hubNetworkType}} ` - -LoginServicePrincipalJson '${{secrets.ALZ_CREDENTIALS}}' ` + -EnvironmentName '${{github.event.inputs.environmentName}}' ` + -LoginServicePrincipalJson (ConvertTo-SecureString -String '${{secrets.ALZ_CREDENTIALS}}' -AsPlainText -Force) ` -GitHubRepo ${env:GITHUB_REPOSITORY} ` -GitHubRef ${env:GITHUB_REF} @@ -90,17 +99,19 @@ jobs: run: | ./RunWorkflows.ps1 ` -Deploy${{github.event.inputs.hubNetworkType}} ` - -LoginServicePrincipalJson '${{secrets.ALZ_CREDENTIALS}}' ` + -EnvironmentName '${{github.event.inputs.environmentName}}' ` + -LoginServicePrincipalJson (ConvertTo-SecureString -String '${{secrets.ALZ_CREDENTIALS}}' -AsPlainText -Force) ` -GitHubRepo ${env:GITHUB_REPOSITORY} ` -GitHubRef ${env:GITHUB_REF} ` - -NvaUsername '${{secrets.NVA_USERNAME}}' ` - -NvaPassword '${{secrets.NVA_PASSWORD}}' + -NvaUsername (ConvertTo-SecureString -String '${{secrets.NVA_USERNAME}}' -AsPlainText -Force) ` + -NvaPassword (ConvertTo-SecureString -String '${{secrets.NVA_PASSWORD}} '-AsPlainText -Force) - name: Deploy Subscriptions if: github.event.inputs.subscriptionIds != '' run: | ./RunWorkflows.ps1 ` - -DeploySubscriptionIds ${{github.event.inputs.subscriptionIds}} ` - -LoginServicePrincipalJson '${{secrets.ALZ_CREDENTIALS}}' ` + -DeploySubscriptionIds '${{github.event.inputs.subscriptionIds}}' ` + -EnvironmentName '${{github.event.inputs.environmentName}}' ` + -LoginServicePrincipalJson (ConvertTo-SecureString -String '${{secrets.ALZ_CREDENTIALS}}' -AsPlainText -Force) ` -GitHubRepo ${env:GITHUB_REPOSITORY} ` -GitHubRef ${env:GITHUB_REF} diff --git a/.github/workflows/1-management-groups.yml b/.github/workflows/1-management-groups.yml index 33bad706..960620a6 100644 --- a/.github/workflows/1-management-groups.yml +++ b/.github/workflows/1-management-groups.yml @@ -9,7 +9,13 @@ name: 1 - Management Groups -on: workflow_dispatch +on: + workflow_dispatch: + inputs: + environmentName: + type: string + description: Environment name + required: false defaults: run: @@ -34,6 +40,7 @@ jobs: run: | ./RunWorkflows.ps1 ` -DeployManagementGroups ` - -LoginServicePrincipalJson '${{secrets.ALZ_CREDENTIALS}}' ` + -EnvironmentName '${{github.event.inputs.environmentName}}' ` + -LoginServicePrincipalJson (ConvertTo-SecureString -String '${{secrets.ALZ_CREDENTIALS}}' -AsPlainText -Force) ` -GitHubRepo ${env:GITHUB_REPOSITORY} ` -GitHubRef ${env:GITHUB_REF} diff --git a/.github/workflows/2-roles.yml b/.github/workflows/2-roles.yml index 8d741f00..ef04e0ab 100644 --- a/.github/workflows/2-roles.yml +++ b/.github/workflows/2-roles.yml @@ -9,7 +9,13 @@ name: 2 - Roles -on: workflow_dispatch +on: + workflow_dispatch: + inputs: + environmentName: + type: string + description: Environment name + required: false defaults: run: @@ -34,6 +40,7 @@ jobs: run: | ./RunWorkflows.ps1 ` -DeployRoles ` - -LoginServicePrincipalJson '${{secrets.ALZ_CREDENTIALS}}' ` + -EnvironmentName '${{github.event.inputs.environmentName}}' ` + -LoginServicePrincipalJson (ConvertTo-SecureString -String '${{secrets.ALZ_CREDENTIALS}}' -AsPlainText -Force) ` -GitHubRepo ${env:GITHUB_REPOSITORY} ` -GitHubRef ${env:GITHUB_REF} diff --git a/.github/workflows/3-logging.yml b/.github/workflows/3-logging.yml index a45b70e9..1907757c 100644 --- a/.github/workflows/3-logging.yml +++ b/.github/workflows/3-logging.yml @@ -9,7 +9,13 @@ name: 3 - Logging -on: workflow_dispatch +on: + workflow_dispatch: + inputs: + environmentName: + type: string + description: Environment name + required: false defaults: run: @@ -34,6 +40,7 @@ jobs: run: | ./RunWorkflows.ps1 ` -DeployLogging ` - -LoginServicePrincipalJson '${{secrets.ALZ_CREDENTIALS}}' ` + -EnvironmentName '${{github.event.inputs.environmentName}}' ` + -LoginServicePrincipalJson (ConvertTo-SecureString -String '${{secrets.ALZ_CREDENTIALS}}' -AsPlainText -Force) ` -GitHubRepo ${env:GITHUB_REPOSITORY} ` -GitHubRef ${env:GITHUB_REF} diff --git a/.github/workflows/4-policy.yml b/.github/workflows/4-policy.yml index bd85b09e..f234ce99 100644 --- a/.github/workflows/4-policy.yml +++ b/.github/workflows/4-policy.yml @@ -9,7 +9,13 @@ name: 4 - Policy -on: workflow_dispatch +on: + workflow_dispatch: + inputs: + environmentName: + type: string + description: Environment name + required: false defaults: run: @@ -34,6 +40,7 @@ jobs: run: | ./RunWorkflows.ps1 ` -DeployPolicy ` - -LoginServicePrincipalJson '${{secrets.ALZ_CREDENTIALS}}' ` + -EnvironmentName '${{github.event.inputs.environmentName}}' ` + -LoginServicePrincipalJson (ConvertTo-SecureString -String '${{secrets.ALZ_CREDENTIALS}}' -AsPlainText -Force) ` -GitHubRepo ${env:GITHUB_REPOSITORY} ` -GitHubRef ${env:GITHUB_REF} diff --git a/.github/workflows/5-hub-network-with-azure-firewall.yml b/.github/workflows/5-hub-network-with-azure-firewall.yml index 15030832..60a37913 100644 --- a/.github/workflows/5-hub-network-with-azure-firewall.yml +++ b/.github/workflows/5-hub-network-with-azure-firewall.yml @@ -9,7 +9,13 @@ name: 5 - Hub Network with Azure Firewall -on: workflow_dispatch +on: + workflow_dispatch: + inputs: + environmentName: + type: string + description: Environment name + required: false defaults: run: @@ -34,6 +40,7 @@ jobs: run: | ./RunWorkflows.ps1 ` -DeployHubNetworkWithAzureFirewall ` - -LoginServicePrincipalJson '${{secrets.ALZ_CREDENTIALS}}' ` + -EnvironmentName '${{github.event.inputs.environmentName}}' ` + -LoginServicePrincipalJson (ConvertTo-SecureString -String '${{secrets.ALZ_CREDENTIALS}}' -AsPlainText -Force) ` -GitHubRepo ${env:GITHUB_REPOSITORY} ` -GitHubRef ${env:GITHUB_REF} diff --git a/.github/workflows/5-hub-network-with-nva.yml b/.github/workflows/5-hub-network-with-nva.yml index 8f0a4a2e..589a17fd 100644 --- a/.github/workflows/5-hub-network-with-nva.yml +++ b/.github/workflows/5-hub-network-with-nva.yml @@ -9,7 +9,13 @@ name: 5 - Hub Network with NVA -on: workflow_dispatch +on: + workflow_dispatch: + inputs: + environmentName: + type: string + description: Environment name + required: false defaults: run: @@ -34,8 +40,9 @@ jobs: run: | ./RunWorkflows.ps1 ` -DeployHubNetworkWithNVA ` - -LoginServicePrincipalJson '${{secrets.ALZ_CREDENTIALS}}' ` + -EnvironmentName '${{github.event.inputs.environmentName}}' ` + -LoginServicePrincipalJson (ConvertTo-SecureString -String '${{secrets.ALZ_CREDENTIALS}}' -AsPlainText -Force) ` -GitHubRepo ${env:GITHUB_REPOSITORY} ` -GitHubRef ${env:GITHUB_REF} ` - -NvaUsername '${{secrets.NVA_USERNAME}}' ` - -NvaPassword '${{secrets.NVA_PASSWORD}}' + -NvaUsername (ConvertTo-SecureString -String '${{secrets.NVA_USERNAME}}' -AsPlainText -Force) ` + -NvaPassword (ConvertTo-SecureString -String '${{secrets.NVA_PASSWORD}} '-AsPlainText -Force) diff --git a/.github/workflows/6-subscriptions.yml b/.github/workflows/6-subscriptions.yml index e190e9cf..66e19a71 100644 --- a/.github/workflows/6-subscriptions.yml +++ b/.github/workflows/6-subscriptions.yml @@ -14,8 +14,12 @@ on: inputs: subscriptionIds: type: string - description: The subscription ID(s) to use for the deployment. - required: true + description: Subscription ID(s) + required: false + environmentName: + type: string + description: Environment name + required: false defaults: run: @@ -39,7 +43,8 @@ jobs: - name: Deploy Subscriptions run: | ./RunWorkflows.ps1 ` - -DeploySubscriptionIds ${{github.event.inputs.subscriptionIds}} ` - -LoginServicePrincipalJson '${{secrets.ALZ_CREDENTIALS}}' ` + -DeploySubscriptionIds '${{github.event.inputs.subscriptionIds}}' ` + -EnvironmentName '${{github.event.inputs.environmentName}}' ` + -LoginServicePrincipalJson (ConvertTo-SecureString -String '${{secrets.ALZ_CREDENTIALS}}' -AsPlainText -Force) ` -GitHubRepo ${env:GITHUB_REPOSITORY} ` -GitHubRef ${env:GITHUB_REF} diff --git a/.github/workflows/README.md b/.github/workflows/README.md index 0c2d6f9e..df82e0a6 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -42,6 +42,8 @@ The subscription ids input value can be one of: There are two `Hub Networking` workflows, but you only need to run one of them. The networking workflow you run is based on whether you choose to implement the Azure Firewall or a Network Virtual Appliance (NVA). +All workflows take an optional `Environment Name` input. By default, the environment name is derived from a combination of the GitHub repository name and branch name, i.e. `repo-branch`. You can use the `Environment Name` input value to override the derived value, forcing the workflow to use configuration folders and files for a specific `repo-branch`. + In the default implementation, all workflows are run manually. This behavior can be changed by modifying the corresponding YAML workflow definition files. For example, to trigger workflow on a push or pull request to the repository. These workflow definitions are implemented using modularized PowerShell scripts in the `scripts/deployments` path. The main entry point for these scripts is `scripts/deployments/RunWorkflows.ps1`. diff --git a/scripts/deployments/RunWorkflows.ps1 b/scripts/deployments/RunWorkflows.ps1 index 587639fc..10ec2146 100644 --- a/scripts/deployments/RunWorkflows.ps1 +++ b/scripts/deployments/RunWorkflows.ps1 @@ -79,7 +79,7 @@ OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. Deploy 2 subscriptions interactively. .EXAMPLE - PS> .\RunWorkflows.ps1 -GitHubRepo 'Azure/CanadaPubSecALZ' -GitHubRef 'refs/head/main' -LoginServicePrincipalJson '' -DeployManagementGroups + PS> .\RunWorkflows.ps1 -GitHubRepo 'Azure/CanadaPubSecALZ' -GitHubRef 'refs/head/main' -LoginServicePrincipalJson (ConvertTo-SecureString -String '' -AsPlainText -Force) -DeployManagementGroups Deploy management groups using service principal authentication. @@ -89,7 +89,7 @@ OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. run: | ./RunWorkflows.ps1 ` -DeployManagementGroups ` - -LoginServicePrincipalJson '${{secrets.ALZ_CREDENTIALS}}' ` + -LoginServicePrincipalJson (ConvertTo-SecureString -String '${{secrets.ALZ_CREDENTIALS}}' -AsPlainText -Force) ` -GitHubRepo ${env:GITHUB_REPOSITORY} ` -GitHubRef ${env:GITHUB_REF} #> @@ -106,14 +106,14 @@ Param( [string[]]$DeploySubscriptionIds=@(), # How to deploy - [string]$EnvironmentName="CanadaESLZ-main", + [string]$EnvironmentName="", [string]$GitHubRepo=$null, [string]$GitHubRef=$null, [string]$LoginInteractiveTenantId=$null, - [string]$LoginServicePrincipalJson=$null, + [SecureString]$LoginServicePrincipalJson=$null, [string]$WorkingDirectory=(Resolve-Path "../.."), - [string]$NvaUsername=$null, - [string]$NvaPassword=$null + [SecureString]$NvaUsername=$null, + [SecureString]$NvaPassword=$null ) #Requires -Modules Az, powershell-yaml @@ -124,19 +124,23 @@ $ErrorActionPreference = "Stop" # Please follow the instructions on https://github.com/Azure/CanadaPubSecALZ/blob/main/docs/onboarding/azure-devops-pipelines.md # to setup the configuration files. Once the configuration files are setup, you can choose to run this script or use Azure DevOps. -# Construct environment name from GitHub repo and ref (result: -) -if ((-not [string]::IsNullOrEmpty($GitHubRepo)) -and (-not [string]::IsNullOrEmpty($GitHubRef))) { - $EnvironmentName = ` - $GitHubRepo.Split('/')[1] + '-' + ` - $GitHubRef.Split('/')[$GitHubRef.Split('/').Count-1] - Write-Host "Environment name: $EnvironmentName" +# Use $EnvironmentName parameter if specified, otherwise derive from GitHub or Azure DevOps environment. +if ([string]::IsNullOrEmpty($EnvironmentName)) { + + # Construct environment name from GitHub repo and ref (result: -) + if ((-not [string]::IsNullOrEmpty($GitHubRepo)) -and (-not [string]::IsNullOrEmpty($GitHubRef))) { + $EnvironmentName = ` + $GitHubRepo.Split('/')[1] + '-' + ` + $GitHubRef.Split('/')[$GitHubRef.Split('/').Count-1] + Write-Host "Environment name: $EnvironmentName" + } + + # Construct environment name from Azure DevOps (result: -) + <# + TO BE IMPLEMENTED + #> } -# Construct environment name from Azure DevOps (result: -) -<# - TO BE IMPLEMENTED -#> - # Load functions Write-Host "Loading functions..." . ".\Functions\EnvironmentContext.ps1" @@ -157,9 +161,9 @@ if (-not [string]::IsNullOrEmpty($LoginInteractiveTenantId)) { } # Az Login via Service Principal -if (-not [string]::IsNullOrEmpty($LoginServicePrincipalJson)) { +if ($LoginServicePrincipalJson -ne $null) { Write-Host "Logging in to Azure using service principal..." - $ServicePrincipal = $LoginServicePrincipalJson | ConvertFrom-Json + $ServicePrincipal = ($LoginServicePrincipalJson | ConvertFrom-SecureString -AsPlainText) | ConvertFrom-Json $Password = ConvertTo-SecureString $ServicePrincipal.password -AsPlainText -Force $Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $ServicePrincipal.appId, $Password Connect-AzAccount -ServicePrincipal -TenantId $ServicePrincipal.tenant -Credential $Credential @@ -255,8 +259,8 @@ if ($DeployHubNetworkWithNVA) { -SubscriptionId $Context.Variables['var-hubnetwork-subscriptionId'] ` -ConfigurationFilePath "$($Context.NetworkingDirectory)/$($Context.Variables['var-hubnetwork-nva-configurationFileName'])" ` -LogAnalyticsWorkspaceResourceId $LoggingConfiguration.LogAnalyticsWorkspaceResourceId ` - -NvaUsername $NvaUsername ` - -NvaPassword $NvaPassword + -NvaUsername (ConvertFrom-SecureString -SecureString $NvaUsername -AsPlainText) ` + -NvaPassword (ConvertFrom-SecureString -SecureString $NvaPassword -AsPlainText) } # Hub Networking with Azure Firewall @@ -291,7 +295,7 @@ if ($DeployHubNetworkWithAzureFirewall) { } # Deploy Subscription archetypes -if ($DeploySubscriptionIds.Count -gt 0) { +if (($DeploySubscriptionIds -ne $null) -and ($DeploySubscriptionIds.Count -gt 0)) { Write-Host "Deploying Subscriptions..." # Get Logging information using logging config file $LoggingConfiguration = Get-LoggingConfiguration `