SaFi Bank Space : Create New GCP & TFC projects via dispatcher

Overview

  • Dispatcher

  • Terraform cloud

    • SaFi terraform workspaces: https://app.terraform.io/app/safi/workspaces

      • Keeping TF-resources in separate workspaces allows to modify resources in each workspace independently from resources in other workspaces.

      • Each workspace has its own running-agents => it allows to run plan and apply for each workspace in separate thread and also independently.

  • GCP projects

Create new GCP projects and TFC workspaces with terraform procedure

  1. github.com/SafiBank/SaFiMono -> devops/terraform/tf-dispatcher/_files/new_projects.yaml:

    • add new-project yaml-structure:

      projects:
        ## your project name
        new-project-name:
          subprojects:
            - infra  ## if defined - create workspace for 'infrastructure' tf-resources
            - config ## if defined - create workspace for 'configuration' tf-resources
          variables: ## necessary to specify which variables your workspace will use, can't be left empty
            infra: [argo, shared_vpc_creds] ## example variables for Infra projects 
            config: [slack] ## example variables for Config projects
          tfc:
            enabled: true ## if 'true' - enable tfc-workspaces creation
          gcp:
            enabled: true ## if 'true' - enable gcp-project creation
            apis:
              - %list%
              - %of%
              - %gcp-apis%
              - %to enable%
              - %in current project%
            sa_roles:
              - roles/owner ## serviceaccount role; set 'owner' so tfc-workspace will have permissions to create resource in proper gcp-project

      e.g:

        monitor:
          subprojects:
            - infra
            - config
          variables:
            infra: [argo, shared_vpc_creds]
            config: [slack]
          tfc:
            enabled: true
          gcp:
            enabled: true
            apis:
              - iam.googleapis.com
              - dns.googleapis.com
              - compute.googleapis.com
              - servicenetworking.googleapis.com
              - cloudresourcemanager.googleapis.com
              - container.googleapis.com
              - iap.googleapis.com
              - monitoring.googleapis.com
              - cloudkms.googleapis.com
              - logging.googleapis.com
            sa_roles:
              - roles/owner

      (warning) If new project is supposed to contain only config-resources:
      - do not add - infra subproject
      - set gcp.enabled: false (warning)

    • commit changes, TF plan, TF apply

  2. github.com/SafiBank/SaFiMonodevops/terraform/:

    • create folders for your projects; name folders according to next templates:

      • tf-env-%project-name%-config
        example: tf-env-monitor-config

      • tf-env-%project-name%-infra
        example: tf-env-monitor-infra

  3. github.com/SafiBank/SaFiMonodevops/terraform/tf-dispatcher/tfc_users.tf:

    1. in resource "tfe_team" "teams" add new teams which correspond to new tfc-workspaces, e.g (for monitor workspaces):

      resource "tfe_team" "teams" {
        for_each = { 
                      for item in concat(
                        ["dispatcher", "cicd", "repos", "all-readonly"],
                        [for d in local.safi_dns_domains : format("dns-%s", d)],
                        [for e in keys(local.safi_environments) : format("env-%s", e)],
                        [for g in keys(local.safi_environments) : format("env-%s-data", g)],
                        ...
                        [for l in keys(local.safi_environments) : format("env-%s-monitor-config", l)], ## <- for `config` workspace
                        [for m in keys(local.safi_environments) : format("env-%s-monitor-infra", m)],  ## <- for `infra` workspace
                      ) : item => "" 
                    }
      
        name         = format("%s-%s", local.prefix, each.key)
        organization = var.tfe_organization
      }

    2. create resource "tfe_team_access" to apply “write“ access for teams created in step 3.a to proper tfc-workspaces, e.g (for monitor workspaces):

      ## monitoring #########################
      resource "tfe_team_access" "monitor_config" {   ## <- for `config` workspace
        for_each = toset(keys(local.safi_environments))
      
        access       = "write"
        team_id      = tfe_team.teams[format("env-%s-monitor-config", each.key)].id
        workspace_id = module.environment_tfe_workspace_new[format("%s-monitor-config", each.key)].workspace_id
      }
      
      resource "tfe_team_access" "monitor_infra" {    ## <- for `infra` workspace
        for_each = toset(keys(local.safi_environments))
      
        access       = "write"
        team_id      = tfe_team.teams[format("env-%s-monitor-infra", each.key)].id
        workspace_id = module.environment_tfe_workspace_new[format("%s-monitor-infra", each.key)].workspace_id
      }
      #######################################

    3. commit changes, TF plan, TF apply

  4. In Terraform-cloud - https://app.terraform.io/app/safi/workspaces:

    1. Check that proper workspaces are created, e.g.:

    2. Manually add extra variables if required


      1. (warning) Don’t forget to add permissions to your account to new projects in devops/terraform/_files/users_devops.yaml, e.g:

        - name: "Sergei Teteriukov"
            email: sergei.teteriukov@vacuumlabs.com
            gcp_email: sergei.teteriukov@vacuumlabs.com
            terraform_cloud:
              teams:
                - ...
                - env-dev-monitor-config ## <-
                - env-dev-monitor-infra  ## <-
            gcp:
              projects_iam:
                - ...
                - project: safi-env-dev-monitor
                  roles:
                    - roles/editor

        → commit changes → tf plan → tf apply in dispatcher workspace;
        Otherwise you won’t be able to add variables and apply changes with terraform apply (warning)