Skip to main content

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