HCP Terraform Cloud is a managed service presented by HashiCorp that permits users to run Terraform in a cloud-based environment. It provides a protected, scalable, and collaborative platform for infrastructure organizational automation.
HCP Terraform Cloud proposes numerous benefits, including:
Enhanced Teamwork Collaboration: Allows teams to work together and organized on infrastructure automation.
Scalability: Scales to meet the requirements of large organizations.
Easy Infrastructure Management: Offloads Terraform management to a cloud-based facility.
Amplified safety and Security: Delivers enterprise-grade security features and compliance.
Here are few key features of HCP Terraform Cloud:
Team work Collaboration: Multiple users and different organizations can team up and collaborate on Terraform configurations and state files.
Workspace Management: Lets you work with multiple workspaces, allowing distinct infrastructures for testing, development, pre-staging, and production.
State file Management: Securely stores and manages Terraform state files.
CLI and API: Offers a REST API and CLI for automation and integration with CI/CD pipelines.
Managed Terraform: HCP Terraform Cloud runs Terraform for you, eradicating the need to manage infrastructure and scalability.
Security: Proposes enterprise-grade security features, audit logging, access controls and including encryption.
Policy as Code: Integrates with HashiCorp's Sentinel for policy enforcement and compliance.
Version Control: Fit in with version control systems like GitLab, Bitbucket and GitHub.
HCP Terraform Cloud is appropriate for organizations that want to adopt infrastructure as code (IaC) practices, improve collaboration and security and automate infrastructure provisioning.
In this article I will configure Hashicorp (HCP) Terraform cloud. Here is Terraform cloud URL https://app.terraform.io/session, open it in the browser. Create an account on the portal. I am creating a free account here. Below are the key points while considering free account.
Team Members: Limited to 5 team members.
Support: Limited to online resources and community support (no priority support).
State File Size: Limited to 100MB per state file.
Runs: Limited to 100 runs per month (combined for all workspaces).
Workspaces: Limited to 5 workspaces.
Provide details to create a new account such as username, valid email id, password, checkboxes to agree and acknowledge terms and privacy policy. Click Create account.
After clicking Create account button, you will received confirmation link on the email box you provided. Click on the url in the email and verify account. Next click on the Create Organization. In Terraform Cloud, an organization is a top-level entity that represents a company, team, or group of users. It serves as a container for multiple workspaces, teams, and users
Provide a name to Organization name and click Create organization button. In my case name it is vcloudlab. Following It will land on to Workspaces view, I will leave this part for now as foundation account setup and configuration of HCP Terraform cloud is completed.
Next prepare your system and run command terraform login on the terminal. Which will ask you to login to HCP Terraform cloud by opening a login url in browser.
Just note encrypted token credentials will be stored under file C:\Users\kunal\AppData\Roaming\terraform.d\credentials.tfrc.json, proceed yes. For token check following screenshot after this next screenshot.
Once CLI login is successful, It will land onto API token page. Here Create a new user token. Provide description and Expiration time for the token and click Generate token. Copy the token then return to your terminal as shown in above screenshot and paste it into your Terraform login prompt (When you copy it doesn't show any value on the screen and hit enter). HCP Terraform will not display this token again. so store it securely.
Terraform login to cloud is successful. Here I just want to show the difference when you run terraform init on local backend vs terraform cloud backend. In the first initialization it is configuring local tfstate file. When I add terraform cloud block to my configuration tf file and run terraform init again, I see initialization to HCP terraform successful in the message. Note: I need to provide organization name which I created earlier. In the workspaces provide the workspace it will create inside organization.
terraform { cloud { #hostname = "app.terraform.io" organization = "vcloudlab" workspaces { name = "vcloud-lab-dev" } } }
Below is the complete sample terraform configuration code for Azure resource group for testing.
terraform { cloud { #hostname = "app.terraform.io" organization = "vcloudlab" workspaces { name = "vcloud-lab-dev" } } } ############################################# provider "azurerm" { features {} #subscription_id = "9exxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" } ############################################# variable "name" { type = string description = "Provide Resource Group Name" default = "dev-rg" } variable "location" { type = string description = "Provide Resource Group Location" default = "east us" } ############################################# resource "azurerm_resource_group" "example" { name = var.name location = var.location }
All looks good here so far, next I will run a plan, which will be executed on terraform cloud. But it will fail as expected with Error: unable to build authorizer for Resource Manager API: could not configure AzureCli Authorizer: could not parse Azure CLI version: launching Azure CLI: exec: "az": executable file not found in $PATH.
This error occurring because, when I run terraform plan, local azure credentials authentication (Az login) information is not passed to HashiCorp HCP cloud and need to mention them separately on the cloud for authentication and authorization.
Just to be noted, when you ran terraform init it created workspace with the name provided inside terraform cloud block.
To store and configure service principal credentials securely on Terraform Cloud, go to organization settings. Navigate to Variable sets to Create New Variable sets.
Configure a Name for new variable set. Click Apply globally (All current and future workspaces in this organization will access this variable set). And click Add variable.
In the Add variable provide key value pair for below Azure infrastructure and service principal information for authentication purpose. Make sure you are selecting Environment variable instead Terraform variables. Environment variable are available in the terraform runtime environment.
ARM_CLIENT_ID
ARM_CLIENT_SECRET
ARM_SUBSCRIPTION_ID
ARM_TENANT_ID
You can make the value sensitive to hide them from seeing. Once you feed all the information don't forget to click Create variable set to save the variable set.
Once you save the Variable sets with required credentials key value pair information. It looks like below as per the screenshot.
Next try running terraform plan command from terminal again. This time it is all good and output is successful.
On the HCP terraform cloud portal, I see There is job executed by user, Status is planned and finished with success.
If I drill down and click the plan for more information. It shows the what is planned to deploy on Azure cloud.
My plan is successful, now I will run terraform apply --auto-approve to deploy the actual resources. It is also successful, I see the result output on terminal as well as in terraform cloud portal.
Another thing to note if I see States inside Workspaces I can see tfstate is created successfully and local tfstate is not created. If I am migrating tfstate will be blanked out or emptied.
Below is the complete code execution output.
1: terraform login
2: Terraform will request an API token for app.terraform.io using your browser.
3: If login is successful, Terraform will store the token in plain text in
4: the following file for use by subsequent commands:
5: C:\Users\\AppData\Roaming\terraform.d\credentials.tfrc.json
6: Do you want to proceed?
7: Only 'yes' will be accepted to confirm.
8: Enter a value: yes
9: ---------------------------------------------------------------------------------
10: Terraform must now open a web browser to the tokens page for app.terraform.io.
11: If a browser does not open this automatically, open the following URL to proceed:
12: https://app.terraform.io/app/settings/tokens?source=terraform-login
13: ---------------------------------------------------------------------------------
14: Generate a token using your browser, and copy-paste it into this prompt.
15: Terraform will store the token in plain text in the following file
16: for use by subsequent commands:
17: C:\Users\\AppData\Roaming\terraform.d\credentials.tfrc.json
18: Token for app.terraform.io:
19: Enter a value:
20: Retrieved token for user vcloud-lab
21: ---------------------------------------------------------------------------------
22: -
23: ----- -
24: --------- --
25: --------- - -----
26: --------- ------ -------
27: ------- --------- ----------
28: ---- ---------- ----------
29: -- ---------- ----------
30: Welcome to HCP Terraform! - ---------- -------
31: --- ----- ---
32: Documentation: terraform.io/docs/cloud -------- -
33: ----------
34: ----------
35: ---------
36: -----
37: -
38: New to HCP Terraform? Follow these steps to instantly apply an example configuration:
39: $ git clone https://github.com/hashicorp/tfc-getting-started.git
40: $ cd tfc-getting-started
41: $ scripts/setup.sh
42: PS D:\Projects\Terraform\\extreme_examples\02-Terraform_Cloud>
43: PS D:\Projects\Terraform\\extreme_examples\02-Terraform_Cloud_Backend> terraform init
44: Initializing the backend...
45: Initializing provider plugins...
46: - Finding latest version of hashicorp/azurerm...
47: - Installing hashicorp/azurerm v4.0.1...
48: - Installed hashicorp/azurerm v4.0.1 (signed by HashiCorp)
49: Terraform has created a lock file .terraform.lock.hcl to record the provider
50: selections it made above. Include this file in your version control repository
51: so that Terraform can guarantee to make the same selections by default when
52: you run "terraform init" in the future.
53: Terraform has been successfully initialized!
54: You may now begin working with Terraform. Try running "terraform plan" to see
55: any changes that are required for your infrastructure. All Terraform commands
56: should now work.
57: If you ever set or change modules or backend configuration for Terraform,
58: rerun this command to reinitialize your working directory. If you forget, other
59: commands will detect it and remind you to do so if necessary.
60: PS D:\Projects\Terraform\\extreme_examples\02-Terraform_Cloud_Backend>
61: PS D:\Projects\Terraform\\extreme_examples\02-Terraform_Cloud_Backend>
62: PS D:\Projects\Terraform\\extreme_examples\02-Terraform_Cloud_Backend>
63: PS D:\Projects\Terraform\\extreme_examples\02-Terraform_Cloud_Backend> terraform init
64: Initializing HCP Terraform...
65: Initializing provider plugins...
66: - Reusing previous version of hashicorp/azurerm from the dependency lock file
67: - Using previously-installed hashicorp/azurerm v4.0.1
68: HCP Terraform has been successfully initialized!
69: You may now begin working with HCP Terraform. Try running "terraform plan" to
70: see any changes that are required for your infrastructure.
71: If you ever set or change modules or Terraform Settings, run "terraform init"
72: again to reinitialize your working directory.
73: PS D:\Projects\Terraform\\extreme_examples\02-Terraform_Cloud_Backend>
74: PS D:\Projects\Terraform\\extreme_examples\02-Terraform_Cloud_Backend>
75: terraform plan
76: Running plan in HCP Terraform. Output will stream here. Pressing Ctrl-C
77: will stop streaming the logs, but will not stop the plan running remotely.
78: Preparing the remote plan...
79: To view this run in a browser, visit:
80: https://app.terraform.io/app/vcloudlab/vcloud-lab-dev/runs/run-j3P94WJVwbcfs3ke
81: Waiting for the plan to start...
82: Terraform v1.9.2
83: on linux_amd64
84: Initializing plugins and modules...
85: ╷
86: │ Error: unable to build authorizer for Resource Manager API: could not configure AzureCli Authorizer: could not parse Azure CLI version: launching Azure CLI: exec: "az": executable file not found in $PATH
87: │
88: │ with provider["registry.terraform.io/hashicorp/azurerm"],
89: │ on main.tf line 12, in provider "azurerm":
90: │ 12: provider "azurerm" {
91: │
92: ╵
93: Operation failed: failed running terraform plan (exit 1)
94: ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
95: Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
96: terraform plan
97: Running plan in HCP Terraform. Output will stream here. Pressing Ctrl-C
98: will stop streaming the logs, but will not stop the plan running remotely.
99: Preparing the remote plan...
100: To view this run in a browser, visit:
101: https://app.terraform.io/app/vcloudlab/vcloud-lab-dev/runs/run-XfvHYjwQDCsvGUxf
102: Waiting for the plan to start...
103: Terraform v1.9.2
104: on linux_amd64
105: Initializing plugins and modules...
106: Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
107: + create
108: Terraform will perform the following actions:
109: # azurerm_resource_group.example will be created
110: + resource "azurerm_resource_group" "example" {
111: + id = (known after apply)
112: + location = "eastus"
113: + name = "dev-rg"
114: }
115: Plan: 1 to add, 0 to change, 0 to destroy.
116: ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
117: Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
Useful Articles
Hashicorp Terraform map and object inside module and variable example
Terraform one module deploy null or multiple resources based on input
Terraform A reference to a resource type must be followed by at least one attribute access, specifying the resource name
Terraform fore_each for loop filter with if condition example
Terraform remote-exec provisioner with ssh connection in null_resource
Terraform count vs for_each for examples with map of objects
Terraform one module deploy null or multiple resources based on input (nested for loop) Example of Terraform functions flatten() and coalesce()
Terraform Azure Create Private Endpoint to existing Storage Account with Custom Private DNS zone record link
Creating a Private Endpoint for Azure Storage Account with required sub services using Terraform Example Terraform functions of lookup() and lower()
Using element function with count meta argument example Terraform Azure subnets Example Terraform functions of element(), count() and sum()
Terraform create Azure Virtual Network subnets from map of object and show name in the header Header name change in the output
Creating a Private Endpoint for Azure Storage Account with Terraform example 2 Example of for_each with toset() function
Creating a Private Endpoint for Azure Storage Account with Terraform example 3