こつこつ環境をTerraformで育てる@AWS part1
思い立った
普段AWSを使ってシステムを提案したり作ったりしていますが、その際にあわせてTeraformをいじったりしています。
が、Terraformを始めたばっかりの時は「これどうやるんだ?」「ちょっといじりたいけど、サンプルが壮大だ・・・」などいろいろ思い悩んでいました。
今はいろんな人が入門記事を書いているので、既に出尽くした感はありますが、自分の整理を兼ねてTerraformでシステムを育てていく過程をAWSで書いてみようと思います。
まずはパート1です。
とりあえずEC2を作る
細かいことは置いておいて、とりあえずEC2とネットワークを作ります。
イメージはこんな感じ
鍵を作る
ローカルで公開鍵と秘密鍵を作っておきます。
ssh-keygen -t rsa -b 4096
Homeディレクトリの.ssh下にid_rsa
とid_rsa.pub
ができるので、作業ディレクトリに移しておきます。
Terraformでコーディング
つくります。Github
# terraform setting
terraform {
required_version = ">= 0.14"
required_providers {
aws = ">= 3.50.0"
}
backend "local" {
path = "terraform.tfstate"
}
}
provider "aws" {
region = "ap-northeast-1"
}
# network setting
## vpc
resource "aws_vpc" "this_vpc" {
cidr_block = "192.168.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "intro-terraform"
}
}
## internet gateway
resource "aws_internet_gateway" "this_igw" {
vpc_id = aws_vpc.this_vpc.id
tags = {
Name = "intro-terraform"
}
}
## subnet
resource "aws_subnet" "this_public_sub_a" {
vpc_id = aws_vpc.this_vpc.id
cidr_block = "192.168.0.0/24"
availability_zone = "ap-northeast-1a"
tags = {
Name = "intro-terraform-subnet-public-a"
}
}
resource "aws_subnet" "this_public_sub_z" {
vpc_id = aws_vpc.this_vpc.id
cidr_block = "192.168.1.0/24"
availability_zone = "ap-northeast-1c"
tags = {
Name = "intro-terraform-subnet-public-c"
}
}
## route table
resource "aws_route_table" "public" {
vpc_id = aws_vpc.this_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.this_igw.id
}
tags = {
Name = "intro-terraform-routetable-public"
}
}
### route table association
resource "aws_route_table_association" "this_public_a_rt" {
subnet_id = aws_subnet.this_public_sub_a.id
route_table_id = aws_route_table.public.id
}
resource "aws_route_table_association" "this_public_z_rt" {
subnet_id = aws_subnet.this_public_sub_z.id
route_table_id = aws_route_table.public.id
}
# security group
resource "aws_security_group" "this_public_sg" {
name = "intro-terraform-sg-public"
vpc_id = aws_vpc.this_vpc.id
tags = {
Name = "intro-terraform-sg-public"
}
}
## get my ip
data "http" "ifconfig" {
url = "http://ipv4.icanhazip.com/"
}
variable "allowed-myip" {
default = null
}
locals {
current-ip = chomp(data.http.ifconfig.body)
allowed-myip = (var.allowed-myip == null) ? "${local.current-ip}/32" : var.allowed-myip
}
## inbound
resource "aws_security_group_rule" "this_public_sg_in_rule_public" {
security_group_id = aws_security_group.this_public_sg.id
type = "ingress"
from_port = "22"
to_port = "22"
protocol = "TCP"
cidr_blocks = ["192.168.0.0/24", "192.168.1.0/24", local.allowed-myip]
}
## outbound
resource "aws_security_group_rule" "this_public_sg_out_rule_all" {
security_group_id = aws_security_group.this_public_sg.id
type = "egress"
cidr_blocks = ["0.0.0.0/0"]
from_port = 0
to_port = 0
protocol = "-1"
}
# EC2 setting
## key setting
resource "aws_key_pair" "this_key" {
key_name = "intro-terraform-keypair"
public_key = file("./id_rsa.pub")
}
resource "aws_instance" "this" {
ami = "ami-0b276ad63ba2d6009"
vpc_security_group_ids = [aws_security_group.this_public_sg.id]
subnet_id = aws_subnet.this_public_sub_a.id
key_name = aws_key_pair.this_key.id
instance_type = "t2.micro"
associate_public_ip_address = "true"
tags = {
Name = "intro-terraform-ec2-part1"
}
}
このコードで図の構成が出来上がります。
解説
準備
terraform {
required_version = ">= 0.14"
required_providers {
aws = ">= 3.50.0"
}
backend "local" {
path = "terraform.tfstate"
}
}
provider "aws" {
region = "ap-northeast-1"
}
実行するTerraformのバージョンを指定します。
最新のTerraformをインストールしておけば大丈夫です。
Network
# network setting
## vpc
resource "aws_vpc" "this_vpc" {
cidr_block = "192.168.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "intro-terraform"
}
}
## internet gateway
resource "aws_internet_gateway" "this_igw" {
vpc_id = aws_vpc.this_vpc.id
tags = {
Name = "intro-terraform"
}
}
## subnet
resource "aws_subnet" "this_public_sub_a" {
vpc_id = aws_vpc.this_vpc.id
cidr_block = "192.168.0.0/24"
availability_zone = "ap-northeast-1a"
tags = {
Name = "intro-terraform-subnet-public-a"
}
}
resource "aws_subnet" "this_public_sub_z" {
vpc_id = aws_vpc.this_vpc.id
cidr_block = "192.168.1.0/24"
availability_zone = "ap-northeast-1c"
tags = {
Name = "intro-terraform-subnet-public-c"
}
}
## route table
resource "aws_route_table" "public" {
vpc_id = aws_vpc.this_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.this_igw.id
}
tags = {
Name = "intro-terraform-routetable-public"
}
}
### route table association
resource "aws_route_table_association" "this_public_a_rt" {
subnet_id = aws_subnet.this_public_sub_a.id
route_table_id = aws_route_table.public.id
}
resource "aws_route_table_association" "this_public_z_rt" {
subnet_id = aws_subnet.this_public_sub_z.id
route_table_id = aws_route_table.public.id
}
ネットワーク周りで必要なリソースを組んでいきます。
まずは土台となるVPCをまず定義。
その上にサブネット、ルートテーブル、インターネットゲートウェイを乗せていきます。
ルートテーブルは定義した後に関連付けが必要なので、aws_route_table_association
を忘れずに。
Security Group
# security group
resource "aws_security_group" "this_public_sg" {
name = "intro-terraform-sg-public"
vpc_id = aws_vpc.this_vpc.id
tags = {
Name = "intro-terraform-sg-public"
}
}
## get my ip
data "http" "ifconfig" {
url = "http://ipv4.icanhazip.com/"
}
variable "allowed-myip" {
default = null
}
locals {
current-ip = chomp(data.http.ifconfig.body)
allowed-myip = (var.allowed-myip == null) ? "${local.current-ip}/32" : var.allowed-myip
}
## inbound
resource "aws_security_group_rule" "this_public_sg_in_rule_public" {
security_group_id = aws_security_group.this_public_sg.id
type = "ingress"
from_port = "22"
to_port = "22"
protocol = "TCP"
cidr_blocks = ["192.168.0.0/24", "192.168.1.0/24", local.allowed-myip]
}
## outbound
resource "aws_security_group_rule" "this_public_sg_out_rule_all" {
security_group_id = aws_security_group.this_public_sg.id
type = "egress"
cidr_blocks = ["0.0.0.0/0"]
from_port = 0
to_port = 0
protocol = "-1"
}
EC2に割り当てるSecurity Groupを定義します。
Security Groupの枠を作って、その中にIN/OUTのルールを流し込むイメージです。
このスクリプトでそのままSSH接続できるようにするために、get my ipの箇所で実行端末のGlobal IPを取得しています。
http://ipv4.icanhazip.com/ のサービスにアクセスすると自分のIPアドレスが返ってくるので、それを変数に入れてInboundルールにはめ込んでいます。
他のルールは、Inboundは同じサブネットのSSH通信を許可、Outboundは全開けです。
EC2
# EC2 setting
## key setting
resource "aws_key_pair" "this_key" {
key_name = "intro-terraform-keypair"
public_key = file("./id_rsa.pub")
}
resource "aws_instance" "this" {
ami = "ami-0b276ad63ba2d6009"
vpc_security_group_ids = [aws_security_group.this_public_sg.id]
subnet_id = aws_subnet.this_public_sub_a.id
key_name = aws_key_pair.this_key.id
instance_type = "t2.micro"
associate_public_ip_address = "true"
tags = {
Name = "intro-terraform-ec2-part1"
}
}
事前に作っておいたKey Pairのファイルを指定して、EC2にセットする鍵として定義します。
EC2に対しては、前段に作ったサブネット、セキュリティグループを定義して、Global IPの割り当てを有効にして起動する設定にしています。
終わりに
まずはとりあえず作ってみる編です。
ここから徐々に育てていきます。
Discussion