5 things Terraform can automate in AWS ⚙️
Tags: beginners, cloud, aws, tutorial
Published: 2020-07-26 16:25:41


[Terraform](https://www.terraform.io/) is an orchestration tool that can provision infrastructure with code. Instead of opening the AWS Management Console to create our resources, we can do that directly in our editor with HCL (HashiCorp's Configuration Langauge).🎉

Let's look at some things we can automate in AWS. 

![Alt text of image](https://media.giphy.com/media/3o7TKUM3IgJBX2as9O/giphy.gif)


## Prerequisites

* [AWS Account - Free Tier](https://aws.amazon.com/free)
* [Create an IAM user](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html)
* [AWS CLI installation and configuration](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html)
* [Terraform installation](https://learn.hashicorp.com/terraform/getting-started/install.html)

*Note:* A step-by-step guide for setup can be found in the [Github README.md](https://github.com/ari-hacks/terraform-aws-automation/blob/master/README.md)


## TODOs 

[Launch an EC2 Instance](#ec2) 
[Create an S3 Bucket](#s3-bucket)
[Create a backend state with S3](#s3)
[Create IAM group and policy](#group-policy)
[Add IAM users to a group](#users)

--------------------

## Launch an EC2 Instance <a name="ec2"></a>

```HCL
#variables.tf
variable "region" {
  description = "AWS region"
  default     = "us-east-2"
}

variable "ami" {
  default     =  "ami-0c8110836d05ad7bd"
}

#main.tf
provider "aws" {
  region  = var.region
}

terraform {
  required_version = ">= 0.12"
}

resource "aws_instance" "ec2_example" {
  ami           = var.ami
  instance_type = "t2.micro"
}
```

In this example, we are creating an AWS resource of type `aws_intstance` with a unique name `ec2_example`. This resource spins up an ec2 server by launching a copy of the AMI(Amazon Machine Image). 

The AMI is a dynamic value and needs to be updated when creating instances. You can find these on the AWS console or search for ubuntu images [here](https://cloud-images.ubuntu.com/locator/ec2/) (For t2.micro select hvm:ebs-ssd).

- [EC2 directory](https://github.com/ari-hacks/terraform-aws-automation/tree/master/launch-ec2-instance)


## Create an S3 Bucket <a name="s3-bucket"></a>

```HCL
#variables.tf
variable "region" {
  description = "AWS region"
  default     = "us-east-2"
}

#outputs.tf
output "s3-bucket" {
  value = aws_s3_bucket.b_example.bucket
}

#main.tf
provider "aws" {
  region  = var.region
}

resource "aws_s3_bucket" "b_example" {
  bucket = "bucket-example-tmed232323"
  force_destroy = true
  acl    = "private"

  versioning {
    enabled = true
  }
}
```
An s3 bucket is used for storage. To create a bucket a unique name is required. If you do not add one AWS will create one for you. To grant access to a bucket `acl` can be used. By default it is set to private. `force_destory=true` is set for testing purposes. This will allow us to delete the bucket with `terraform destroy` even if it is not empty. 

`versioning` keeps different variants of an object in the bucket and `outputs.tf` will output the results of the file to the console after an `apply`.

- [S3 Bucket directory](https://github.com/ari-hacks/terraform-aws-automation/tree/master/create-s3-bucket)

## Create a backend state with S3 <a name="s3"></a>

```HCL
#main.tf
terraform {
  backend "s3" {
    bucket = "bucket-example-tmed232323"
    key    = "terraform-aws-automation/create-s3-backend-state/terraform.tfstate"
  }
}
```
In this example, remote state is being stored with a `terraform.tfstate` file. This is common practice when using Terraform with more than one person so state does not get locked and only one person can make changes at a time on the latest copy. Since the bucket we created is using versioning there will be a history of changes stored as well.

To add an object to a bucket the unique bucket name is required along with the `key` which defines the path of the file that's created in AWS.  

- [S3 backend state directory](https://github.com/ari-hacks/terraform-aws-automation/tree/master/create-s3-backend-state)

## Create IAM group and policy <a name="group-policy"></a>

```HCL
#variables.tf
variable "region" {
  description = "AWS region"
  default     = "us-east-2"
}
#main.tf
provider "aws" {
  region  = var.region
}

resource "aws_iam_group" "admin_example" {
  name = "admin_example"
}

resource "aws_iam_policy_attachment" "admin-attachement" {
  name       = "admin-attachement"
  groups     = [aws_iam_group.admin_example.name]
  policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess"
}

```

Groups are collections of IAM users that share specific privileges or policies.

Two resources are created here, one for the IAM group and another to attach a policy to that group. The attribute `policy_arn` is set to attach the Administrator Access policy to the IAM group.

- [IAM Group and Policy directory](https://github.com/ari-hacks/terraform-aws-automation/tree/master/create-iam-group-policy)

## Add IAM users to a group <a name="users"></a>

```HCL
#variables.tf
variable "region" {
  description = "AWS region"
  default     = "us-east-2"
}

#main.tf
provider "aws" {
  region  = var.region
}

resource "aws_iam_user" "admin_example_1" {
  name = "admin_example_1"
}

resource "aws_iam_user" "admin_example_2" {
  name = "admin_example_2"
}

resource "aws_iam_group_membership" "admin-user-group-example" {
  name = "admin-user-group-example"
  users = [
    aws_iam_user.admin_example_1.name,
    aws_iam_user.admin_example_2.name,
  ]
  group = "admin_example"
}

```
After an IAM group is created we can add new users to it. This is down with the resource type `aws_iam_group_membership`. Users are passed to this resource along with the name of the group. 

- [Add users to group directory](https://github.com/ari-hacks/terraform-aws-automation/tree/master/add-users-to-iam-group)

---------------

To run these examples locally, clone the [repo](https://github.com/ari-hacks/terraform-aws-automation) and navigate to the root directory. In your terminal `cd` into one of the above directories and follow these steps:
   1. Initialize Terraform: `terraform init`
   2. Check the plan to make sure the configuration will do what we expect: `terraform plan`
   3. Apply the execution plan and build the stack: `terraform apply`
   4. Check the resource is up: `terraform state list` or `terraform state show 'type.name'` `ex. aws_instance.ec2_example`
   5. Tear down all provisions: `terraform destroy`
 
---------------

If you found this article useful give the repo a ⭐️ and check back later for more examples of automating AWS with Terraform. 🙂✌🏾

{% github ari-hacks/terraform-aws-automation %}