Credits: Onkar Naik

Terraform As A Service: Google Infrastructure Manager

Onkar Naik
Google Cloud - Community
9 min readNov 1, 2023

--

What is Google Infrastructure Manager?

Source: Google

Infrastructure Manager is a GCP-managed service that automates the deployment and management of Google Cloud infrastructure resources.

Infrastructure is defined using Terraform and deployed onto Google Cloud by Infra Manager, enabling you to manage GCP resources using Terraform as a service.

Infra Manager for IAC Lifecycle Management

  1. You can keep the Terraform code or configuration, either in a public Git repository, in a Cloud Storage bucket, or in a local machine.
  2. Infra Manager keeps the versioning of every terraform deployment by creating revisions of the deployments.
  3. For every revision, Infra Manager stores the Logs, terraform source code, Artifacts, and state files in a cloud storage bucket.

Infra Manager Workflow

  1. Creating Infra Manager deployment using gcloud CLI to deploy resources from terraform code.
  2. Infra Manager takes the request and creates a cloud build trigger to perform terraform init | validate | plan and apply stages.

Infra Manager Terraform Constraints

  1. Templating or generation of Terraform is not supported.
  2. The configuration should be using Terraform version 1.2.3.
  3. Backend blocks shouldn’t be defined.
  4. Provisioners are not supported.

Infra Manager Pricing

Infrastructure Manager charges for Cloud Build execution and Cloud Storage of source code + logs blueprints.

Infra Manager In Action

In this article, we will be deploying sample GCS buckets using Google Infra Manager.

Prerequisite

  1. Google Cloud Project

As a part of the prerequisite, we already have an active GCP Project where we can use the GCP Infra manager to provision the GCP resources.

Enabling Infra Manager Service API

Before getting started with GCP Infra Manager we need to enable the Infra Manager service API for the GCP Project.

gcloud services enable config.googleapis.com

Authentication for Infra Manager Deployments

In order to create Infra Manager deployment the service account used for deploying the resources defined in the terraform code needs to have a config agent role.

  1. Create the service account (If you do not have one already)
gcloud iam service-accounts create SERVICE_ACCOUNT_NAME

2. Grant the roles/config.agent IAM role to the service account:

gcloud projects add-iam-policy-binding PROJECT_ID --member="serviceAccount:SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com" --role=roles/config.agent
IAM bindings for Terraform/Infra Manager service account

3. Grant the additional required permissions for deploying the resources described in the terraform code.

gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com \
--role=storage.Admin // for creating GCS buckets

Creating Infra Manager Deployment

Below are the respective commands for creating Infra Manager deployments based on source code location.

  1. Deploy a Terraform configuration stored in a Cloud Storage bucket
gcloud alpha infra-manager deployments apply projects/PROJECT_ID/locations/LOCATION/deployments/DEPLOYMENT_ID \
--service-account projects/SERVICE_ACCOUNT_PROJECT_ID/serviceAccounts/SERVICE_ACCOUNT \
--gcs-source gs://BUCKET_NAME/OBJECT_NAME \
--input-values=INPUT_1_NAME=VALUE,INPUT_2_NAME=VALUE

2. Deploy a Terraform configuration stored in a public Git repository

gcloud alpha infra-manager deployments apply projects/PROJECT_ID/locations/LOCATION/deployments/DEPLOYMENT_ID \
--service-account projects/SERVICE_ACCOUNT_PROJECT_ID/serviceAccounts/SERVICE_ACCOUNT \
--git-source-repo="GIT_REPO" \
--git-source-directory="DIRECTORY" \
--git-source-ref="REF" \
--input-values=INPUT_1_NAME=VALUE,INPUT_2_NAME=VALUE

3. Deploy a Terraform configuration stored on your local machine

gcloud alpha infra-manager deployments apply projects/PROJECT_ID/locations/LOCATION/deployments/DEPLOYMENT_ID \
--service-account projects/SERVICE_ACCOUNT_PROJECT_ID/serviceAccounts/SERVICE_ACCOUNT \
--local-source="LOCAL_DIRECTORY" \
--input-values=INPUT_1_NAME=VALUE,INPUT_2_NAME=VALUE

In our case, we have the terraform source code (root+calling modules) stored in a public git repository.

Note: Currently Infra Manager only supports public git repositories.

calling module
Infra Manager Deployment for GCS bucket creation

We can also see the cloud build trigger created by Infra Manager at the backend for deploying the terraform code.

Infra Manager Cloud Build trigger output

After Infra Manager terraform deployment we can see that the sample GCS bucket has been provisioned successfully.

GCS Bucket provisioned by Infra Manager deployment

Infra Manager creates a storage bucket in the project and location where Infra Manager is run. Currently, the supported locations include asia-east1, europe-west1, and us-central1.

After the deployment is created, the Infrastructure Manager artifacts are in this storage bucket which has the name in the format: gs://PROJECT_ID-LOCATION-blueprint-config.

The artifacts in the blueprint storage bucket include:

  • Cloud Build logs.
  • Terraform logs.
  • A copy of the Terraform configuration.
Infra Manager Blueprint Storage Bucket

Infra Manager Deployment Revisions

For every terraform run Infra Manager deployment creates revisions to keep versioning.

When you initially create a deployment, this deployment is also a revision and has the revision ID r-0.

If you update the deployment(Terraform code modification), then Infrastructure Manager creates a new revision with an identifier(revision ID)r-1. For every new revision, the identifier increases by one.

Infra Manager Deployment Revisions

Now, Let's create a new GCS bucket named gcp-infra-manager-bucket-2 using Infra Manager deployment. This will create a new revision of Infra manager deployment named gcs-deployment.

gcloud alpha infra-manager deployments apply projects/onkar-17-cloud/locations/us-central1/deployments/gcs-deployment\
--service-account projects/onkar-17-cloud/serviceAccounts/infra-manager-gcp@onkar-17-cloud.iam.gserviceaccount.com\
--git-source-repo=https://github.com/Onkar179/google-infra-manager-repo \
--git-source-directory=gcs-buckets \
--git-source-ref=main \
--input-values=name=gcp-infra-manager-bucket-2

You can also check & view the deployments, revisions & state of the resources that have been deployed by the Infra Manager.

Listing Infra Manager deployment

gcloud alpha infra-manager deployments list --project PROJECT_ID --location "LOCATION"
Infra Manager deployment list

Checking Infra Manager deployment state

The Infra Manager deployments have several states from which the status of deployment can be checked.

gcloud alpha infra-manager deployments describe projects/PROJECT_ID/locations/LOCATION/deployments/DEPLOYMENT_ID
Infra Manager deployment state

Listing revisions in a deployment

gcloud alpha infra-manager revisions list --deployment=projects/PROJECT_ID/locations/LOCATION/deployments/DEPLOYMENT_ID
Infra Manager deployment revisions

Checking the State of a revision in a deployment

gcloud alpha infra-manager revisions describe projects/PROJECT_ID/locations/LOCATION/deployments/DEPLOYMENT_ID/revisions/REVISION_ID
Infra Manager deployment revision state
Infra Manager deployment revision state

Listing the resources provisioned by deployment under a particular revision

Similar to deployments each revision has several states given below from which the status of resource provisioning can be checked.

STATE_UNSPECIFIED, PLANNED, IN_PROGRESS, RECONCILED, FAILED

gcloud alpha infra-manager resources list --revision=projects/PROJECT_ID/locations/LOCATION/deployments/DEPLOYMENT_ID/revisions/REVISION_ID
Infra Manager deployment revisions resources

Checking details of deployed resources

The below command requires Resource ID which you can get from the above command while listing out the resources.

gcloud alpha infra-manager resources describe projects/PROJECT_ID/locations/LOCATION/deployments/DEPLOYMENT_ID/revisions/REVISION_ID/resources/RESOURCE_ID
Infra Manager deployment resources state

Managing Terraform states with Infra Manager

Source: spacelift.io/

Google Infra Manager does support terraform state modification & inspection for each deployment & revision by which we can do state mutation or import the states of manually created resources for managing those resources using Google Infra Manager.

For importing the terraform state of any manually created resource into the Infra Manager managed terraform state, first we need to lock the Infra Manager deployment and download the state file locally.

  1. Lock the deployment

Lock the deployment to prevent any changes to the deployment while you mutate the state file. The deployment must be locked to be able to download the state file.

gcloud alpha infra-manager deployments lock DEPLOYMENT_ID --project PROJECT_ID --location LOCATION
locked Infra Manager deployment

2. Download the state file

Downloading state files requires a blueprint cloud storage bucket signed URL.

SIGNED_STATE_DOWNLOAD_URL=$(gcloud alpha infra-manager deployments export-statefile DEPLOYMENT_ID --project PROJECT_ID --location LOCATION --format="get(signedUri)")
curl -s -X GET --output terraform.tfstate ${SIGNED_STATE_DOWNLOAD_URL}

Once the state file is downloaded you can place it under local terraform code workspace and perform state import.

Here we have one bucket named onkar-datathat is manually created in our GCP project. Going forward, In order to manage it using Infra Manager we need to import the state of that bucket in the Infra Manager deployment state that we downloaded above.

Importing the terraform state

terraform state import block
terraform plan
terraform plan
terraform apply

After the successful state import, if you have made changes to terraform code files locally then have to upload the modified terraform code to the storage bucket, or public git repository that you are using as the source to deploy the configuration.

In our case, it is a public git repository so have to push the updated terraform code for onkar-data GCS bucket, so that Infra Manager will sync the updated source code with the updated state in order to manage new resources.

Upload back the terraform state file to the Infra Manager storage bucket

  1. Getting the lock ID of Infra Manager deployment to unlock
LOCK_ID=$(gcloud alpha infra-manager deployments export-lock DEPLOYMENT_ID --project PROJECT_ID --location LOCATION --format="get(lockId)"

2. Uploading the modified/imported state file

SIGNED_STATE_UPLOAD_URL=$(gcloud alpha infra-manager deployments import-statefile DEPLOYMENT_ID --project PROJECT_ID --location LOCATION --lock-id ${LOCK_ID} --format="get(signedUri)")

curl -s -X PUT --upload-file terraform.tfstate $SIGNED_STATE_UPLOAD_URL
terraform state bucket signed URL

3. Unlock the Infra Manager deployment

LOCK_ID=$(gcloud alpha infra-manager deployments export-lock DEPLOYMENT_ID --project PROJECT_ID --location LOCATION --format="get(lockId)")

gcloud alpha infra-manager deployments unlock DEPLOYMENT_ID --project PROJECT_ID --location LOCATION --lock-id ${LOCK_ID}
Unlocked Infra Manager deployment

Once the deployment is unlocked & after successful terraform state import, the Infra Manager also manages the manually created bucket onkar-data along with gcp-infra-manager-bucket-2 .

Deleting the Infra Manager Deployment

Source: Google
  1. Delete the deployment and provisioned resources
gcloud alpha infra-manager deployments delete projects/PROJECT_ID/locations/LOCATION/deployments/DEPLOYMENT_ID

2. Delete the deployment by keeping resources undeleted

Google Infra Manager also supports deletion of deployment by keeping the provisioned resources undeleted.

This can be useful in scenarios where you want to manage the resources manually not using IAC for which you can only delete the deployment.

gcloud infra-manager deployments delete projects/PROJECT_ID/locations/LOCATION/deployments/DEPLOYMENT_ID \
--delete-policy=abandon

Why Google Infra Manager? Why not just run Terraform directly?

Source: Google

Google Infrastructure Manager Vs Terraform

Google Infra Manager provides the below features in addition to using Terraform locally, which makes it more useable as Terraform as a service.

  1. Provides history or traceability of all deployments
  2. Role-based access control for each deployment & revisions
  3. Governance and auditing controls
  4. Secured storage of terraform state files (SIGNED URLs)
  5. UI and Observability

Conclusion

With Infrastructure Manager, users can create templates, version their infrastructure configurations, and deploy resources consistently, promoting scalability, agility, and resource optimization.

This tool streamlines infrastructure management and enhances the overall efficiency and reliability of operations on Google Cloud.

🔗 References

  1. Demo Source Code: https://github.com/Onkar179/google-infra-manager-repo.git
  2. Infra Manager Documentation: https://cloud.google.com/infrastructure-manager/docs/

🤔 Questions?

If you have any questions, I’ll be happy to read them in the comments. Follow me on Medium or LinkedIn for more interesting content.

😃 Try out the Infra Manager deployments & let me know your experience or use cases in the comments.

🚀 Let’s connect and embark on a transformative cloud journey together!

Source: Google

--

--