Provisioning a Simple EC2 Instance with Terraform
Tags: ec2, terraform, aws, cloud
Published: 2022-10-11 12:33:09

If you're just starting out with Terraform this is a simple lab to learn how to provision an EC2 instance on Amazon Web Services. EC2 instances are virtual machines running on AWS, and a common component of many infrastructure projects.

The use of Terraform is very necessary for cloud engineers in order to automate deployments of your infrastructure. Terraform is an infrastructure as code tool that lets you define infrastructure resources in human-readable configuration files that you can version, reuse, and share. You can then use a consistent workflow to safely and efficiently provision and manage your infrastructure throughout its lifecycle.

#### Benefits of Using Terraform

- You'll need tools that can automate the majority of your work if you're going to be an effective cloud Engineer, and Terraform will help you do that.

- Terraform is OpenSource and platform-agnostic. This simply means it's free and can be used on multi cloud platforms, it's not limited to one cloud provider.

- Terraform is Declarative. Since the Terraform language is declarative, it defines an expected outcome rather than the precise processes that must be taken to achieve it.

And many more. So let's start learning how to use terraform by deploying your very first EC2 instance with Terraform.

### Prerequisites for this Lab

- The [Terraform CLI](https://www.terraform.io/downloads) installed.
- The [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed.
- AWS account and associated credentials that allow you to create resources.

#### NB
This tutorial will provision resources that qualify under the [AWS free tier](https://aws.amazon.com/free/). If your account does not qualify for free tier resources, we are not responsible for any charges that you may incur.

### Set your Environment Variable.
From a security standpoint we do not store our password within our codes. This is why it is necessary to set our environment. 

Storing secrets in code is a mistake that may cause a credential to be unintentionally exposed.

Access Keys are long-term credentials that should NOT be stored in code.

#### Tip

If you don't have access to IAM user credentials, use another authentication method described in the [AWS provider documentation](https://www.terraform.io/docs/providers/aws/index.html?_gl=1*1hdsnib*_ga*MTEyNTk4NDkyNC4xNjYzMjA1MDgx*_ga_P7S46ZYEKW*MTY2MzQ0MDU1OC4xOS4xLjE2NjM0NDA2MDQuMC4wLjA.#environment-variables).

To use your IAM credentials to authenticate the Terraform AWS provider, set the AWS_ACCESS_KEY_ID environment variable.

For Linux and MacOS users enter the below command: 
```hcl
export AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY
```
PowerShell users, enter the below command:

```hcl
$env:aws_access_key="YOUR_ACCESS_KEY"
```

Enter the access key of your AWS account after the = sign in place of "YOUR_ACCESS_KEY"

Now, we set our secret key.

Linux and MacOS

```hcl
export AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY
```
PowerShell

```hcl
$env:aws_secret_key="YOUR_SECRET_KEY"
```
### Let's write our Configuration

A Terraform configuration is a collection of files used to represent infrastructure in Terraform. You will create your first AWS EC2 instance setup to specify a single instance.

The working directory for each Terraform configuration must be distinct. For your configuration, make a directory.

```
mkdir learn-terraform-aws-instance
```
Change into the directory.

```
cd learn-terraform-aws-instance
```
Create a file to define your infrastructure.

```
touch main.tf
```
Open main.tf in your text editor, paste in the configuration below, and save the file.

```hcl
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.30"
    }
  }

  required_version = ">= 1.2.9"
}

provider "aws" {
  region  = "us-west-2"
}

resource "aws_instance" "app_server" {
  ami           = "ami-830c94e3"
  instance_type = "t2.micro"

  tags = {
    Name = "ExampleAppServerInstance"
  }
}

```
Tip: The AMI ID used in this configuration is specific to the us-west-2 region. If you would like to use a different region, specify it under the region block.

### Brief Explanation

#### - Terraform Block

The terraform {} block contains Terraform settings, including the required providers Terraform will use to provision your infrastructure. For each provider, the source attribute defines an optional hostname, a namespace, and the provider type. Terraform installs providers from the Terraform Registry by default. In this example configuration, the aws provider's source is defined as hashicorp/aws, which is shorthand for registry.terraform.io/hashicorp/aws.

#### - Providers

The provider block configures the specified provider, in this case aws. A provider is a plugin that Terraform uses to create and manage your resources.

You can use multiple provider blocks in your Terraform configuration to manage resources from different providers. You can even use different providers together.

#### Resources

Use resource blocks to define components of your infrastructure. A resource might be a physical or virtual component such as an EC2 instance, or it can be a logical resource such as an NGINX server. Resource blocks have two strings before the block: the resource type and the resource name.

Resource blocks contain arguments which you use to configure the resource. Arguments can include things like machine sizes, disk image names, or VPC IDs.

### Initialize the Directory

You must use `terraform init` to initialize the directory when creating a new configuration or checking out an old configuration from version control.

When a configuration directory is initialized, the configuration's defined providers—in this example, the aws provider—are downloaded and installed.

Initialize the directory.

```hcl
terraform init
```

![Terraform EC2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xy191971k9zmut2edh4q.png)

### Validate the Configuration

We need to make sure our configuration is syntactically valid and internally consistent by using the terraform validate command.

Validate your configuration. The example configuration provided above is valid, so Terraform will return a success message.

```hcl
terraform validate
```

![Terraform EC2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5gw2ok5iyfbmvbvt7tlk.png)

### Create Infrastructure

Apply the configuration now with the `terraform apply` command. Terraform will print output similar to what is shown below. We have truncated some of the output to save space.

```hcl
terraform apply
```

![Terraform EC2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fk7xf7hvppivlxmflgmq.png)

Tip: If your configuration fails to apply, you may have customized your region or removed your default VPC. Refer to the troubleshooting section at the bottom of this tutorial for help.

Before it applies any changes, Terraform prints out the execution plan which describes the actions Terraform will take in order to change your infrastructure to match the configuration.

The output has a + next to aws_instance.app_server, meaning that Terraform will create this resource. Beneath that, it shows the attributes that will be set. When the value displayed is (known after apply), it means that the value will not be known until the resource is created.

Enter yes to create the infrastructure.


![Terraform EC2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i4e9uebw3jh0ipiew56f.png)

We have now created infrastructure using Terraform! Visit the EC2 console and find your new EC2 instance.

### Destroy your Infrastructure

To avoid incurring charges you can destroy your infrastructure when you are done. With your configuration file you can easily spin up your instance by running 2 simple commands.

Run:

```hcl
terraform destroy
```

![Terraform EC2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/42suzwsir891j3q0lqog.png)

Type in yes to confirm your choice


![Terraform EC2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p83n4di2iftav6g2qd4a.png)

You have now successfully spun up and destroyed an EC2 Instance using terraform.

Until next time.