Terraform Cloud with AWS
Tags: aws, devops, terraform
Published: 2024-01-13 06:06:38

 
**TerraForm**
Terraform is an infrastructure-as-code tool to provision and tear down infrastructure on cloud or on-premises

**Terraform Cloud**
Terraform Cloud is a SaaS application that helps teams use Terraform together. It aims to solve many problems that arise when many developers are using Terraform in an organization. 

- It provides secure & easy access to shared state and secret data. No longer have to give out powerful credentials to everyone who needs to run Terraform. No need to have duplicated variable values. 
- It allows you to integrate with your version control repo and run terraform plans/runs when there is a state change on the repo, i.e. Pull-Request, Commit, etc. You can run a terraform plan on pull-request and see the speculated changes.

- Cost Estimation: Estimate the cost of cloud resources you are creating. 

- You can apply policies to control what infrastructure changes are allowed, using policy-as-code tools like Sentinel or OPA. You can fail the terraform run if the cost is higher than $$$. 

**Get your own Free Terraform Cloud Account**
You can sign up with your email ID and get a free Terraform cloud account from [here](https://www.hashicorp.com/products/terraform?product_intent=terraform). 

Once your email is verified you are in Terraform Cloud. Click "Create New Organization"

![Create Org1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z1ocgi82obbkskjpnaz8.png)


![Create org1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uqy0b1phntpw9qpk8is8.png)


**Create Workspace**
One Github Repository corresponds to one workspace. All terraform runs from the repo will come inside this workspace.

Terraform Cloud has 3 different workflow types:
VCS - Connect to your GitHub and trigger runs manually or automatically on commit/pull-request

CLI - Have the code on your local system and run from the terminal, but runs will still display on the portal. 

API - Run terraform using API. 

On the below screen select "Version Control Workflow"


![Create workspace](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m8hssgqgcxfibn8anelp.png)

Select your Version Control System (Github in my case) then do the login into the version control system. 


![Select Repo1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6l8wtmf4hoe2jmchd8as.png)


Once logged in, you will be asked to select the repository that will be tracked by this workspace. 


![Select Repo2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6d6zamb42rm6rpd3avf4.png)


After this, enter the Workspace name,  and you are done. 

**Connecting Terraform Cloud to AWS** 
Unlike the Terraform CLI you use on the local system, you don't need to have your AWS credentials available to the Terraform locally in the cloud version. Terraform Cloud can save variables that should be available to all workspaces (or some of them) centrally. You can keep them secure. 

You create Variable Sets (that contain variables) and specify whether the variable set would be accessible to all workspaces or some of them. 

Navigate to Settings - Variable Sets and create a Variable Set. 


![Variable set](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vqivuxqqicno3gdjpy0z.png)


Inside this create 2 variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. Set the value as the access key id and secret access key from AWS of an IAM user with the required permissions.

Select the variable type as "environment". The other option is "Terraform Variables" which are variables of terraform type. 
Mark them as sensitive, and they are no longer visible to anyone. 


![Variable](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1nma2ilo5p9sfctq93em.png)


**Workspace Variables **
You can specify variables that are local to a specific repository in its Workspace variables. This also allows you to have variables with the same name in different workspaces. 
For eg: I have a Workspace with the below variables. These will be used by the terraform scripts in that workspace. 


![Workspace Variables](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ukhc73x2suwu4eds5j6.png)


In effect, any workspace will get the variables in the workspace, plus the variable sets defined as global or linked to that workspace. 

**Now let's start Terraforming!**
Add the code from the below repo into your Workspace repository.

{% github manumaangit/terraformcloud_demo %}

The terraform does not run automatically the very first time, so trigger a run from the Workspace by going to it and clicking "New Run". You can trigger a run anytime manually using this button. In the below window, I have selected to do both terraform plan and terraform apply. You can choose to do only apply also.


![New Run](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fi1evd4rg6wx2u8ut78s.png)


Once it completes planning, just like CLI it will wait for approval to apply by default. 

![Complete Run](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0vbu7vb2tlndovdy25dm.png)


If you want to, you can set an option in Workspace settings to auto-apply.


![Apply Default](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9nvbriqxc8uhyi8glehu.png)


If you don't want to apply, click "Discard Run".
Now onwards, anytime you commit or pull-request on the repository, it will trigger an automatic run. The run on pull-request is only a speculative plan and you cannot apply it. Only changes that are committed to the repo can be applied. 

I make a small change in the main.tf file and raise a pull-request. Terraform Cloud will automatically run a plan from the changes. 


![PR Run](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pp2yiytyzh28vkrcapaz.png)



I commit the changes. Another run happens which has the option to apply. 


![applyrun](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/boqievcyd0nangw56sw0.png)

**Cost Estimation**
You can enable cost estimation in the Terraform Cloud. Goto Organization Settings - Cost Estimation and enable it.


![costestimation1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7n9f773mtn130hx95bt7.png)


Now if you change the ec2 type in the tf file and commit, you can see the cost estimation in the plan run. 


![costestimation2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tx6l2jzti3j3ivgf6pnf.png)

**Policies for Terraform**
Policies-As-Code is a way to specify policies in the form of code, and there are multiple tools out there to do that. In Terraform Cloud 2 of the most popular ones are supported - Sentinel (by Hashicorp, makers of Terraform) and OPA. 

In the Free version of Terraform Cloud, there are a lot of limitations on how many policies you can have - You can have a total of 5 policies and one PolicySet as of this writing. (PolicySet is what links a policy to one or more Workspaces in the Terraform Cloud). Also, you cannot fetch policies from a version control system in a Free version. 

From Organization Settings - Policies you can create a Policy as given below. I have selected Sentinel type. 

Note that in the Free version, you can have a maximum of one soft/hard mandatory policy and multiple advisory policies. 

- Soft Mandatory - This is like a Warning, even if the code breaks the policy you can override it. 
- Hard Mandatory - This is an Error. You cannot override if the code breaks the policy you can override it.
- Advisory - Will just print a message. More like INFO.
 
Below given Sentinel code checks if the change in infra will incur a cost of more than $100. 

```
import "tfrun"
import "decimal"
delta_monthly_cost = decimal.new(tfrun.cost_estimate.delta_monthly_cost)
main = rule {
 print("Cost change cannot be more than $ 100") and
 delta_monthly_cost.less_than(100)
}
```

Once the policy is saved, Navigate to Organization Settings - PolicySets and click on "Connect a New PolicySet"


![Policy1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1e37uplfroygyreg933b.png)


Then click the link that says "Create a PolicySet with individually managed policies"


![Policy2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vq2syctu22ef3l9z25oy.png)



Set what kind of policies are in the set (Sentinel). Select Policies enforced globally to apply to all Workspaces. At the bottom from the drop-down select the previously created Policy and add it to this PolicySet. Click "Connect PolicySet".


![Policyset](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/329rp6kfto5vtvuuhcym.png)


Now let's change the EC2 type to t2.2xlarge which will surely break this policy. 

The cost estimation is $276.97 which triggers the Policy to fail. Note that Apply is not an option anymore since we set it as "Hard Mandatory"


![Policyfail](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0zkvzanj0gd1zsgetv6z.png)



Try out the Terraform Cloud and take your Terraforming to the next level. 

Hope this was helpful!