How to make terraform Scripts Generic
- Variables Refer
Our Scenario
In the case of sample architecuture, i have created the following variables in a file called as vars.tf
# required variable accesskey
variable "accesskey" {
type = "string"
}
# required variable secretkey
variable "secretkey" {
type = "string"
}
# optional region
variable "region" {
type = "string"
default = "eu-west-3"
}
variable "subnet1az" {
type = "string"
default = "eu-west-3a"
}
variable "subnet2az" {
type = "string"
default = "eu-west-3b"
}
# optional ami-id
variable "appserverami" {
type = "string"
default = "ami-0ad37dbbe571ce2a1"
}
variable "awskeypair" {
type = "string"
default = "forterraform"
}
variable "sshusername" {
type = "string"
default = "ubuntu"
}
variable "sshkeypath" {
type = "string"
default = "./forterraform.pem"
}
Using Variables in terraform resources/providers/outputs
- Basic Syntax:
"${var.<variablename>}"
Lets Examine our Provider
provider "aws" {
region = "${var.region}"
access_key = "${var.accesskey}"
secret_key = "${var.secretkey}"
}
Lets Examine Our Resources
resource "aws_vpc" "my_network" {
cidr_block = "10.10.0.0/16"
enable_dns_hostnames = true
tags = {
Name = "openmrs"
}
}
resource "aws_subnet" "subnet_1" {
cidr_block = "10.10.0.0/24"
vpc_id = "${aws_vpc.my_network.id}"
availability_zone = "${var.subnet1az}"
tags = {
Name = "openmrs"
}
}
resource "aws_subnet" "subnet_2" {
cidr_block = "10.10.1.0/24"
vpc_id = "${aws_vpc.my_network.id}"
availability_zone = "${var.subnet2az}"
tags = {
Name = "openmrs"
}
}
resource "aws_internet_gateway" "my_igw" {
vpc_id = "${aws_vpc.my_network.id}"
tags = {
Name = "openmrs"
}
}
resource "aws_route_table" "my_rt" {
vpc_id = "${aws_vpc.my_network.id}"
route {
cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.my_igw.id}"
}
tags = {
Name = "openmrs"
}
}
resource "aws_security_group" "my_sg" {
name = "my_sg"
description = "created from terraform"
vpc_id = "${aws_vpc.my_network.id}"
ingress{
cidr_blocks = ["0.0.0.0/0"]
protocol = "-1"
from_port = "0"
to_port = "0"
}
egress{
cidr_blocks = ["0.0.0.0/0"]
protocol = "-1"
from_port = "0"
to_port = "0"
}
tags = {
Name = "openmrs"
}
}
resource "aws_route_table_association" "subnet1assoc" {
subnet_id = "${aws_subnet.subnet_1.id}"
route_table_id = "${aws_route_table.my_rt.id}"
}
resource "aws_route_table_association" "subnet2assoc" {
subnet_id = "${aws_subnet.subnet_2.id}"
route_table_id = "${aws_route_table.my_rt.id}"
}
resource "aws_instance" "web1" {
ami = "${var.appserverami}"
instance_type = "t2.micro"
subnet_id = "${aws_subnet.subnet_1.id}"
associate_public_ip_address = true
vpc_security_group_ids = [ "${aws_security_group.my_sg.id}" ]
key_name = "${var.awskeypair}"
tags = {
Name = "openmrs"
}
}
resource "aws_instance" "web2" {
ami = "${var.appserverami}"
instance_type = "t2.micro"
subnet_id = "${aws_subnet.subnet_2.id}"
associate_public_ip_address = true
vpc_security_group_ids = [ "${aws_security_group.my_sg.id}" ]
key_name = "${var.awskeypair}"
tags = {
Name = "openmrs"
}
}
The commands used to create infra
terraform validate -var 'accesskey=<your access key>' -var 'secretkey=<yoursecretkey>' .
terraform apply -var 'accesskey=<your access key>' -var 'secretkey=<yoursecretkey>' .
What is that we have acheived so far
- We were able to create ec2 machines and generalize the behavior.
- Now we can use this script to create ec2 machines in any account & also in any region
We need to install tomcat
- To do installations , we need to do provisioning
- Terraform Provisioning more info is available here
- To acheive our architecture we need to
- login into ec2 machines => This is acheived by using Terraform Provisioner Connections
- install tomcat => Can be acheived in different ways, in this example i would be shell script/linux commands (You can use ansible/chef)
Lets look at the script in Terraform to create two ec2 machines & install tomcat
# required variable accesskey
variable "accesskey" {
type = "string"
}
# required variable secretkey
variable "secretkey" {
type = "string"
}
# optional region
variable "region" {
type = "string"
default = "eu-west-3"
}
variable "subnet1az" {
type = "string"
default = "eu-west-3a"
}
variable "subnet2az" {
type = "string"
default = "eu-west-3b"
}
# optional ami-id
variable "appserverami" {
type = "string"
default = "ami-0ad37dbbe571ce2a1"
}
variable "awskeypair" {
type = "string"
default = "forterraform"
}
variable "sshusername" {
type = "string"
default = "ubuntu"
}
variable "sshkeypath" {
type = "string"
default = "./forterraform.pem"
}
provider "aws" {
region = "${var.region}"
access_key = "${var.accesskey}"
secret_key = "${var.secretkey}"
}
resource "aws_vpc" "my_network" {
cidr_block = "10.10.0.0/16"
enable_dns_hostnames = true
tags = {
Name = "openmrs"
}
}
resource "aws_subnet" "subnet_1" {
cidr_block = "10.10.0.0/24"
vpc_id = "${aws_vpc.my_network.id}"
availability_zone = "${var.subnet1az}"
tags = {
Name = "openmrs"
}
}
resource "aws_subnet" "subnet_2" {
cidr_block = "10.10.1.0/24"
vpc_id = "${aws_vpc.my_network.id}"
availability_zone = "${var.subnet2az}"
tags = {
Name = "openmrs"
}
}
resource "aws_internet_gateway" "my_igw" {
vpc_id = "${aws_vpc.my_network.id}"
tags = {
Name = "openmrs"
}
}
resource "aws_route_table" "my_rt" {
vpc_id = "${aws_vpc.my_network.id}"
route {
cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.my_igw.id}"
}
tags = {
Name = "openmrs"
}
}
resource "aws_security_group" "my_sg" {
name = "my_sg"
description = "created from terraform"
vpc_id = "${aws_vpc.my_network.id}"
ingress{
cidr_blocks = ["0.0.0.0/0"]
protocol = "-1"
from_port = "0"
to_port = "0"
}
egress{
cidr_blocks = ["0.0.0.0/0"]
protocol = "-1"
from_port = "0"
to_port = "0"
}
tags = {
Name = "openmrs"
}
}
resource "aws_route_table_association" "subnet1assoc" {
subnet_id = "${aws_subnet.subnet_1.id}"
route_table_id = "${aws_route_table.my_rt.id}"
}
resource "aws_route_table_association" "subnet2assoc" {
subnet_id = "${aws_subnet.subnet_2.id}"
route_table_id = "${aws_route_table.my_rt.id}"
}
resource "aws_instance" "web1" {
ami = "${var.appserverami}"
instance_type = "t2.micro"
subnet_id = "${aws_subnet.subnet_1.id}"
associate_public_ip_address = true
vpc_security_group_ids = [ "${aws_security_group.my_sg.id}" ]
key_name = "${var.awskeypair}"
tags = {
Name = "openmrs"
}
connection {
type = "ssh"
user = "${var.sshusername}"
private_key = "${file(var.sshkeypath)}"
host = "${aws_instance.web1.public_ip}"
}
provisioner "remote-exec" {
inline = [
"sudo apt-get update",
"sudo apt-get install openjdk-8-jdk -y",
"sudo apt-get install tomcat8 -y"
]
}
}
resource "aws_instance" "web2" {
ami = "${var.appserverami}"
instance_type = "t2.micro"
subnet_id = "${aws_subnet.subnet_2.id}"
associate_public_ip_address = true
vpc_security_group_ids = [ "${aws_security_group.my_sg.id}" ]
key_name = "${var.awskeypair}"
tags = {
Name = "openmrs"
}
connection {
type = "ssh"
user = "${var.sshusername}"
private_key = "${file(var.sshkeypath)}"
host = "${aws_instance.web2.public_ip}"
}
provisioner "remote-exec" {
inline = [
"sudo apt-get update",
"sudo apt-get install openjdk-8-jdk -y",
"sudo apt-get install tomcat8 -y"
]
}
}
output "webserver1-ip" {
value = "${aws_instance.web1.public_ip}"
}
output "webserver2-ip" {
value = "${aws_instance.web2.public_ip}"
}