Skip to content

Commit

Permalink
Merge pull request #82 from bcgov/feat/57-tf-bootstrap-migration
Browse files Browse the repository at this point in the history
chore/57 tf bootstrap migration
  • Loading branch information
dleard authored Jan 16, 2024
2 parents 300ae0b + b7147cc commit 0da2da5
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 0 deletions.
1 change: 1 addition & 0 deletions .env-example
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ GH_DEVELOPERS_TEAM=<The GitHub team for devs>
OC_PROJECT_PREFIXES=<Comma-separated list of openshift namespace prefixes>
VALUES_FILE_PATH=<Path to values file (with filename)>
MONITORING_VALUES_FILE_PATH=<Path to monitoring values file (with filename)>
GCP_PROJECT=<The Google Cloud platform project where TF buckets are created>

# Airflow prefixes and dockerhub account info are now in a helm value chart ./helm/cas-provision/values.yaml
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ authorize:
.PHONY: provision
provision:
$(call oc_whoami)
@@source .env; ./lib/gcs_terraform_buckets.sh -pp $$OC_PROJECT_PREFIXES -gcp $$GCP_PROJECT
@@source .env; ./lib/helm_deploy.sh -pp $$OC_PROJECT_PREFIXES -c ./helm/cas-provision/ -n cas-provision -v $$VALUES_FILE_PATH

.PHONY: provision_artifactory
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ Deploys the [`cas-provision` helm chart] to every namespace used by the team. Th
- a DockerHub registry credential
- a `SysdigTeam` object, which is a custom resource created by platform services to grant access to the Sysdig monitoring platform.
- various secrets containing credentials used by our applications
- Utilizing `gcp` (the Google Cloud Platform CLI), creates buckets for TF state for every namespace used by the team. Relies on a being authorized with a service account (credentials stored in the team's password manager) with storage permissions on the project.
- **Note**: `gcp` will give errors when a bucket is created *already under the service accounts control*. The script ignores these errors, as they don't need to block further buckets from being created or the rest of the make target executing.

### `make install_crunchy_monitoring`

Expand All @@ -52,3 +54,10 @@ Lints the [`crunchy-monitoring` helm chart]
Prior to using Helm to deploy applications to the OpenShift cluster, the CAS team used a set of common `make` commands (e.g. `configure`, `build`, `install`) that abstracted the `oc` command line tool. These came with various utility functions located in the `*.mk` files, which are still in use in some projects but are considered deprecated.

[least privilege principle]: https://csrc.nist.gov/glossary/term/least-privilege

## Terraform in CAS repos

See an example of our containerized Terraform process in an OpenShift job that is integrated into a the 'cas-registration' Helm chart. It deploys at the pre-install, pre-upgrade hooks. The Terraform scripts are located in the `/terraform` subdirectory in the chart, which is then pulled in via a ConfigMap utilized by the job at `/templates/backend/job/terraform-apply.yaml`.

- `terraform-apply.yaml`: This file defines the Job that deploys a container to run Terraform. Secrets (deployed by `make provision`) contain the credentials and `.tfbackend` Terraform uses to access the GCP buckets where it stores state. The `terraform-modules.yaml` ConfigMap is what pulls in the Terraform scripts that will be run.
- `terraform-modules.yaml`: This file defines a ConfigMap that sources terraform `.tf` files from a subdirectory in the chart. All `.tf` files in the subdirectory are pulled into the ConfigMap, which is then mounted as a Volume on the container created in `terraform-apply.yaml`. Changes to these files are *automatically applied* when the helm chart is installed/upgraded. Currently, this is `-auto-approved`.
14 changes: 14 additions & 0 deletions helm/cas-provision/templates/terraformSecret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
kind: Secret
apiVersion: v1
metadata:
name: gcp-credentials-secret
labels:
{{ include "cas-provision.labels" . | indent 4 }}
type: Opaque
stringData:
gcp_project_id: "{{ .Values.gcpTerraform.projectId }}"
tf_backend: |
bucket = "{{ .Release.Namespace }}-state"
prefix = "terraform/state"
credentials = "/etc/gcp/credentials.json"
sa_json: {{ .Values.gcpTerraform.serviceAccountCredentials | quote }}
4 changes: 4 additions & 0 deletions helm/cas-provision/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,7 @@ airflowOAuth:
prod:
clientId: ~
clientSecret: ~

gcpTerraform:
projectId: "ggl-project-id-where-terraform-state-buckets-live"
serviceAccountCredentials: "single line string of gcp-tf-credentials.json"
71 changes: 71 additions & 0 deletions lib/gcs_terraform_buckets.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/bin/bash
set -uo pipefail

usage() {
cat << EOF
$0 [OPTIONS]
Runs the GCP CLI to provision storage buckets for Terraform usage.
The list of namespaces affected by the script is defined by the
"--project-prefixes" and "--project-suffixes" options (see below).
For instance, "--project-prefixes abc123,456qwe --project-suffixes dev,test"
would affect the following namespaces: abc123-dev, abc123-test, 456qwe-dev and 456qwe-test
Options:
-pp, --project-prefixes
The comma-separated project prefixes of the project to create buckets for. e.g. "abc123,456qwe"
-ps, --project-suffixes
The comma-separated project suffixes of the project to create buckets for. Defaults to "dev,test,prod"
-gcp, --google-cloud-project
The google cloud project id where the buckets will be created.
-gcr, --google-cloud-region
The google cloud region where the buckets will be created. Defaults to "northamerica-northeast1", in Montreal.
-h, --help
Prints this message
EOF
}

# default options
declare -a suffixes=("dev" "test" "prod")
google_region="northamerica-northeast1" # Montreal

while [[ -n ${1+x} && "$1" =~ ^- && ! "$1" == "--" ]]; do case $1 in
-pp | --project-prefixes )
shift
IFS=',' read -r -a prefixes <<< "$1"
;;
-ps | --project-suffixes )
shift
IFS=',' read -r -a suffixes <<< "$1"
;;
-gcp | --google-cloud-project )
shift
google_project=$1
;;
-gcr | --google-cloud-region )
shift
google_region=$1
;;
-h | --help )
usage
exit 0
;;
esac; shift; done



for prefix in "${prefixes[@]}"; do
for suffix in "${suffixes[@]}"; do

namespace=$prefix-$suffix
bucket="gs://${namespace}-state"
echo "Creating TF state bucket $bucket for $namespace namespace"
gcloud storage buckets create $bucket --project=$google_project --location=$google_region

done
done

0 comments on commit 0da2da5

Please sign in to comment.