Terraform入門してみた

2016–09–24

まずはこのBlogをホストしている環境をTerrraorrm化してみました。 いまだにClassic EC2を使ってたので、そろそろ再構築したかったんですよね。

インストール

https://www.terraform.io/downloads.html ダウンロードしたファイルを解凍して、terraformファイルにパスを通しておきます。

構成

1つのVPCに1つのsubnetを割り振って、その中でインスタンスを起動します。 ELBは使わず、EIPを割り振ります。

実行

アクセスキーとシークレットキーを環境変数に設定します。

$ export AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXXXXXX
$ export AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
$ export AWS_DEFAULT_REGION=ap-northeast-1	  
$ terraform plan	  

で変更箇所を確認して、

$ terraform apply	  

で実行します。

terraform.tfstateの管理

terraformはterraform.tfstateというファイルで、対象のインフラ構成の状態を管理しています。 実際のインフラ構成の状態をこのファイルで管理しているので、重要なファイルです。

こいつはterraformを実行するどの環境でも同じ物である必要があります。 というわけで、こいつをS3で管理してみます。

$ aws s3 mb s3://gside-terraform-state
make_bucket: s3://gside-terraform-state/
$ terraform remote config -backend=S3 -backend-config="bucket=gside-terraform-state" -backend-config="key=terraform.tfstate"
Remote configuration updated
Remote state configured and pulled.	  

この設定の後は、S3でterraform.tfstateファイルを管理しつつ、特にS3を意識することなくterraformが使えます。

まとめ

拍子抜けするくらい簡単にterraform化が終わってしまいました。 既存の環境をimportする機能もついたということで、ますます利用するシーンが増えそうです。

参考に今回実行したコードを載せておきます。

resource "aws_vpc" "main" {
    cidr_block = "10.0.0.0/16"
}

resource "aws_internet_gateway" "gw" {
    vpc_id = "${aws_vpc.main.id}"

    tags {
        Name = "main"
    }
}

resource "aws_subnet" "main" {
    vpc_id = "${aws_vpc.main.id}"
    cidr_block = "10.0.1.0/24"

    tags {
        Name = "Main"
    }
}

resource "aws_route_table" "r" {
    vpc_id = "${aws_vpc.main.id}"
    route {
        cidr_block = "0.0.0.0/0"
        gateway_id = "${aws_internet_gateway.gw.id}"
    }

    tags {
        Name = "main"
    }
}

resource "aws_route_table_association" "a" {
    subnet_id = "${aws_subnet.main.id}"
    route_table_id = "${aws_route_table.r.id}"
}

resource "aws_security_group" "basic" {
    name        = "basic"
    description = "basic security group for web"
    vpc_id      = "${aws_vpc.main.id}"

    ingress {
        from_port       = 22
        to_port         = 22
        protocol        = "tcp"
        cidr_blocks     = ["0.0.0.0/0"]
    }

    ingress {
        from_port       = 80
        to_port         = 80
        protocol        = "tcp"
        cidr_blocks     = ["0.0.0.0/0"]
    }

    ingress {
        from_port       = 443
        to_port         = 443
        protocol        = "tcp"
        cidr_blocks     = ["0.0.0.0/0"]
    }


}

resource "aws_instance" "gside" {
    ami                         = "ami-c1fe26a2"
    availability_zone           = "${aws_subnet.main.availability_zone}"
    ebs_optimized               = false
    associate_public_ip_address = false
    instance_type               = "t1.micro"
    monitoring                  = false
    key_name                    = "ec2Key"
    vpc_security_group_ids      = ["${aws_security_group.basic.id}"]
    associate_public_ip_address = true
    private_ip                  = "10.0.1.10"
    disable_api_termination     = "true"
    source_dest_check           = "false"
    subnet_id 			= "${aws_subnet.main.id}"

    root_block_device {
        volume_type           = "gp2"
        volume_size           = 10
        delete_on_termination = true
    }

    tags {
        "Name" = "gside"
    }
}

resource "aws_eip" "gside" {
  vpc = true

  instance                  = "${aws_instance.gside.id}"
  associate_with_private_ip = "10.0.1.10"
}
</code>