Skip to content

Instantly share code, notes, and snippets.

@wokamoto
Last active April 20, 2017 06:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wokamoto/167a7e92a4ef16370e20c3f693534701 to your computer and use it in GitHub Desktop.
Save wokamoto/167a7e92a4ef16370e20c3f693534701 to your computer and use it in GitHub Desktop.
[AWS] Terraform で EFS 作って、EC2 起動時にマウントさせておく ref: http://qiita.com/wokamoto/items/c70b12ed104b23fd7188
## IAM Instance Profile
resource "aws_iam_instance_profile" "instance_role" {
name = "instance_role"
role = "${aws_iam_role.instance_role.name}"
}
## SSH Key
resource "aws_key_pair" "deployer" {
key_name = "${var.project}"
public_key = "${var.ssh_public_key}"
}
## EC2
resource "aws_instance" "app" {
ami = "${lookup(var.ami,var.region)}"
availability_zone = "${aws_subnet.a.availability_zone}"
ebs_optimized = false
instance_type = "t2.micro"
monitoring = true
key_name = "${aws_key_pair.deployer.key_name}"
subnet_id = "${aws_subnet.a.id}"
vpc_security_group_ids = ["${aws_security_group.ec2.id}"]
associate_public_ip_address = true
source_dest_check = true
iam_instance_profile = "${aws_iam_instance_profile.instance_role.id}"
disable_api_termination = false
user_data = <<USERDATA
#!/bin/bash
az="${aws_subnet.a.availability_zone}"
efs_region="${var.region}"
efs_id="${aws_efs_file_system.app.id}"
efs_mount_target="${aws_efs_mount_target.app-a.dns_name}:/"
efs_mount_point="/mnt/efs/$${efs_id}/$${az}"
web_doc_root="/var/www/html"
# EFS Mount
/usr/bin/yum -y install nfs-utils || /usr/bin/yum -y update nfs-utils
if [ ! -d $${efs_mount_point} ]; then
mkdir -p $${efs_mount_point}
fi
cp -pi /etc/fstab /etc/fstab.$(date "+%Y%m%d")
echo "$${efs_mount_target} $${efs_mount_point} nfs4 defaults" | tee -a /etc/fstab
mount $${efs_mount_point}
# create Web document root
if [ -d $${web_doc_root} ]; then
rm -rf $${web_doc_root}
fi
if [ ! -d $${efs_mount_point}/html ]; then
mkdir $${efs_mount_point}/html
chown ec2-user:ec2-user $${efs_mount_point}/html
fi
ln -s $${efs_mount_point}/html $${web_doc_root}
chown -h ec2-user:ec2-user $${web_doc_root}
USERDATA
root_block_device {
volume_type = "gp2"
volume_size = 10
delete_on_termination = true
}
tags {
"Name" = "${var.domain}"
}
}
resource "aws_efs_file_system" "app" {
tags {
"Name" = "${var.domain}"
}
}
resource "aws_efs_mount_target" "app-a" {
file_system_id = "${aws_efs_file_system.app.id}"
subnet_id = "${aws_subnet.a.id}"
security_groups = ["${aws_security_group.efs.id}"]
}
resource "aws_efs_mount_target" "app-b" {
file_system_id = "${aws_efs_file_system.app.id}"
subnet_id = "${aws_subnet.b.id}"
security_groups = ["${aws_security_group.efs.id}"]
}
resource "aws_efs_mount_target" "app-c" {
file_system_id = "${aws_efs_file_system.app.id}"
subnet_id = "${aws_subnet.c.id}"
security_groups = ["${aws_security_group.efs.id}"]
}
$ terraform plan \
-var 'project=example' \
-var 'domain=example.com'
$ terraform import aws_instance.app ${instance_id}
$ terraform plan
$ terraform apply
provider "aws" {
access_key = "__ACCESS_KEY__"
secret_key = "__SECRET_KEY__"
region = "us-west-2"
}
## For EC2 instance Role
resource "aws_iam_role" "instance_role" {
name = "instance_role"
path = "/"
assume_role_policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
POLICY
}
## AmazonEC2RoleforDataPipelineRole
resource "aws_iam_role_policy_attachment" "data-pipeline" {
role = "${aws_iam_role.instance_role.name}"
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforDataPipelineRole"
}
## PutCloudwatchLogs
resource "aws_iam_policy" "put-cloudwatch-logs" {
name = "AmazonEC2PutCloudwatchLogs"
description = ""
policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
POLICY
}
resource "aws_iam_role_policy_attachment" "put-cloudwatch-logs" {
role = "${aws_iam_role.instance_role.name}"
policy_arn = "${aws_iam_policy.put-cloudwatch-logs.arn}"
}
resource "aws_iam_role" "instance_role" {
name = "instance_role"
path = "/"
assume_role_policy = "${file("data/instance_role_assume_policy.json")}"
}
resource "aws_iam_role" "instance_role" {
name = "instance_role"
path = "/"
assume_role_policy = "${file("data/instance_role_assume_policy.json")}"
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
# 今回のプロジェクト名
variable "project" {}
variable "domain" {}
# AWS リソースを起動するリージョンとかの情報
variable "region" { default = "us-west-2" }
variable "azs" {
default {
"a" = "us-west-2a"
"b" = "us-west-2b"
"c" = "us-west-2c"
}
}
# AMI ID (Amazon Linux)
variable "ami" {
default {
"us-west-2" = "ami-8ca83fec"
}
}
# EC2 接続用の SSH 鍵の公開鍵
variable "ssh_public_key" {}
provider "aws" {
region = "${var.region}"
}
## Internet Gateway
resource "aws_internet_gateway" "igw" {
vpc_id = "${aws_vpc.app.id}"
}
## Route Table
resource "aws_route_table" "rtb" {
vpc_id = "${aws_vpc.app.id}"
route {
cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.igw.id}"
}
}
resource "aws_route_table_association" "route_a" {
subnet_id = "${aws_subnet.a.id}"
route_table_id = "${aws_route_table.rtb.id}"
}
resource "aws_route_table_association" "route_b" {
subnet_id = "${aws_subnet.b.id}"
route_table_id = "${aws_route_table.rtb.id}"
}
resource "aws_route_table_association" "route_c" {
subnet_id = "${aws_subnet.c.id}"
route_table_id = "${aws_route_table.rtb.id}"
}
## For EC2
resource "aws_security_group" "ec2" {
name = "${var.project}-EC2"
description = "for ${var.project} EC2"
vpc_id = "${aws_vpc.app.id}"
ingress = [
{
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
},
{
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
},
{
from_port = 22
to_port = 22
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"]
}
}
## For EFS
resource "aws_security_group" "efs" {
name = "${var.project}-EFS"
description = "for ${var.project} EFS"
vpc_id = "${aws_vpc.app.id}"
ingress {
from_port = 2049
to_port = 2049
protocol = "tcp"
security_groups = ["${aws_security_group.ec2.id}"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
## VPC
resource "aws_vpc" "app" {
cidr_block = "172.31.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
instance_tenancy = "default"
tags {
"Name" = "${var.project}"
}
}
## Subnet
resource "aws_subnet" "a" {
vpc_id = "${aws_vpc.app.id}"
cidr_block = "172.31.0.0/20"
availability_zone = "${lookup(var.azs,"a")}"
map_public_ip_on_launch = true
tags {
"Name" = "${var.project}-subnet-a"
}
}
resource "aws_subnet" "b" {
vpc_id = "${aws_vpc.app.id}"
cidr_block = "172.31.16.0/20"
availability_zone = "${lookup(var.azs,"b")}"
map_public_ip_on_launch = true
tags {
"Name" = "${var.project}-subnet-b"
}
}
resource "aws_subnet" "c" {
vpc_id = "${aws_vpc.app.id}"
cidr_block = "172.31.32.0/20"
availability_zone = "${lookup(var.azs,"c")}"
map_public_ip_on_launch = true
tags {
"Name" = "${var.project}-subnet-c"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment