Terraform AWS EC2編

  • EC2
  • VPC
  • Terraform
  • 準備するもの

    今回は、なるべく簡単な形で 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
    • AMI

    それぞれ準備していきましょう。

    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

    terraform-ec2-01

    Key-pair

    terraform-ec2-01

    Security Group

    terraform-ec2-01

    接続してみましょう

    問題なく resource が作成されているようです。

    実際に接続できるか確かめてみましょう。

    AmazonLinux2 で最初に作成されているユーザーは ec2-user です。ec2-user のユーザーパスワードは不要です。

    接続時に先ほど作成した private key "twemily_private" を指定します。

    terraform-ec2-01

    terraform-ec2-01

    上手いことできましたね!次は RDS を Terraform で構築してみようかなと思います。

  • EC2
  • VPC
  • Terraform