Deploying a Two-Tier Architecture in AWS Using Terraform Modules in Terraform Cloud
Tags: aws, terraform, devops, github
Published: 2022-10-02 20:14:23


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m2y0s3kxzv1w0qj85wjj.png)

This is the same continuation of my previous article on [Deploying a two-tier architecture in AWS using Terraform Modules](https://medium.com/@revathijoshi70/deploying-a-two-tier-architecture-in-aws-using-terraform-modules-c4cebdecfcde), but in Terraform Cloud.

Objectives are the same which are given below:

## Objectives:

## 1. Create a highly available two-tier AWS architecture containing the following:

- 3 Public Subnets

- 3 Private Subnets

- Auto Scaling Group for Bastion Host and Web Server

- Internet-facing Application Load Balancer for Web Server

## 2. Use module blocks for ease of use and re-usability.

In this article, I am going to show only on how to deploy the same infra-structure in **Terraform Cloud**.

Used [Terraform Cloud Documentation](https://www.terraform.io/cloud-docs).

What you will need in addition is a Terraform Cloud Account.


## What is Terraform Cloud?

[**Terraform**](https://www.terraform.io/intro) is an infrastructure as code tool that lets you define and manage infrastructure resources through configuration files. It uses modules for readability and re-usability. It securely stores state and secret data, and can connect to version control systems so that you can develop your infrastructure. It helps you to collaborate with your teams in your organization so that all can review at the same time you plan a new change, and approve the plan before you apply it.

Click on [my repository link](https://github.com/awsmine/2_tier_architecture_modules_terraform_cloud) below to clone it into Cloud9 IDE.

[Create a Terraform Cloud account](https://learn.hashicorp.com/tutorials/terraform/cloud-sign-up)

- Sign into [Terraform Cloud](https://cloud.hashicorp.com/products/terraform)

- In your Terraform Cloud dashboard, navigate to _**Settings**_



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6r93pchdwjrz46jwvlmy.png)

- On the left hand, scroll down to **_Providers_**


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ds3kp9so0h3773ygywmv.png)

- Click _**Add a VCS provider**_ at the top right of screen


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x4r6s6lq72dazrftt8bv.png)

- Click _**GitHub**_ and select _**GitHub.com (Custom)**_


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l83dq6i9ddzh5x15zu1b.png)


- After making sure you are signed into your GitHub account, in the Terraform Cloud web page, click on the link **_register a new OAuth Application._**

- Use the information given to fill out the fields in your GitHub account.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gx123z66jyeay7r6iswu.png)

- _**Register application**_


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/12ctpwiaxqvszk8nw4np.png)

- Finish **_without creating a SSH key pair_**.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4l4ykgb4yusdrvx0j6gq.png)

- In Terraform Cloud dashboard, click to create a _**New Workspace**_


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zz46rmlikpzzp3adfuze.png)

- Click _**Version control workflow**_



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/at0f9lf204dquvfpmrp0.png)

- click the **_GitHub custom_** you just created


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7m8vry4stnvatz71hrl8.png)

- Select repository for this project, _**awsmine/2_tier_architecture_modules_terraform_cloud**_


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a421govt3lyzi5rxhfta.png)


- Create a name for this workspace and select _**Create workspace**_


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/onq0ar9knkbivl9kwdt0.png)

- Click _**Go to workspace overview**_ to add variables


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gvopt7g1pgva1jarckdt.png)

- Click _**Configure variables**_.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q4qtuexsxx7crhx769mx.png)

- Click _**Add variable**_ in the _**Environment Variable**_ section.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j20lhk0fw3kqeg3djxaz.png)


- First add your _**1st environment variable — AWS_ACCESS_KEY_ID**_ for your IAM user with admin permissions.

- Ensure that you click _**Sensitive**_ for these variable. This will prevent your variable value from being displayed.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bmfgd2vo03rxexwpym17.png)

- Then add your _**2nd environment variable — AWS_SECRET_ACCESS_KEY**_ for your IAM user with admin permissions.

- Ensure that you click _**Sensitive**_ for these variable. This will prevent your variable value from being displayed.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qviowrzxmipb8fjq10c4.png)

- Then add your _**3rd environment variable — for AWS_DEFAULT_REGION**_ set to _**us-east-1**_


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/knh2tv78mh58sqex4dy5.png)


- Then add your **_4th environment variable_** — create a _**CONFIRM_DESTROY**_ variable set to **_1_**. This is needed to destroy our infrastructure later.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e5kdg4ox0j77tdvma66v.png)

- Instead of using a .tfvars file in the GitHub repo, we are adding our _**access_ip**_ variable to the _**Terraform Variables**_. In our root _**main.tf**_, the _access_ip_ is set up which determines the CIDR block that can SSH into our Bastion Host. Use 0.0.0.0/0, but you can also use your personal IP address.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zdbnvsrcaxjs1gubj57j.png)

- See the _**list of Environment and Terraform variables added**_


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/38q9rp5fib4z4ht2ldgs.png)


- Now click the **_Actions_** link at the top right and select _**Start new run**_


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1fvzx7ffjtzw1tugdbkp.png)


- Write _**test**_ for Reason for starting run, Choose run type _**Plan and apply (standard)**_ and click _**Start run**_



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n1ub6qmr0y8r1l02odmu.png)




- _**Plan running**_


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xanpbz6zd4rosqxw8e6q.png)

- Once _**Plan finished**_


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fu1hzk5kmwwilu5h9032.png)



- go all the way down , click _**Confirm & apply**_



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dnpf5198ekxzkh4ub7ro.png)

- write _**test apply**_ and click _**Confirm Plan**_


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/56oz9yhcnle9yg611mxs.png)



- you will see _**Apply running**_



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ufyy9bmv2iwzct2g7fj.png)

- _**Apply errored**_
- _**Error**_: with the retirement of EC2-Classic no new non-VPC EIPs can be created


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d0sdwcr6hjy73tzd7ne4.png)



- But our infrastructure is completed.



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zzzmjzgdrzrwmr2xm5zm.png)


## VERIFY

_**DNS name**_


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j6r3w3ezucvsgtbqsz0p.png)



_**Security group for Bastion host**_



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0oksm3qmb84jqfie8qy4.png)

- Copy the _**Public IP of the Bastion host**_



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lmr3f2an3tl5jg5sykxb.png)



- Using _**Putty**_ and _**Putty Agent forwarding**_ (use Pageant — Putty authentication agent), log into the putty session using the _**key name**_ from the root main.tf (_**NVirKey**_) as your _**EC2 Key Pair name**_ via _**SSH connection**_.


- Test Internet connection by _**ping google.com**_


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2a8nmkes5vtuze26tlcp.png)


- **_Validate 1st webserver (named as database server)_**
- _**Security group for webserver host**_


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/09idomnwrna7lowte7rv.png)



- copy the _**Private IP address of 1st webserver (database server)**_



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kokh21h2882b2ioocc65.png)

- _**SSH from the bastion host**_


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tf29ikyipbcrgo9vwgeb.png)



- verify internet connection — _**ping google.com**_



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v5ic4nqs49en17zsl9kb.png)

- Validate _**2nd webserver (named as database server)
Security group for webserver host**_


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wxlviufccguzyame5qaw.png)



- copy the _**Private IP address of 2nd webserver (database server)**_



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qpa2pk45nh8txiu7xp69.png)


- _**SSH from the bastion host**_

- verify internet connection — _**ping google.com**_


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5gxdgpw3xbpnw45wxqfr.png)



## **Clean up**

Navigate to your Workspace and click _**Settings/Destruction and Deletion.
**_


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/arwi6q0lbtolvh4sh5xk.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/khz02urkbmdz86ff22d6.png)


- First click _**Queue destroy plan**_ and follow the below prompts


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4led9rwfsy8w2ivrg3wo.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0unq6kvyfbex0vwsoelj.png)



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xt9p5aiu0embnpqkqm6j.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ztwue9qlg359x83te77j.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ma2gywszugwe31kgzhv.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4y1myh4s5rnr4tm4p4tc.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5zmjzhegsqctfpf0l3g4.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/llrvobbwmbnxp0okmwda.png)

- Now _**Delete workspace from Terraform Cloud**_


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5pn5mcrsx2auwg74pc1i.png)


- _**Delete workspace**_



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mi24n893gg1b2xlflqlr.png)


- check to see that everything is cleaned up


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fgbub3qyl8wk0jr27usl.png)


## What we have done so far

_In_ _**Terraform Cloud**_, _we created two Web servers placed in Private Subnets which has access to the internet through a Bastion host placed in Public Subnets with High availability and Load Balancing features._