Getting Started With Terraform and AWS EC2 (Workshop 1)

DZone 's Guide to

Getting Started With Terraform and AWS EC2 (Workshop 1)

If you're using AWS EC2, Terraform can help you detect changes to state and configure your infrastructure with execution plans

· Cloud Zone ·
Free Resource

At Smartling, we’re implementing Service Oriented Architecture (SOA). According to our vision of SOA and service ownership, every tech team owns and runs services in Amazon Web Services (AWS). Developers from each team have their own AWS account and can launch, support, deploy, and maintain AWS infrastructure for services they own using Terraform and a set of templates.

Our developers passed a set of AWS/Terraform workshops covering AWS basics like Elastic Compute (EC2), Elastic Block Storage (EBS), Elastic Load Balancing (ELB), as well as Terraform syntax and best practices in this field.

Now we’re sharing those workshops with you. In this post, you’ll find our introductory workshop, covering Terraform and AWS EC2.




EC2 stands for Elastic Compute Cloud — the service that provides scalable computing capacity in the Amazon Web Services (AWS) cloud. Using EC2, you can launch virtual servers, setup networking and security for them, and attach storage, public IP addresses, or associated domain names. EC2 lets you scale up or down computing resources depending on changes in requirements or spikes in popularity, reducing your need to forecast traffic.

When you launch an instance, you associate it with one or more security groups: virtual firewalls enforcing a set of rules that control the traffic to and from instances. AMI (Amazon Machine Image) is a template that contains a software configuration, including an operating system and packages. Using AMI, you can launch an instance that contains a copy of the AMI running as a virtual server in AWS cloud.

Locations for running EC2 instances are composed of regions and availability zones. Each region is a separate geographic area. Each region has multiple, isolated locations known as Availability Zones. Amazon EC2 provides you the ability to place resources, such as instances and data, in multiple locations.

EBS (Elastic Block Store) provides block level storage volumes for use with EC2 instances. You can create highly reliable EBS volumes and attach them to any running instance that is in the same Availability Zone. EBS volumes that are attached to an EC2 instance are exposed as storage volumes that persist independently from the life of the instance.

On-demand EC2 instances let you pay by the hour with no long-term commitments. Price varies considerably, based on instance type and attached storage. Internet traffic, public IP addresses, load balancing, and detailed monitoring resources are paid separately. There are options to reduce costs by upfront payments like instances reservations.

Read more:


Terraform is command line tool for building, changing, and versioning infrastructure, it supports popular cloud providers including Amazon AWS. Configuration files describe the infrastructure components needed to run a single application, for example, an EC2 instance with an attached EBS volume.

Terraform generates an execution plan, describing what it will do to reach the desired state, then executes it to build the described infrastructure. As the configuration changes, Terraform is able to determine what has changed and creates incremental execution plans that can be applied. The actual state of AWS resources managed by Terraform is stored in a terraform.tfstate file that is created after the first run of Terraform.

Key Features of Terraform

  • Infrastructure as code: Infrastructure is described using a high-level configuration syntax. This allows a blueprint of your datacenter to be versioned and treated as you would any other code. Additionally, infrastructure can be shared and re-used.
  • Execution plans: Terraform has a “planning” step where it generates an execution plan. The execution plan shows what Terraform will do when you call apply. This lets you avoid any surprises when Terraform manipulates infrastructure.
  • Resource graph: Terraform builds a graph of all your resources in order to create or modify non-dependent resources. Because of this, Terraform builds infrastructure as efficiently as possible, and operators get insight into dependencies in their infrastructure.
  • Change automation: Complex changesets can be applied to your infrastructure with minimal human interaction. With the previously mentioned execution plan and resource graph, you know exactly what Terraform will change and in what order, avoiding many possible human errors.


resource "aws_instance" "web" {
    ami = "ami-12345678"
    instance_type = "t1.micro"
    tags {
        Name = "HelloWorld"
    security_groups = [ "${aws_security_group.my_security_group.id}" ]

aws_instance is the TYPE of resource to be created. In this example, it’s an AWS EC2 instance

web is the NAME of a resource that is addressable within the Terraform configuration file.

Read more:


1. Login to your AWS account console.
2. Clone git repository with workshop data, go to w1 directory:
$ git clone https://github.com/Smartling/aws-terraform-workshops.git
$ cd aws-terraform-workshops/w1
3. Configure Terraform with AWS credentials (see pre-requisites) in creds.tf configuration file:
$ cat creds.tf
provider "aws" {
  region = "us-east-1"
4. Follow terraform documentation for EC2 instance and comments in ec2.tf to complete configuration:
   4.1. Go to AWS VPC console, write down VPC ID and subnet ID which are required to complete configuration.
Please notice that VPC and subnets are covered in details in the next workshops but they are still required to finish EC2 configuration.
   4.2. Use t2.nano as instance type for EC2 instance.
   4.3. You should specify names for AWS resources as well as missing configuration parameters.
   4.4. In this workshop we need to create EC2 instance in its own security group, see documentation here and here.
   4.5. Run terraform plan to make sure configuration is ready to be applied.
   4.6. Run terraform apply to actually create AWS resources: EC2 security group and EC2 instance.
5. Go to AWS console and find newly created EC2 instance and security group.
6. Open terraform.tfstate to examine its structure and newly created AWS resources. Please don't make any changes into this file. It's managed by terraform so manual changes into this file may break things up.
7. Modify EC2 instance type:
   7.1. Change EC2 instance type from t2.nano to t2.micro.
   7.2. Run terraform plan and then terraform apply to actually apply changes.
   7.3. Check changes in AWS EC2 web console.
8. Add your SSH key to EC2 instance and access it via SSH.
   8.1. Uncomment user_data parameter in terraform config.
   8.2. Replace example SSH key with your public SSH key to shared/user-data.txt file:
cd ../../
$ cat shared/user-data.txt

mkdir -p /home/ec2-user/.ssh
cat <<FILE > /home/ec2-user/.ssh/authorized_keys
ssh-rsa AAAAEXAMPLEyc2EAAAADAQABAAABAQCxz1G2vfqCabgFNZiL/timcrISitT4ShZP0iB4G1F+tFRM7to3CstEbS9TFeZwJdKeKLJoGsB5mMueqQb34lVt+ieodNKn8vMjTqv62W8YLqhRavnJ7bTGqGxNhAuLZJdEXAMPLEgywFwQjKYIVQt0SeB0XXLgAUIp+FS7MVyywDdViLqHWexxFN9Nrd6nPAj0fLV9DRIwe7nRccj+R4HvGIC7rQ060QCDCssYiZT/FVihNcPfohQA1JlNGao/lXLkSivwtl0pEDECyzs2KULS+9mc5Bz0Ap1Liskoa5V9umz8LhA9WLqNaCtt6fWQurPAd5lpEXAMPLE user@host
chown ec2-user.ec2-user /home/ec2-user/.ssh/authorized_keys
chmod 400 /home/ec2-user/.ssh/authorized_keys
yum -y erase docker
   8.3. Apply configuration changes.
   8.4. Login to newly created EC2 instance via SSH.
   8.5. Run commands uptime, top, uname -a on EC2 instance.
9. Run terraform destroy to delete AWS resources which were created during this workshop.
Hint: in case you got stuck during this workshop you can check answers directory in aws-terraform-workshops git repository.

You will find the second Terraform workshop here. Enjoy!

aws terraform ,cloud ,tutorial ,aws ec2 ,change management

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}