BFF

2021年12月19日

【Terraform】EC2/VPC作成+SSH接続(Ubuntu)

TerraformでEC2・VPC作成後、SSH接続(Ubuntu 20.04)

今回も作業効率化のメモです。
TerraformでSSH接続できるEC2・VPC作成します。
AMIは「Ubuntu 20.04」になります。
リージョンは、ap-northeast-3, アジアパシフィック (大阪)です。

環境

  • macOS Monterey 12.1 チップ Apple M1
  • Terraform v1.0.9
  • aws-cli/2.4.6 Python/3.9.9 Darwin/21.2.0 source/arm64 prompt/off

事前準備

AWS CLI インストールと、aws configureの設定は済ませておいてください。
ここでは解説を省かせていただきます。
$ brew install awscli
$ aws configure
AWS Access Key ID [None]: アクセスキー ID
AWS Secret Access Key [None]: シークレットアクセスキー
Default region name [None]: ap-northeast-3
Default output format [None]: json

Terraformをインストール

$ brew install terraform

秘密鍵・公開鍵を作成

SSHキーの名前は「terraform_example」としていますが、適宜変更してください。
$ ssh-keygen -t rsa -f terraform_example -N ''

各設定ファイル(*.tf)作成

<参考サイト>

参考サイトとの相違点は、Amazon Linux 2ではなくUbuntu 20.04である点と、
リージョンがap-northeast-3(大阪)である点、
SSHキーの名前が「terraform_example」という点です。
構築したいAMIの情報について
AMI(今回はUbuntu 20.04)の情報が必要になります。
入手する方法はいくつかありますが、リージョンやタイミングにもよるので、下記の参考サイトなどをご確認ください。

<参考サイト>

サンプルコード

provider.tf

# ====================
#
# Provider
#
# ====================
provider "aws" {
  profile = "default"
  region = "ap-northeast-3"
}

ec2.tf

# ====================
#
# AMI
#
# ====================
data "aws_ami" "terraform_example" {
  most_recent = true
  owners = ["099720109477"]

  filter {
    name = "architecture"
    values = ["x86_64"]
  }

  filter {
    name = "root-device-type"
    values = ["ebs"]
  }

  filter {
    name = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }

  filter {
    name = "virtualization-type"
    values = ["hvm"]
  }

  filter {
    name = "block-device-mapping.volume-type"
    values = ["gp2"]
  }

  filter {
    name = "state"
    values = ["available"]
  }
}

# ====================
#
# EC2 Instance
#
# ====================
resource "aws_instance" "terraform_example" {
  ami = data.aws_ami.terraform_example.image_id
  vpc_security_group_ids = [aws_security_group.terraform_example.id]
  subnet_id = aws_subnet.terraform_example.id
  key_name = aws_key_pair.terraform_example.id
  instance_type = "t2.micro"

  tags = {
    Name = "terraform_example"
  }
}

# ====================
#
# Elastic IP
#
# ====================
resource "aws_eip" "terraform_example" {
  instance = aws_instance.terraform_example.id
  vpc = true
}

# ====================
#
# Key Pair
#
# ====================
resource "aws_key_pair" "terraform_example" {
  key_name = "terraform_example"
  public_key = file("./terraform_example.pub")
}

vpc.tf

# ====================
#
# VPC
#
# ====================
resource "aws_vpc" "terraform_example" {
  cidr_block = "10.0.0.0/16"
  enable_dns_support = true
  enable_dns_hostnames = true

  tags = {
    Name = "terraform_example"
  }
}

# ====================
#
# Subnet
#
# ====================
resource "aws_subnet" "terraform_example" {
  cidr_block = "10.0.1.0/24"
  availability_zone = "ap-northeast-3a"
  vpc_id = aws_vpc.terraform_example.id

  map_public_ip_on_launch = true

  tags = {
    Name = "terraform_example"
  }
}

# ====================
#
# Internet Gateway
#
# ====================
resource "aws_internet_gateway" "terraform_example" {
  vpc_id = aws_vpc.terraform_example.id

  tags = {
    Name = "terraform_example"
  }
}

# ====================
#
# Route Table
#
# ====================
resource "aws_route_table" "terraform_example" {
  vpc_id = aws_vpc.terraform_example.id

  tags = {
    Name = "terraform_example"
  }
}

resource "aws_route" "terraform_example" {
  gateway_id = aws_internet_gateway.terraform_example.id
  route_table_id = aws_route_table.terraform_example.id
  destination_cidr_block = "0.0.0.0/0"
}

resource "aws_route_table_association" "terraform_example" {
  subnet_id = aws_subnet.terraform_example.id
  route_table_id = aws_route_table.terraform_example.id
}

# ====================
#
# Security Group
#
# ====================
resource "aws_security_group" "terraform_example" {
  vpc_id = aws_vpc.terraform_example.id
  name = "terraform_example"

  tags = {
    Name = "terraform_example"
  }
}

resource "aws_security_group_rule" "in_ssh" {
  security_group_id = aws_security_group.terraform_example.id
  type = "ingress"
  cidr_blocks = ["0.0.0.0/0"]
  from_port = 22
  to_port = 22
  protocol = "tcp"
}

resource "aws_security_group_rule" "in_icmp" {
  security_group_id = aws_security_group.terraform_example.id
  type = "ingress"
  cidr_blocks = ["0.0.0.0/0"]
  from_port = -1
  to_port = -1
  protocol = "icmp"
}

resource "aws_security_group_rule" "out_all" {
  security_group_id = aws_security_group.terraform_example.id
  type = "egress"
  cidr_blocks = ["0.0.0.0/0"]
  from_port = 0
  to_port = 0
  protocol = "-1"
}

terraform.output.tf

# ====================
#
# Output
#
# ====================
output "public_ip" {
  value = aws_eip.terraform_example.public_ip
}

リソース作成

作業用ディレクトリを初期化(※必須)

$ terraform init

各設定ファイルのフォーマット

$ terraform fmt

実行計画の作成

$ terraform plan

リソースの作成・変更の実行(※必須)

$ terraform apply

途中で下記の質問が出てくるので、yesと入力してEnter。

Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.

Enter a value: yes

現在の状況確認

$ terraform show

リソースの作成・変更の実行結果

terraform applyを実行後、AWSにリソースが作成されます。

最後にElastic IPのパブリックIPが表示されます。
Apply complete! Resources: 13 added, 0 changed, 0 destroyed.
Outputs:

public_ip = "13.208.78.235"

pingコマンドの確認

$ ping 13.208.78.235

ssh接続の確認

参考サイトはAmazon Linux 2のため、ユーザー名が「ec2-user」ですが、今回はUbuntuなので、ユーザー名は「ubuntu」になります。
$ ssh -i ./terraform_example ubuntu@13.208.78.235
無事、AWS EC2のubuntuにログインできれば成功です。

管理インフラストラクチャの削除(後片付け)

最後は後片付けをします。
$ terraform destroy
今回は以上となります。
LINEで送る
Pocket

label

Written by
isaka

バックエンドエンジニア

CONTACT

お問い合わせ、ご依頼などは下記電話番号かメールアドレスまでご連絡ください。
※内容により回答までお時間をいただく場合がございます、予めご了承ください。

tel. 06-6534-9333

10:00-19:00(※土日祝を除く)