first step of terraform
install
$ wget url https://releases.hashicorp.com/terraform/x.xx.xx/terraform_x.xx.xx_linux_amd64.zip
$ unzip terraform_x.xx.xx_linux_amd64.zip
$ cp terraform /usr/local/bin
sample varible file
terraform.tfvars
# region = "ap-northeast-2"
# az = {
# zone0 = "ap-northeast-2a"
# zone1 = "ap-northeast-2b"
# }
# ami = "ami-0d79f772de48b11f7"
cidr_block = "172.16.0.0/16"
cidr_subnet0 = "172.16.0.0/24"
cidr_subnet1 = "172.16.10.0/24"
sample tf file
test.tf
variable "region" {
default = "ap-northeast-1"
}
variable "az" {
default = {
zone0 = "ap-northeast-1a"
zone1 = "ap-northeast-1c"
}
}
variable "ami" {
default = "ami-03a1ce3bba6d67270"
}
variable "instance_type" {
default = "t3.nano"
}
variable "cidr_block" {}
variable "cidr_subnet0" {}
variable "cidr_subnet1" {}
variable "operation_addr" {}
variable "key_name" {}
variable "private_key" {}
provider "aws" {
region = var.region
}
resource "aws_vpc" "terraform_test_vpc" {
cidr_block = var.cidr_block
instance_tenancy = "default"
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "terraform_test"
}
}
resource "aws_subnet" "terraform_test_subnet0" {
vpc_id = aws_vpc.terraform_test_vpc.id
cidr_block = var.cidr_subnet0
availability_zone = var.az.zone0
tags = {
Name = "terraform_test"
}
}
resource "aws_subnet" "terraform_test_subnet1" {
vpc_id = aws_vpc.terraform_test_vpc.id
cidr_block = var.cidr_subnet1
availability_zone = var.az.zone1
tags = {
Name = "terraform_test"
}
}
resource "aws_internet_gateway" "terraform_test_igw" {
vpc_id = aws_vpc.terraform_test_vpc.id
tags = {
Name = "terraform_test"
}
}
resource "aws_route_table" "terraform_test_route" {
vpc_id = aws_vpc.terraform_test_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.terraform_test_igw.id
}
tags = {
Name = "terraform_test"
}
}
resource "aws_route_table_association" "terraform_test_subnet0" {
subnet_id = aws_subnet.terraform_test_subnet0.id
route_table_id = aws_route_table.terraform_test_route.id
}
resource "aws_route_table_association" "terraform_test_subnet1" {
subnet_id = aws_subnet.terraform_test_subnet1.id
route_table_id = aws_route_table.terraform_test_route.id
}
resource "aws_security_group" "sg_ssh_web" {
name = "terraform_test_security_group"
description = "allow inbound ssh and web traffic"
vpc_id = aws_vpc.terraform_test_vpc.id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = [var.operation_addr]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_instance" "ec2_public" {
ami = var.ami
instance_type = var.instance_type
key_name = var.key_name
vpc_security_group_ids = [
aws_security_group.sg_ssh_web.id,
]
subnet_id = aws_subnet.terraform_test_subnet0.id
associate_public_ip_address = "true"
user_data = file("userdata.sh")
connection {
user = "admin"
host = self.public_ip
private_key = file(var.private_key)
}
provisioner "file" {
source = "index.html"
destination = "~/index.html"
}
provisioner "remote-exec" {
inline = [
"sudo apt update",
"sudo apt install -y nginx",
"sudo mv ~/index.html /var/www/html"
]
}
tags = {
Name = "terraform_test"
}
}
output "public_dns" {
value = aws_instance.ec2_public.public_dns
}
ininialize
install plugin file under the current directory
$ terraform init
validate tf file
$ terraform validate
apply
$ terraform plan -out=apply.plan -var 'operation_addr=xxx.xxx.xxx.xxx/xx' -var 'key_name=mykey' -var 'private_key=./id_rsa.mykey'
$ terraform apply -auto-approve "apply.plan"
or when destroy
$ terraform plan -destroy -out=apply.plan -var 'operation_addr=xxx.xxx.xxx.xxx/xx' -var 'key_name=mykey' -var 'private_key=./id_rsa.mykey' -target aws_instance.web1
$ terraform apply -auto-approve "destroy.plan"
confirm result
$ terraform show
destroy
$ terraform destroy -auto-approve -var 'operation_addr=xxx.xxx.xxx.xxx/xx' -var 'key_name=mykey' -var 'private_key=./id_rsa.mykey'
sample ansible playbook
apply.playbook
- hosts: localhost
connection: local
gather_facts: no
tasks:
- name: terraform plan
terraform:
project_path: './'
state: planned
plan_file: ansible.plan
variables:
operation_addr: "{{ operation_addr }}"
key_name: "{{ key_name }}"
private_key: "{{ private_key }}"
register: result
- name: debug result
debug:
var: result
- name: terraform apply
terraform:
project_path: './'
state: present
plan_file: ansible.plan
variables:
operation_addr: "{{ operation_addr }}"
key_name: "{{ key_name }}"
private_key: "{{ private_key }}"
when: not ansible_check_mode
register: result
- name: debug result
debug:
var: result
when: not ansible_check_mode
destroy.playbook
- hosts: localhost
connection: local
gather_facts: no
tasks:
- name: terraform destroy
terraform:
project_path: './'
state: absent
plan_file: ansible.plan
variables:
operation_addr: "{{ operation_addr }}"
key_name: "{{ key_name }}"
private_key: "{{ private_key }}"
when: not ansible_check_mode
register: result
- name: debug result
debug:
var: result
when: not ansible_check_mode
apply and destroy with ansible
$ jq . extravars.json
{
"operation_addr": "xxx.xxx.xxx.xxx/xx",
"key_name": "mykey",
"private_key": "id_rsa.mykey"
}
$ ansible-playbook --check -e @extravars.json apply.playbook
$ ansible-playbook -e @extravars.json apply.playbook
$ ansible-playbook --check -e @extravars.json destroy.playbook
$ ansible-playbook -e @extravars.json destroy.playbook