AWS
Terraform
俺でもわかるシリーズ

terraform 0.7系で作るEC2 Module

More than 1 year has passed since last update.

サーバーレス逆行委員会の俺ですこんにちわ。

縄文土器って最高に素敵ですね。

terraform 0.7からmap型やlist型の受け渡しが簡単になりました。

ついについにmoduleに手を出す日が来たようです。

ということでEC2いってみましょお


  • この記事を書いたときのterraform version: 0.7.3


ModuleのDirecoty構成

こんな感じで作りました。これがわかり易いかなあと(俺調べ)

modules/<provider_name>/<resource_name>

orenomac$ tree -d

.
└── modules
└── aws
└── ec2

3 directories


Moduleのtfファイル


  • variable.tf

variable "ec2" {

type = "map"
default = {}
}
variable "subnet_id" {}
variable "key_name" {}
variable "vpc_security_group_ids" {
type = "list"
default = []
}


  • main.tf

resource "aws_instance" "ec2" {

ami = "${var.ec2["ami"]}"
instance_type = "${var.ec2["instance_type"]}"
key_name = "${var.key_name}"
iam_instance_profile = "${var.ec2["iam_instance_profile"]}"
source_dest_check = "${var.ec2["source_dest_check"]}"
ebs_optimized = "${var.ec2["ebs_optimized"]}"
vpc_security_group_ids = ["${var.vpc_security_group_ids}"]
subnet_id = "${var.subnet_id}"
root_block_device {
volume_type = "${var.ec2["root_block_device"]}"
volume_size = "${var.ec2["root_block_device_size"]}"
}
count = "${var.ec2["count"]}"
tags {
Name = "${var.ec2["tag_name"]}-${format("%03d",count.index+1)}"
Role = "${var.ec2["tag_role"]}"
environment = "${var.ec2["tag_environment"]}"
}
}


  • output.tf

output "id" {

value = "${aws_instance.ec2.id}"
}
output "availability_zone" {
value = "${aws_instance.ec2.availability_zone}"
}
output "private_ip" {
value = "${aws_instance.ec2.private_ip}"
}
output "private_dns" {
value = "${aws_instance.ec2.private_dns}"
}


使い方

踏み台サーバを作るってことで

map型variable bastionにはEC2のLaunch情報を纏めておきます。

他のterraform resourceで作ったリソースのidを別引数として渡します


  • aws_key_pair

  • aws_subnet

  • aws_securitygroup


bastion.tf

variable "bastion" {

type = "map"
default = {
ami = "ami-XXXXXXXX"
instance_type = "t2.micro"
iam_instance_profile = "bastion"
source_dest_check = true
ebs_optimized = false
root_block_device = "gp2"
root_block_device_size = 64
count = 1
tag_name = "bastion"
tag_role = "bastion"
}
}
resource "aws_eip" "bastion" {
instance = "${module.bastion.id}"
vpc = true
}

module "bastion" {
source = "./modules/aws/ec2"
ec2 = "${var.bastion}"
key_name = "${aws_key_pair.bastion.key_name}"
subnet_id = "${aws_subnet.public_ap-northeast-1a.id}"
vpc_security_group_ids = ["${aws_security_group.bastion.id}"]
}

これでおk牧場です。

以下もうちょっと進化待ちの箇所


  • LaunchしたEC2のName Tagにcount indexは指定せずAvailability ZoneとInstance IDを指定するのが最近のジャスティスなのですが自己resource内のattribute参照は循環参照扱いになるのでできません。残念。countで我慢

例)↓な感じ

    count = "${var.ec2["count"]}"

tags {
Name = "${var.ec2["tag_name"]}-${aws_instance.ec2.availability_zone}-${aws_instance.ec2.id}"
}
}


  • map型に他resourceのattributeをぶち込んだら1つのmap渡すだけでスッキリすると思うのですができません。残念。引数分けて我慢

例)↓な感じ

variable "bastion" {

type = "map"
default = {
ami = "ami-XXXXXXXX"
instance_type = "t2.micro"
iam_instance_profile = "${aws_iam_instance_profile.bastion.name}"
subnet_id = "${aws_subnet.public_ap-northeast-1a.id}"
vpc_security_group_ids = ["${aws_securitygroup.bastion.id}"]
source_dest_check = true
ebs_optimized = false
root_block_device = "gp2"
root_block_device_size = 64
count = 1
tag_name = "bastion"
tag_role = "bastion"
}
}

おわり