Crossplane 101 & GCP ( GCP Organisation Policy using Upbound Terraform Provider) : Part 2

Bhavishya Gupta
Google Cloud - Community
4 min readJun 25, 2023

--

This blog is a second blog of 2 blogs deploy Organisation policies in using terraform crossplane provider. The purpose of doing so , is because upbound does not have any CRD’s for organization policies in GCP. In the first blog we talked about the basics of crossplane and the setup of crossplane gcp provider.

Lets drill down in weeds of Organisation Polciy implementation using crossplane upbound terraform provider on GCP.

Step 1: We will install upbound terraform provider on the same crossplane cluster which has the gcp provider installed as part of blog 1. Create the provider file as below and apply the configurations using kubectl apply -f provider.yaml.

apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
name: provider-terraform
spec:
package: xpkg.upbound.io/upbound/provider-terraform:v0.7.0

Step2 : Create a Service Accout and download a JSON file. We will use it to create a secret which will be then consumed by the provider. The same steps have been done in blog 1. Please refer for the same.

kubectl create secret generic tf-gcp-creds -n crossplane-system \
--from-file=credentials=./gcp-credentials.json

Step3 : Configure provderconfig as per the details below manifests and apply the configurations.

apiVersion: tf.upbound.io/v1beta1
kind: ProviderConfig
metadata:
name: default
spec:
credentials:
- filename: gcp-credentials.json
source: Secret
secretRef:
namespace: upbound-system
name: tf-gcp-creds
key: credentials
configuration: |
provider "google" {
credentials = "gcp-credentials.json"
project = "YOUR-GCP-PROJECT-ID"
}

// Modules _must_ use remote state. The provider does not persist state.
terraform {
backend "kubernetes" {
secret_suffix = "providerconfig-default"
namespace = "upbound-system"
in_cluster_config = true
}
}

Update <YOUR-GCP-PROJECT-ID> with your gcp project id.

Step 4: Lets create a simple GCS bucket using the terraform code for the GCS bucket creation as below.

apiVersion: tf.upbound.io/v1beta1
kind: ProviderConfig
metadata:
name: default
spec:
credentials:
- filename: gcp-credentials.json
source: Secret
secretRef:
namespace: crossplane-system
name: tf-gcp-creds
key: credentials
configuration: |
provider "google" {
credentials = "gcp-credentials.json"
project = "YOUR-GCP-PROJECT-ID"
}

// Modules _must_ use remote state. The provider does not persist state.
terraform {
backend "kubernetes" {
secret_suffix = "providerconfig-default"
namespace = "crossplane-system"
in_cluster_config = true
}
}

Update <YOUR-GCP-PROJECT-ID> with your gcp project id.

Upon applying the above manifest you will see a bucket created in GCP using Terraform provider for crossplane.

You can also describe the bucket to see if any error appears while bucket provisioning using below command:

kubectl describe workspace.tf.upbound.io/example-inline

Validate the bucket creation from the console.

Step 6 : Now Lets apply a sample organisation policy which is “Skip Default Network Creation” on our organisation. This policy skips the default network creation whenever any new resource us create For Example: Project.

Use the manifest below:

##### Organization Policies #########################
# Implementes "Skip Default Network Creation" Organisation Policy
# when creating a new Project
# Required Service Account Role is
# "Organization Policy Administrator(roles/orgpolicy.policyAdmin)" at Organisation level
#####################################################


apiVersion: tf.upbound.io/v1beta1
kind: Workspace
metadata:
name: org-policy-skipnetwork
spec:
forProvider:
source: Inline
module: |
variable "orgid" {
}

resource "google_organization_policy" "skip_network" {
org_id = var.orgid
constraint = "compute.skipDefaultNetworkCreation"

boolean_policy {
enforced = true
}
}
vars:
- key: orgid
value: "<YOUR ORG ID>"

Replace <YOUR ORG ID> with Organisation ID.

Once you apply Organization policy, validate the same form console.

The policy is enforced, and any new project will skip the default network creation.

Note : You must either use remote state or ensure the provider container’s /tf directory is not lost. provider-terraform does not persist state; consider using the Kubernetes remote state backend. More details can be found on Github page.

--

--