最近Terraformに入門しました!!!!!
初なのでブログしたいと思います。
■Terraformってなに
HashiCorpが作っているインフラ構築や設定をコード化し自動化するためのツール。今回はAWSですが、他のクラウドにも対応しているのが見どころ。Hashicorpと言えば、「Vagrant」「Nomad」などが有名。
・ちなみに対応しているクラウド
- Atlas
- AWS
- Azure
- CloudFlare
- CloudStack
- Consul
- DigitalOcean
- DNSMadeEasy
- DNSimple
- Docker
- Google Cloud Platform
- Heroku
- Mailgun
- OpenStack
こんなに!!ところで、
adachin server labブログもクラウドにリプレイスしようと考えてるので、Terraform使えば楽そう。Terraformの開発は毎月のペースで新バージョンがリリースされるのでこれは熱い!
■今回実装すること
・VPC
インターネットゲートウェイの設定
サブネットの設定(冗長化のため2つ用意)
ルートテーブルの設定
セキュリティグループの設定
・EC2(1台)
OSはamazon linux
上記のVPC、セキュリティグループを使用
EBSは30GB
ここらへんを自動化してみました。
■環境
Macを使ってローカルから実行。
■Terraformのインストール
| 1 | $ brew install terraform | 
以前はterraformコマンドを実行するためにパスの設定やら必要だったのですが、
brewがよしなにやってくれるのでOK。
| 1 2 | $ terraform -v Terraform v0.8.5 | 
■Terraformの構成
| 1 2 3 4 5 6 7 8 9 10 | $ tree terraform terraform └── envs         ├── aws #AWS用         │   ├── aws_region.tf         │   ├── aws_vpc.tf         │   ├── aws_ec2.tf         │   ├── aws_security-group.tf         │   └── variables.tf         ├── gcp #GCP用 | 
■aws_resion.tf
| 1 2 3 4 5 | provider "aws" {     access_key = "xxxxxxx"     secret_key = "xxxxxxx"     region = "ap-northeast-1" } | 
ここはプロバイダーの設定をぶち込みます。
awsでいうIAMからユーザ作ってアクセスキーとシークレットキーを書いて、
terraformを使えるようにします。
このファイルはgithubにあげるとAWSからセキュリティアラートが来るので気をつけてください。その後 terraform init で以下の設定をします。
■aws_vpc.tf
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | ## VPCの設定 resource "aws_vpc" "adachin-web_vpc" {   cidr_block           = "10.0.0.0/16"   instance_tenancy     = "default"   enable_dns_support   = true   enable_dns_hostnames = true   tags {     Name = "adachin-web_vpc"   } } ##サブネットの作成(1a) resource "aws_subnet" "public-a" {   vpc_id            = "${aws_vpc.adachin-web_vpc.id}"   cidr_block        = "10.0.0.0/24"   availability_zone = "ap-northeast-1a"   tags {     Name = "adachin-web_1a"   } } ##サブネットの追加(1c) resource "aws_subnet" "public-c" {   vpc_id            = "${aws_vpc.adachin-web_vpc.id}"   cidr_block        = "10.1.0.0/24"   availability_zone = "ap-northeast-1c"   tags {     Name = "adachin-web_1c"   } } ##ルートテーブルの追加(0.0.0.0/0) resource "aws_route_table" "public-route" {   vpc_id = "${aws_vpc.adachin-web_vpc.id}"   route {     cidr_block = "0.0.0.0/0"     gateway_id = "${aws_internet_gateway.adachin-web_GW.id}"   } } ##ルートテーブルの追加(1a) resource "aws_route_table_association" "puclic-a" {   subnet_id      = "${aws_subnet.public-a.id}"   route_table_id = "${aws_route_table.public-route.id}" } ##ルートテーブルの追加(1c) resource "aws_route_table_association" "puclic-c" {   subnet_id      = "${aws_subnet.public-c.id}"   route_table_id = "${aws_route_table.public-route.id}" } ##ゲートウェイの設定 resource "aws_internet_gateway" "adachin-web_GW" {   vpc_id = "${aws_vpc.adachin-web_vpc.id}" } | 
■aws_security-group.tf
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | ## security group (adachin-web) resource "aws_security_group" "adachin-web" {   name        = "adachin-web"   description = "adachin-web"   vpc_id      = "${aws_vpc.adachin-web_vpc.id}"   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"]   }   egress {     from_port   = 0     to_port     = 0     protocol    = "-1"     cidr_blocks = ["0.0.0.0/0"]   }   egress {     from_port        = 0     to_port          = 0     protocol         = "-1"     ipv6_cidr_blocks = ["::/0"]   }   tags {     Name = "adachin-web"   } } ## security group (adachin-web ALB) resource "aws_security_group" "adachin-web-ALB" {   name        = "adachin-web-ALB"   description = "adachin-web-ALB"   vpc_id      = "${aws_vpc.adachin-web_vpc.id}"   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"]   }   egress {     from_port   = 0     to_port     = 0     protocol    = "-1"     cidr_blocks = ["0.0.0.0/0"]   }   egress {     from_port        = 0     to_port          = 0     protocol         = "-1"     ipv6_cidr_blocks = ["::/0"]   }   tags {     Name = "adachin-web-ALB"   } } ## security group (RDS) resource "aws_security_group" "adachin-web-rds" {   name        = "adachin-web-rds"   description = "rds"   vpc_id      = "${aws_vpc.adachin-web_vpc.id}"   ingress {     from_port       = 0     to_port         = 0     protocol        = "-1"     security_groups = ["${aws_security_group.adachin-web.id}"]   }   egress {     from_port   = 0     to_port     = 0     protocol    = "-1"     cidr_blocks = ["0.0.0.0/0"]   }   egress {     from_port        = 0     to_port          = 0     protocol         = "-1"     ipv6_cidr_blocks = ["::/0"]   }   tags {     Name = "adachin-web-rds"   } } | 
■aws_ec2.tf
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ##EC2(adachin-web01) resource "aws_instance" "adachin-web01" {   ami                     = "${var.ami}"   instance_type           = "${var.instance_type}"   disable_api_termination = false   key_name                = "adachi_aws"   vpc_security_group_ids  = ["${aws_security_group.adachin-web.id}"]   subnet_id               = "${aws_subnet.public-a.id}"   root_block_device = {     device_name = "/dev/sdf"     volume_type = "gp2"     volume_size = "${var.volume_size}"   }   tags {     Name = "adachin-web01"   } } ##EIP(adachin-web01) resource "aws_eip" "adachin-web01" {   instance = "${aws_instance.adachin-web01.id}"   vpc      = true } | 
■variables.tf
| 1 2 3 4 5 6 7 | variable "ami" {     default = "ami-xxxxxx"  } variable "instance_type" {     default = "t2.micro"  } | 
variabled.tfは変数として使用しているファイルです。
今回はAMIとインスタンスタイプだけです。
他にも変数化できそうだけれども。。
■terraform plan(dry run)
| 1 2 3 4 5 | $ terraform plan Refreshing Terraform state prior to plan... ... + aws_vpc.adachin-web_vpc ~省略~ | 
さてこのコード化したファイルを実行してインフラ構築してみましょう。
その前に、
このプログラムで問題ないか、dry runをして確認します。
「+」マークが付いているのが新規に作成されるリソースです。
大丈夫であればterraform applyで適用します。
■terraform apply
| 1 2 3 4 5 6 7 8 9 | $ terraform apply aws_vpc.adachin-web_vpc: Creating...  ~省略~ ... Apply complete! Resources: x added, 0 changed, 0 destroyed. ... | 
これでAWSコンソール見ると、まあ不思議!
コード化したものがちゃんと出来上がっています。
■terraform plan -destroy
| 1 2 3 4 5 6 7 | $ terraform plan -destroy ... ~省略~ Plan: 0 to add, 0 to change, 7 to destroy. | 
先程作ったものを消したい場合もdry runであれば上記の様に。
■terraform destroy
| 1 2 3 4 5 6 7 8 9 10 | $ terraform destroy Do you really want to destroy?  Terraform will delete all your managed infrastructure.  There is no undo. Only 'yes' will be accepted to confirm.  Enter a value: yes ... Apply complete! Resources: 0 added, 0 changed, 7 destroyed. | 
AWSコンソールを見れば消えてることが分かると思います。
■まとめ
自動化は素晴らしいいい!コード化していれば、このインフラ構成はどうなっているのか理解できるし、解約時の場合はterraform destroyコマンドで全て消えるので、あれ何か残ってる?料金未だに発生してるのだが。。みたいなこともなさそう。ちなみにバグは未だにあるらしいですがw今のところ出会ってない。。
そういえばAWSが出してるCloudFormationでも同様なことができてからの
ansibleでもcloudモジュール使えばインフラ構築できます。
そしてインフラ構築はHashicorp、ミドルウェアはansibleにしようと決めました!
次回はELB、CloudFront、Route53など紹介できれば!!Terraformおじさんへ!

 
													 
													 
													
0件のコメント