Skip to content

Commit b8f61c3

Browse files
committed
Add basic Terraform code examples
1 parent af95ae0 commit b8f61c3

File tree

8 files changed

+258
-0
lines changed

8 files changed

+258
-0
lines changed

LICENSE.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Gruntwork License
2+
3+
Copyright (c) 2016 Gruntwork, LLC
4+
5+
This code is the property of Gruntwork, LLC. In the Software Development Agreement signed by both Gruntwork and your
6+
company, Gruntwork grants you a limited license to use, modify, and create derivative works of this code. Please
7+
consult the Software Development Agreement for the complete terms under which you may use this code.

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# An Introduction to Terraform Sample Code
2+
3+
This repo contains the sample code for the blog post [An Introduction to Terraform]().
4+
It is broken into two folders:
5+
6+
* [single-web-server](./single-web-server): Deploy a single EC2 Instance with a web server that will return
7+
"Hello, World" for every request on port 8080.
8+
* [cluster-of-web-servers](./cluster-of-web-servers): Deploy a cluster of EC2 Instances in an Auto Scaling Group (ASG)
9+
and an Elastic Load Balancer (ELB). The ELB listens on port 80 and distributes load across the EC2 Instances, each
10+
of which runs the same "Hello, World" web server.
11+
12+
## Quick start
13+
14+
**Note**: These examples deploy resources into your AWS account. Although all the resources should fall under the
15+
[AWS Free Tier](https://aws.amazon.com/free/), it is not our responsibility if you are charged money for this.
16+
17+
1. Install [Terraform](https://www.terraform.io/).
18+
1. Set your AWS credentials as the environment variables `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`.
19+
1. `cd` into one of the two example folders.
20+
1. Run `terraform plan`.
21+
1. If the plan looks good, run `terraform apply`.
22+
23+
Please see [An Introduction to Terraform]() for more information.
24+
25+
## License
26+
27+
Please see [LICENSE.txt](/LICENSE.txt) for details on how the code in this repo is licensed.
28+

cluster-of-web-servers/main.tf

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2+
# CREATE ALL THE RESOURCES TO DEPLOY AN APP IN AN AUTO SCALING GROUP WITH AN ELB
3+
# This template runs a simple "Hello, World" web server in Auto Scaling Group (ASG) with an Elastic Load Balancer
4+
# (ELB) in front of it to distribute traffic across the EC2 Instances in the ASG.
5+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6+
7+
# ------------------------------------------------------------------------------
8+
# CONFIGURE OUR AWS CONNECTION
9+
# ------------------------------------------------------------------------------
10+
11+
provider "aws" {
12+
region = "us-east-1"
13+
}
14+
15+
# ---------------------------------------------------------------------------------------------------------------------
16+
# GET THE LIST OF AVAILABILITY ZONES IN THE CURRENT REGION
17+
# Every AWS accout has slightly different availability zones in each region. For example, one account might have
18+
# us-east-1a, us-east-1b, and us-east-1c, while another will have us-east-1a, us-east-1b, and us-east-1d. This resource
19+
# queries AWS to fetch the list for the current account and region.
20+
# ---------------------------------------------------------------------------------------------------------------------
21+
22+
data "aws_availability_zones" "all" {}
23+
24+
# ---------------------------------------------------------------------------------------------------------------------
25+
# CREATE THE AUTO SCALING GROUP
26+
# ---------------------------------------------------------------------------------------------------------------------
27+
28+
resource "aws_autoscaling_group" "example" {
29+
launch_configuration = "${aws_launch_configuration.example.id}"
30+
availability_zones = ["${data.aws_availability_zones.all.names}"]
31+
32+
min_size = 2
33+
max_size = 10
34+
35+
load_balancers = ["${aws_elb.example.name}"]
36+
health_check_type = "ELB"
37+
38+
tag {
39+
key = "Name"
40+
value = "terraform-asg-example"
41+
propagate_at_launch = true
42+
}
43+
}
44+
45+
# ---------------------------------------------------------------------------------------------------------------------
46+
# CREATE A LAUNCH CONFIGURATION THAT DEFINES EACH EC2 INSTANCE IN THE ASG
47+
# ---------------------------------------------------------------------------------------------------------------------
48+
49+
resource "aws_launch_configuration" "example" {
50+
# Ubuntu Server 14.04 LTS (HVM), SSD Volume Type in us-east-1
51+
image_id = "ami-2d39803a"
52+
instance_type = "t2.micro"
53+
security_groups = ["${aws_security_group.instance.id}"]
54+
55+
user_data = <<-EOF
56+
#!/bin/bash
57+
echo "Hello, World" > index.html
58+
nohup busybox httpd -f -p "${var.server_port}" &
59+
EOF
60+
61+
# Important note: whenever using a launch configuration with an auto scaling group, you must set
62+
# create_before_destroy = true. However, as soon as you set create_before_destroy = true in one resource, you must
63+
# also set it in every resource that it depends on, or you'll get an error about cyclic dependencies (especially when
64+
# removing resources). For more info, see:
65+
#
66+
# https://www.terraform.io/docs/providers/aws/r/launch_configuration.html
67+
# https://terraform.io/docs/configuration/resources.html
68+
lifecycle {
69+
create_before_destroy = true
70+
}
71+
}
72+
73+
# ---------------------------------------------------------------------------------------------------------------------
74+
# CREATE THE SECURITY GROUP THAT'S APPLIED TO EACH EC2 INSTANCE IN THE ASG
75+
# ---------------------------------------------------------------------------------------------------------------------
76+
77+
resource "aws_security_group" "instance" {
78+
name = "terraform-example-instance"
79+
80+
# Inbound HTTP from anywhere
81+
ingress {
82+
from_port = "${var.server_port}"
83+
to_port = "${var.server_port}"
84+
protocol = "tcp"
85+
cidr_blocks = ["0.0.0.0/0"]
86+
}
87+
88+
# aws_launch_configuration.launch_configuration in this module sets create_before_destroy to true, which means
89+
# everything it depends on, including this resource, must set it as well, or you'll get cyclic dependency errors
90+
# when you try to do a terraform destroy.
91+
lifecycle {
92+
create_before_destroy = true
93+
}
94+
}
95+
96+
# ---------------------------------------------------------------------------------------------------------------------
97+
# CREATE AN ELB TO ROUTE TRAFFIC ACROSS THE AUTO SCALING GROUP
98+
# ---------------------------------------------------------------------------------------------------------------------
99+
100+
resource "aws_elb" "example" {
101+
name = "terraform-asg-example"
102+
security_groups = ["${aws_security_group.elb.id}"]
103+
availability_zones = ["${data.aws_availability_zones.all.names}"]
104+
105+
health_check {
106+
healthy_threshold = 2
107+
unhealthy_threshold = 2
108+
timeout = 3
109+
interval = 30
110+
target = "HTTP:${var.server_port}/"
111+
}
112+
113+
# This adds a listener for incoming HTTP requests.
114+
listener {
115+
lb_port = 80
116+
lb_protocol = "http"
117+
instance_port = "${var.server_port}"
118+
instance_protocol = "http"
119+
}
120+
}
121+
122+
# ---------------------------------------------------------------------------------------------------------------------
123+
# CREATE A SECURITY GROUP THAT CONTROLS WHAT TRAFFIC AN GO IN AND OUT OF THE ELB
124+
# ---------------------------------------------------------------------------------------------------------------------
125+
126+
resource "aws_security_group" "elb" {
127+
name = "terraform-example-elb"
128+
129+
# Inbound HTTP from anywhere
130+
ingress {
131+
from_port = 80
132+
to_port = 80
133+
protocol = "tcp"
134+
cidr_blocks = ["0.0.0.0/0"]
135+
}
136+
}

cluster-of-web-servers/outputs.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
output "elb_dns_name" {
2+
value = "${aws_elb.example.dns_name}"
3+
}

cluster-of-web-servers/vars.tf

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# ---------------------------------------------------------------------------------------------------------------------
2+
# ENVIRONMENT VARIABLES
3+
# Define these secrets as environment variables
4+
# ---------------------------------------------------------------------------------------------------------------------
5+
6+
# AWS_ACCESS_KEY_ID
7+
# AWS_SECRET_ACCESS_KEY
8+
9+
# ---------------------------------------------------------------------------------------------------------------------
10+
# OPTIONAL PARAMETERS
11+
# ---------------------------------------------------------------------------------------------------------------------
12+
13+
variable "server_port" {
14+
description = "The port the server will use for HTTP requests"
15+
default = 8080
16+
}

single-web-server/main.tf

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2+
# DEPLOY A SINGLE EC2 INSTANCE
3+
# This template uses runs a simple "Hello, World" web server on a single EC2 Instance
4+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5+
6+
# ------------------------------------------------------------------------------
7+
# CONFIGURE OUR AWS CONNECTION
8+
# ------------------------------------------------------------------------------
9+
10+
provider "aws" {
11+
region = "us-east-1"
12+
}
13+
14+
# ---------------------------------------------------------------------------------------------------------------------
15+
# DEPLOY A SINGLE EC2 INSTANCE
16+
# ---------------------------------------------------------------------------------------------------------------------
17+
18+
resource "aws_instance" "example" {
19+
# Ubuntu Server 14.04 LTS (HVM), SSD Volume Type in us-east-1
20+
ami = "ami-2d39803a"
21+
instance_type = "t2.micro"
22+
vpc_security_group_ids = ["${aws_security_group.instance.id}"]
23+
24+
user_data = <<-EOF
25+
#!/bin/bash
26+
echo "Hello, World" > index.html
27+
nohup busybox httpd -f -p "${var.server_port}" &
28+
EOF
29+
30+
tags {
31+
Name = "terraform-example"
32+
}
33+
}
34+
35+
# ---------------------------------------------------------------------------------------------------------------------
36+
# CREATE THE SECURITY GROUP THAT'S APPLIED TO THE EC2 INSTANCE
37+
# ---------------------------------------------------------------------------------------------------------------------
38+
39+
resource "aws_security_group" "instance" {
40+
name = "terraform-example-instance"
41+
42+
# Inbound HTTP from anywhere
43+
ingress {
44+
from_port = "${var.server_port}"
45+
to_port = "${var.server_port}"
46+
protocol = "tcp"
47+
cidr_blocks = ["0.0.0.0/0"]
48+
}
49+
}

single-web-server/outputs.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
output "public_ip" {
2+
value = "${aws_instance.example.public_ip}"
3+
}

single-web-server/vars.tf

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# ---------------------------------------------------------------------------------------------------------------------
2+
# ENVIRONMENT VARIABLES
3+
# Define these secrets as environment variables
4+
# ---------------------------------------------------------------------------------------------------------------------
5+
6+
# AWS_ACCESS_KEY_ID
7+
# AWS_SECRET_ACCESS_KEY
8+
9+
# ---------------------------------------------------------------------------------------------------------------------
10+
# OPTIONAL PARAMETERS
11+
# ---------------------------------------------------------------------------------------------------------------------
12+
13+
variable "server_port" {
14+
description = "The port the server will use for HTTP requests"
15+
default = 8080
16+
}

0 commit comments

Comments
 (0)