From eb27635221dc24c3cb4995dbc4d2bc18470394b2 Mon Sep 17 00:00:00 2001 From: Ludovico Magnocavallo Date: Fri, 11 Nov 2022 08:55:57 +0100 Subject: [PATCH] FAST: improve GitHub workflow, stage 01 output fixes (#966) * fix outputs on null output files variable * improve GH workflow * bring back apply status * fix heading level * add missing try, update IAM md files --- fast/assets/templates/workflow-github.yaml | 22 +++++++++----- fast/stages/00-bootstrap/IAM.md | 2 +- fast/stages/01-resman/IAM.md | 35 +++++++--------------- fast/stages/01-resman/outputs-files.tf | 14 +++++---- 4 files changed, 34 insertions(+), 39 deletions(-) diff --git a/fast/assets/templates/workflow-github.yaml b/fast/assets/templates/workflow-github.yaml index 1efb9c66..2556816c 100644 --- a/fast/assets/templates/workflow-github.yaml +++ b/fast/assets/templates/workflow-github.yaml @@ -81,7 +81,7 @@ jobs: - id: tf-setup name: Set up Terraform - uses: hashicorp/setup-terraform@v1 + uses: hashicorp/setup-terraform@v2.0.3 with: terraform_version: $${{ env.TF_VERSION }} @@ -99,14 +99,18 @@ jobs: name: Terraform plan continue-on-error: true run: | - terraform plan -input=false -out ../plan.out -no-color + echo -e "## Plan Output\n\n\`\`\`hcl" >> $$GITHUB_STEP_SUMMARY + terraform plan -input=false -out ../plan.out -no-color |tee -a $$GITHUB_STEP_SUMMARY + echo "\`\`\`" >> $$GITHUB_STEP_SUMMARY - id: tf-apply if: github.event.pull_request.merged == true name: Terraform apply continue-on-error: true run: | - terraform apply -input=false -auto-approve -no-color ../plan.out + echo -e "## Apply Output\n\n\`\`\`hcl" >> $$GITHUB_STEP_SUMMARY + terraform apply -input=false -auto-approve -no-color ../plan.out |tee -a $$GITHUB_STEP_SUMMARY + echo "\`\`\`" >> $$GITHUB_STEP_SUMMARY - id: pr-comment name: Post comment to Pull Request @@ -116,8 +120,10 @@ jobs: PLAN: terraform\n$${{ steps.tf-plan.outputs.stdout }} with: script: | - const output = `#### Terraform Initialization ⚙️\`$${{ steps.tf-init.outcome }}\` - #### Terraform Validation 🤖\`$${{ steps.tf-validate.outcome }}\` + const output = `### Terraform Initialization \`$${{ steps.tf-init.outcome }}\` + + ### Terraform Validation \`$${{ steps.tf-validate.outcome }}\` +
Validation Output \`\`\`\n @@ -126,17 +132,17 @@ jobs:
- #### Terraform Plan 📖\`$${{ steps.tf-plan.outcome }}\` + ### Terraform Plan \`$${{ steps.tf-plan.outcome }}\`
Show Plan \`\`\`\n - $${process.env.PLAN} + $${process.env.PLAN.split('\n').filter(l => l.match(/^([A-Z\s].*|)$$/)).join('\n')} \`\`\`
- #### Terraform Apply 📖\`$${{ steps.tf-apply.outcome }}\` + ### Terraform Apply \`$${{ steps.tf-apply.outcome }}\` *Pusher: @$${{ github.actor }}, Action: \`$${{ github.event_name }}\`, Working Directory: \`$${{ env.tf_actions_working_dir }}\`, Workflow: \`$${{ github.workflow }}\`*`; diff --git a/fast/stages/00-bootstrap/IAM.md b/fast/stages/00-bootstrap/IAM.md index 7e7d7c19..b938c44f 100644 --- a/fast/stages/00-bootstrap/IAM.md +++ b/fast/stages/00-bootstrap/IAM.md @@ -8,10 +8,10 @@ Legend: + additive, conditional. |---|---| |GCP organization domain
domain|[roles/browser](https://cloud.google.com/iam/docs/understanding-roles#browser) | |gcp-billing-admins
group|[roles/billing.admin](https://cloud.google.com/iam/docs/understanding-roles#billing.admin) +
[roles/billing.costsManager](https://cloud.google.com/iam/docs/understanding-roles#billing.costsManager) +| +|gcp-devops
group|[roles/cloudsupport.techSupportEditor](https://cloud.google.com/iam/docs/understanding-roles#cloudsupport.techSupportEditor)
[roles/logging.viewer](https://cloud.google.com/iam/docs/understanding-roles#logging.viewer)
[roles/monitoring.viewer](https://cloud.google.com/iam/docs/understanding-roles#monitoring.viewer) | |gcp-network-admins
group|[roles/cloudasset.owner](https://cloud.google.com/iam/docs/understanding-roles#cloudasset.owner)
[roles/cloudsupport.techSupportEditor](https://cloud.google.com/iam/docs/understanding-roles#cloudsupport.techSupportEditor)
[roles/compute.orgFirewallPolicyAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.orgFirewallPolicyAdmin) +
[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin) +| |gcp-organization-admins
group|[roles/cloudasset.owner](https://cloud.google.com/iam/docs/understanding-roles#cloudasset.owner)
[roles/cloudsupport.admin](https://cloud.google.com/iam/docs/understanding-roles#cloudsupport.admin)
[roles/compute.osAdminLogin](https://cloud.google.com/iam/docs/understanding-roles#compute.osAdminLogin)
[roles/compute.osLoginExternalUser](https://cloud.google.com/iam/docs/understanding-roles#compute.osLoginExternalUser)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.organizationAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.organizationAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator)
[roles/billing.admin](https://cloud.google.com/iam/docs/understanding-roles#billing.admin) +
[roles/billing.costsManager](https://cloud.google.com/iam/docs/understanding-roles#billing.costsManager) +
[roles/orgpolicy.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#orgpolicy.policyAdmin) +| |gcp-security-admins
group|[roles/cloudasset.owner](https://cloud.google.com/iam/docs/understanding-roles#cloudasset.owner)
[roles/cloudsupport.techSupportEditor](https://cloud.google.com/iam/docs/understanding-roles#cloudsupport.techSupportEditor)
[roles/iam.securityReviewer](https://cloud.google.com/iam/docs/understanding-roles#iam.securityReviewer)
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/securitycenter.admin](https://cloud.google.com/iam/docs/understanding-roles#securitycenter.admin)
[roles/accesscontextmanager.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#accesscontextmanager.policyAdmin) +
[roles/iam.organizationRoleAdmin](https://cloud.google.com/iam/docs/understanding-roles#iam.organizationRoleAdmin) +
[roles/orgpolicy.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#orgpolicy.policyAdmin) +| -|gcp-support
group|[roles/cloudsupport.techSupportEditor](https://cloud.google.com/iam/docs/understanding-roles#cloudsupport.techSupportEditor)
[roles/logging.viewer](https://cloud.google.com/iam/docs/understanding-roles#logging.viewer)
[roles/monitoring.viewer](https://cloud.google.com/iam/docs/understanding-roles#monitoring.viewer) | |prod-bootstrap-0
serviceAccount|[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/resourcemanager.organizationAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.organizationAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator)
[roles/resourcemanager.projectMover](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectMover)
[roles/billing.admin](https://cloud.google.com/iam/docs/understanding-roles#billing.admin) +
[roles/billing.costsManager](https://cloud.google.com/iam/docs/understanding-roles#billing.costsManager) +
[roles/iam.organizationRoleAdmin](https://cloud.google.com/iam/docs/understanding-roles#iam.organizationRoleAdmin) +| |prod-resman-0
serviceAccount|organizations/[org_id #0]/roles/organizationIamAdmin
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.tagAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.tagAdmin)
[roles/resourcemanager.tagUser](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.tagUser)
[roles/billing.admin](https://cloud.google.com/iam/docs/understanding-roles#billing.admin) +
[roles/billing.costsManager](https://cloud.google.com/iam/docs/understanding-roles#billing.costsManager) +
[roles/orgpolicy.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#orgpolicy.policyAdmin) +| diff --git a/fast/stages/01-resman/IAM.md b/fast/stages/01-resman/IAM.md index 78fac484..403bd96c 100644 --- a/fast/stages/01-resman/IAM.md +++ b/fast/stages/01-resman/IAM.md @@ -41,12 +41,6 @@ Legend: + additive, conditional. |---|---| |dev-resman-pf-0
serviceAccount|organizations/[org_id #0]/roles/serviceProjectNetworkAdmin
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) | -## Folder development [#4] - -| members | roles | -|---|---| -|dev-resman-pf-0
serviceAccount|organizations/[org_id #0]/roles/serviceProjectNetworkAdmin
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) | - ## Folder networking | members | roles | @@ -80,12 +74,6 @@ Legend: + additive, conditional. |---|---| |prod-resman-pf-0
serviceAccount|organizations/[org_id #0]/roles/serviceProjectNetworkAdmin
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) | -## Folder production [#4] - -| members | roles | -|---|---| -|prod-resman-pf-0
serviceAccount|organizations/[org_id #0]/roles/serviceProjectNetworkAdmin
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) | - ## Folder sandbox | members | roles | @@ -99,30 +87,27 @@ Legend: + additive, conditional. |gcp-security-admins
group|[roles/viewer](https://cloud.google.com/iam/docs/understanding-roles#viewer) | |prod-resman-sec-0
serviceAccount|[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) | -## Folder team a - -| members | roles | -|---|---| -|team-a
group|[roles/viewer](https://cloud.google.com/iam/docs/understanding-roles#viewer) | -|prod-teams-team-a-0
serviceAccount|[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin)
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) | - -## Folder team b - -| members | roles | -|---|---| -|prod-teams-team-b-0
serviceAccount|[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin)
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) | - ## Folder teams | members | roles | |---|---| |prod-resman-teams-0
serviceAccount|[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin)
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) | +## Folder teams test + +| members | roles | +|---|---| +|prod-teams-teams-test-0
serviceAccount|[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin)
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) | + ## Project prod-iac-core-0 | members | roles | |---|---| +|dev-pf-resman-pf-1
serviceAccount|[roles/logging.logWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.logWriter) +| |dev-resman-dp-1
serviceAccount|[roles/logging.logWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.logWriter) +| |dev-resman-gke-1
serviceAccount|[roles/logging.logWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.logWriter) +| +|prod-pf-resman-pf-1
serviceAccount|[roles/logging.logWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.logWriter) +| +|prod-resman-dp-1
serviceAccount|[roles/logging.logWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.logWriter) +| |prod-resman-gke-1
serviceAccount|[roles/logging.logWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.logWriter) +| |prod-resman-net-1
serviceAccount|[roles/logging.logWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.logWriter) +| +|prod-resman-sec-1
serviceAccount|[roles/logging.logWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.logWriter) +| diff --git a/fast/stages/01-resman/outputs-files.tf b/fast/stages/01-resman/outputs-files.tf index 5efad294..bd281d45 100644 --- a/fast/stages/01-resman/outputs-files.tf +++ b/fast/stages/01-resman/outputs-files.tf @@ -16,23 +16,27 @@ # tfdoc:file:description Output files persistence to local filesystem. +locals { + outputs_location = try(pathexpand(var.outputs_location), "") +} + resource "local_file" "providers" { for_each = var.outputs_location == null ? {} : local.providers file_permission = "0644" - filename = "${pathexpand(var.outputs_location)}/providers/${each.key}-providers.tf" - content = each.value + filename = "${local.outputs_location}/providers/${each.key}-providers.tf" + content = try(each.value, null) } resource "local_file" "tfvars" { for_each = var.outputs_location == null ? {} : { 1 = 1 } file_permission = "0644" - filename = "${pathexpand(var.outputs_location)}/tfvars/01-resman.auto.tfvars.json" + filename = "${local.outputs_location}/tfvars/01-resman.auto.tfvars.json" content = jsonencode(local.tfvars) } resource "local_file" "workflows" { for_each = var.outputs_location == null ? {} : local.cicd_workflows file_permission = "0644" - filename = "${pathexpand(var.outputs_location)}/workflows/${replace(each.key, "_", "-")}-workflow.yaml" - content = each.value + filename = "${local.outputs_location}/workflows/${replace(each.key, "_", "-")}-workflow.yaml" + content = try(each.value, null) }