Menu

Virtual Geek

Tales from real IT system administrators world and non-production environment

HashiCorp HCP Terraform Cloud backend configuration

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.

Terraform hcl hcp terraform free account username password sso create account azurerm provider azure cloud configuration hcl tfvars resources block.png

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

Terraform cloud confirm Email address organization hcl hcp terraform cloud configuration setup administration resend confirmation link azure provider azurrm workspaces io sessions.png

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.

Terraform cloud portal hashicorp projects organization creation email workspaces registry configuration managing infrastructure as code provider azurerm azure cloud portal.png

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.

HCP terraform hashicorp terraform cloud portal user name email free account app.terraform.io migrate tf state to cloud tfrc.json credentials api tocken azurerm azure configuration setup github git orgnization.png

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.

Microsoft Azure Terraform cloud configuration block hashicorp hcp terraform tokens terraform login github git expiration azurerm provider devops github git two factor authentication sessiosn terraform io.png

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"
    }
  }
}

HCP Terraform initialization hashicorp configuration azurerm configuration migration to cloud terraform.lock.hcl lock file azurerm azure portal devops module infrastructure as code iac.png

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.

Terraform cloud plan plugin modules registry terraform io hashicorp configuration block api resource manager azure cli error authorizer azurerm hcp terraform cloud configuration portal organization workspaces devops iac code.png

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.

Terraform hcp cloud configuration workspace organization projects settings variable sets creation provider azure azurerm subscription tenant arm export environment variable.png

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.

Terraform HCP cloud configuration workspace variable sets plan billing policies terraform configuration configuration block global variable organization set scope priority.png

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. 

Hashicorp terraform hcp cloud configuration create variable sets add variable ARM_CLIENT_ID ARM_CLIENT_SECRET sensetive key value pair set priority API login azurerm azure provider devops cicd iac infrastructure as code.png

Once you save the Variable sets with required credentials key value pair information. It looks like below as per the screenshot.

Terraform hcp hashicorp cloud setup configuration variable sets azurerm arm_client_id arm_client_secret arm_subscription_id arm_tenant_id environment variable terraform variable azure rm terraform cloud setup.png

Next try running terraform plan command from terminal again. This time it is all good and output is successful.

Terraform cloud terraform plan configuration migrate state azurerm_resource_group variable authentication azure cloud github git plugin modules backend.png

On the HCP terraform cloud portal, I see There is job executed by user, Status is planned and finished with success.

Terraform cloud hcp hashicorp cloud workspaces organization triggered via CLI plan only run planned and finnish devops ci cd new run lock azurerm provider.png

If I drill down and click the plan for more information. It shows the what is planned to deploy on Azure cloud.

Terraform hcp hashicorp terraform cloud devops ci cd run plan finished plan only workspace default run triggered via cli azurerm azure cloud infrastructure as a code.png

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.

Terraform remote apply hcp cloud terraform hashicorp output azure terraform cloud configuration state backened terraform cloud block apply auto approve plan destroy.png

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.

Terraform workspace hcp terraform cloud hashicorp triggered via cli backend configuration cloud block azure states tfstate variables settings runs apply azurerm provider cloud.png

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

Go Back

Comment

Blog Search

Page Views

12086182

Follow me on Blogarama