26 Apr 2021
This contribution is a new feature.
In order to understand some parts of the contribution, you have to be familiar with Terraform Cloud.
What is Terraform Cloud/Terraform Enterprise?
Terraform Cloud is a managed service providing a consistent and reliable environment to manage Terraform runs.
Here is some screenshots of what the Terraform Cloud Dashboard looks like.
How Terraform Cloud Works?
- Write: Create new infrastructure or manage existing one that you’ve already written using Terraform
- Compose: Use to manage your environments
- Plan: Create an execution
- Provision & Manage: Use Terraform as an execution platform
- Collaborate & Share: Use the to provide
Here is a schema showing the Terraform Cloud architecture.
Terraform Enterprise focuses more on large enterprises by providing a self-hosted distribution of Terraform Cloud.
Currently, a user can retrieve the
terraform.tfstate file from the following places:
tfstate+s3://: AWS S3
tfstate+http://: HTTP Endpoint
tfstate+https://: HTTPS Endpoint
The idea is to bring support for Terraform Cloud/Terraform Enterprise.
The logic is pretty straightforward as we can use the Terraform Cloud API to retrieve the current state for a given Workspace.
Note that Terraform Cloud also retains historical state versions that we can retrieve using the following endpoint.
Here is a sample request example to fetch the current state from the Workplace with the id
We will then receive a response with the following shape:
The part we are interested in is the
hosted-state-download-url attribute which provides a url from which we can download the raw state
We can then use this url with the
HTTPReader already present in driftctl which allows us to get a state from an https endpoint.
To summarize, here is the final workflow:
- Fetch hosted-state-download-url from the API with the provided
tfstate+tfcloud://WORKSPACE_ID) and the API token through the provided
HTTPReaderwith the retrieved
As said above, we will add a new IaC source to scan resources from the input Terraform statefile.
This new flag will be :
$WORKSPACE_ID representing the ID for the workspace whose current state version we want to fetch.
Define constants and Terraform Cloud types.
Define our TFCloudReader method.
NewTFCloudReader function above will be triggered when we'll use
This logic is defined in the main state backend file:
To check that our code covers the different cases correctly, we will write three tests:
- Success to fetch URL with auth header
- Fail with wrong workspaceId
- Fail with bad authentication token
We will define an array of tests in which we will iterate.
Here is the example of the success test case when we manage to recover the state correctly.
Here is the main loop in which we check that each test matches what we expected.
Retrieve your workspace ID and API token from your Terraform Cloud account.
We can now scan our resource with the command:
Which in my case gives the following output telling me that 9 resources are not covered by IaC.
The majority of the problems I encountered were related to Golang. It's not a language I am familiar with so I often had to go back and forth between my IDE and the docs.
This was my first contribution in Golang and also the first one using Terraform Cloud.