準備するもの
今回は、なるべく簡単な形で EC2 を作成して、ローカル端末から SSH で接続できるようにしたいという目標で行きます。
Terraform で EC2 を作成するには以下のものを準備する必要があります。
- AWS アカウント(Access key ID, Secret access key)
- VPC
- IGW
- Subnet
- SecurityGroup
- SSH pub_key
- AMI
本当はこの他にも色々あるんです。簡単な EC2 を作成するという前提なのでこんな感じです。
AWS のコンソール画面でポチポチやっている以上に、実際には中身で色々設定しなければいけません。
Terraform のディレクトリ構成
Terraform で EC2 を作成するに当たって、ディレクトリ構成はこちらでいきます。
terraform_aws_test
|-- .terraform # terraform init 実行で作成
|-- plugins
|-- windows_amd64
|-- lock.json
|-- terraform-provider-aws_v2.66.0_x4.exe
|-- main.tf
|-- terraform.tfvars
|-- variables.tf
PVC の作成については、過去の記事で紹介しましたので詳細は割愛します。
各サービスの作成
それでは、一つ一つのサービスの作り方を確認していきます。
IGW
VPC の id を引用する形で作成すると、IGW 作成時に VPC にアタッチできます。
また、Terraform を用いて作成した resource を区別するために、Name, Owner タグを常にセットすることとします。
以下の main.tf で VPC と IGW を作成できます。
main.tf
# Terraform version
terraform {
required_version = "= 0.12.26"
}
# Provider
provider "aws" {
version = "2.66.0"
access_key = var.aws_access_key
secret_key = var.aws_secret_key
region = var.aws_region
}
# VPC
resource "aws_vpc" "vpc" {
cidr_block = var.aws_vpc_cidr
instance_tenancy = "default"
enable_dns_support = "true"
enable_dns_hostnames = "false"
tags = {
Name = var.aws_tags_name
Owner = var.aws_tags_owner
}
}
# IGW
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.vpc.id
tags = {
Name = var.aws_tags_name
Owner = var.aws_tags_owner
}
}
Subnet
続いて、Subet を作成します。 ※以下の内容は main.tf に追記しています。
ポイント1つ目は map_public_ip_on_launch = true とすることです。こうすることで、EC2 の作成時に Public IP をセットすることが出来ます。
ポイント2つ目は route table です。route table の外部経路を有効にしておかないと EC2 で yum コマンド等が実行できません。
main.tf
# Subnet
resource "aws_subnet" "subnet" {
vpc_id = aws_vpc.vpc.id
cidr_block = var.aws_subnet_cidr
map_public_ip_on_launch = true
tags = {
Name = var.aws_tags_name
Owner = var.aws_tags_owner
}
}
# Route Table
resource "aws_route_table" "route_table" {
vpc_id = aws_vpc.vpc.id
tags = {
Name = var.aws_tags_name
Owner = var.aws_tags_owner
}
}
# Route
resource "aws_route" "route" {
destination_cidr_block = "0.0.0.0/0"
route_table_id = aws_route_table.route_table.id
gateway_id = aws_internet_gateway.igw.id
}
# Route Table Asoociation
resource "aws_route_table_association" "route_table_association" {
subnet_id = aws_subnet.subnet.id
route_table_id = aws_route_table.route_table.id
}
Security Group
原則、全てのリソースに対してアクセス制限を行うべきです。
まずは、自宅やオフィス以外からは SSH できないよう制限したいと思います。
main.tf
# Security Group
resource "aws_security_group" "security_group" {
name = var.aws_tags_name
description = "Twemily Public Security Group"
vpc_id = aws_vpc.vpc.id
ingress {
description = "SSH"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = [var.my_home_ip,var.my_office_ip]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = var.aws_tags_name
Owner = var.aws_tags_owner
}
}
以上でネットワーク関連の設定は完了です。
EC2 の作成
まだ、準備が終わっていないのは以下の2つです。
それぞれ準備していきましょう。
SSH pub_key
Terraform の Resource: aws_key_pair を見ればわかる通り、public key は直接入力し登録しなければいけません。言い換えれば、Terraform では公開鍵はインポートしかできません。
コンソール画面で key-pair を作成したら秘密鍵がダウンロードできましたが、その機能は現時点(2020年6月)では Terraform には備わっていません。
tls_private_key を利用すれば、Terraform で鍵が作成できますが、今回は簡単に手元で鍵を作成してアップロードという方法を取ります。
Windows10 でも Git をインストールして PATH を通していれば ssh-keygen コマンドが使用できます。
PS C:\...\terraform-aws-test02> ssh-keygen -t rsa -b 4096
Generating public/private rsa key pair.
Enter file in which to save the key (C:\Users\xxxxx/.ssh/id_rsa): C:\Users\xxxxx\Documents\key\twemily_private
Enter passphrase (empty for no passphrase): # no passphrase enter
Your identification has been saved in C:\Users\xxxxx\Documents\key\twemily_private.
Your public key has been saved in C:\Users\xxxxx\Documents\key\twemily_private.pub.
この作成した鍵を aws_key_pair に登録します。
main.tf
resource "aws_key_pair" "key_pair" {
key_name = var.aws_key_name
public_key = file(var.public_key_path)
tags = {
Name = var.aws_tags_name
Owner = var.aws_tags_owner
}
}
Windows の場合、file(var.public_key_path) の環境情報指定に注意です。
path の情報をそのまま入力すると Error: Invalid escape sequence が出ます。
バックスラッシュが escape 文字です。
terraform.tfvars
aws_key_name = "twemily-key"
public_key_path = "C:\\Users\\xxxxx\\Documents\\key\\twemily_private.pub"
AMI
続いて、AMIを取得する方法ですが、ここでは最新の AmazonLinux2 の AMI を使用するよう指定します。
main.tf
# aws_key_pair
data "aws_ssm_parameter" "amzn2_ami" {
name = "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
}
この "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2" は AWS が用意してくれているものです。
EC2
これで EC2 を作成するための材料が揃いました。
EBS のタイプやボリュームサイズは任意に指定してください。
main.tf
# EC2
resource "aws_instance" "twemily_ec2" {
ami = data.aws_ssm_parameter.amzn2_ami.value
instance_type = var.aws_ec2_instance_type
key_name = aws_key_pair.key_pair.key_name
vpc_security_group_ids = [
aws_security_group.security_group.id
]
subnet_id = aws_subnet.subnet.id
root_block_device {
volume_type = var.aws_ec2_volume_type
volume_size = var.aws_ec2_volume_size
}
tags = {
Name = var.aws_tags_name
Owner = var.aws_tags_owner
}
}
terraform.tfvars と variables.tf は最終的にこんな感じになっています。
terraform.tfvars
terraform.tfvars
aws_access_key = "xxxxxxxxxxxxxxxxxxx"
aws_secret_key = "xxxxxxxxxxxxxxxxxxxxxxxxx"
aws_region = "eu-west-1"
aws_vpc_cidr = "10.113.0.0/16"
aws_subnet_cidr = "10.113.1.0/24"
aws_tags_owner = "koizumi"
aws_tags_name = "Twemily"
aws_key_name = "twemily-key"
aws_amzn2_ami = "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
aws_ec2_instance_type = "t2.micro"
aws_ec2_volume_type = "gp2"
aws_ec2_volume_size = "30"
my_home_ip = "XXX.XXX.XXX.XXX/32"
my_office_ip = "XXX.XXX.XXX.XXX/32"
public_key_path = "C:\\Users\\xxxxx\\Documents\\key\\twemily_private.pub"
variables.tf
variables.tf
variable aws_access_key {}
variable aws_secret_key {}
variable aws_region {}
variable aws_vpc_cidr {}
variable aws_tags_owner {}
variable aws_tags_name {}
variable aws_subnet_cidr {}
variable my_home_ip {}
variable my_office_ip {}
variable aws_key_name {}
variable public_key_path {}
variable aws_amzn2_ami {}
variable aws_ec2_instance_type {}
variable aws_ec2_volume_type {}
variable aws_ec2_volume_size {}
稼働確認
まずは、Terraform コマンドを実行して resource を作成しましょう。
> terraform plan
Plan: 9 to add, 0 to change, 0 to destroy.
> terraform apply
Apply complete! Resources: 9 added, 0 changed, 0 destroyed.
リソースが作成されているかコンソール画面で確認しましょう。
EC2
Key-pair
Security Group
接続してみましょう
問題なく resource が作成されているようです。
実際に接続できるか確かめてみましょう。
AmazonLinux2 で最初に作成されているユーザーは ec2-user です。ec2-user のユーザーパスワードは不要です。
接続時に先ほど作成した private key "twemily_private" を指定します。
上手いことできましたね!次は RDS を Terraform で構築してみようかなと思います。
EC2VPCTerraform