概要
今回、Terraformを使って、AWS VPCを構築して、VPCのpublic subnetに外部からアクセスできるec2を起動します。
システム構成図
やること
- VPCを構築
- Internet Gatewayを作成
- Route Tableを作成
- サブネットを作成
- Route Tableにサブネットを関連付け
- port22,443,80を許可Security Groupを作成
- network interfaceを作成
- 作成したnetwork interfaceにElastic IPを関連付け
- EC2を作成して、ec2にApacheをインストールして、起動する
前提条件
・MAC
・VS code
・リソースを作成するためのAWSの権限設定をもつiamユーザーのアクセスキー
・Terraformをインストール済み
・EC2のキーペアを作成済み
参照DOC
ローカルip確認
VPCを構築
## 1.create vpc
resource "aws_vpc" "dev-vpc" {
cidr_block = "10.0.0.0/16"
}
Internet Gatewayを作成
## 2.create Internet Gateway
resource "aws_internet_gateway" "dev-igw" {
vpc_id = aws_vpc.dev-vpc.id
tags = {
Name = "dev-igw"
}
}
Route Tableを作成
# 3.create Custom Route Table
resource "aws_route_table" "dev-route-table" {
vpc_id = aws_vpc.dev-vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.dev-igw.id
}
route {
ipv6_cidr_block = "::/0"
gateway_id = aws_internet_gateway.dev-igw.id
}
tags = {
Name = "dev-route-table"
}
}
サブネットを作成
# 4.create a subnet
resource "aws_subnet" "dev-subnet" {
vpc_id = aws_vpc.dev-vpc.id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-northeast-1c"
tags = {
Name = "dev-subnet"
}
}
Route Tableにサブネットを関連付け
# 5.associate subnet with Route Table
resource "aws_route_table_association" "dev-route-table-association" {
subnet_id = aws_subnet.dev-subnet.id
route_table_id = aws_route_table.dev-route-table.id
}
port22,443,80を許可Security Groupを作成
ローカルIPだけEC2のport22,443,80にアクセス許可します。
xx.xx.xx.xx/32はローカルipです。
# 6.create Security Group to allow prot 22,80,443
resource "aws_security_group" "allow_web" {
name = "allow_web_traffic"
description = "Allow web inbound traffic"
vpc_id = aws_vpc.dev-vpc.id
ingress {
description = "HTTPS"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["xx.xx.xx.xx/32"]
}
ingress {
description = "HTTP"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["xx.xx.xx.xx/32"]
}
ingress {
description = "SSH"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["xx.xx.xx.xx/32"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "allow_web"
}
}
network interfaceを作成
# 7.create a network interface with an ip in the subnet that created in step 4
resource "aws_network_interface" "dev-network-interface" {
subnet_id = aws_subnet.dev-subnet.id
private_ips = ["10.0.1.50"]
security_groups = [aws_security_group.allow_web.id]
}
作成したnetwork interfaceにElastic IPを関連付け
# 8.Assign an elastic IP to the network interface created in step7
resource "aws_eip" "one" {
vpc = true
network_interface = aws_network_interface.dev-network-interface.id
associate_with_private_ip = "10.0.1.50"
depends_on = [aws_internet_gateway.dev-igw]
}
EC2を作成して、ec2にApacheをインストールして、起動する
# 9.create Ec2 server and install/start apache
resource "aws_instance" "dev-web-server" {
ami = "ami-0b7546e839d7ace12"
instance_type = "t2.micro"
availability_zone = aws_subnet.dev-subnet.availability_zone
key_name = "terraform-key"
network_interface {
device_index = 0
network_interface_id = aws_network_interface.dev-network-interface.id
}
user_data = <<-EOF
#!/usr/bin/env bash
su ec2-user
sudo yum install httpd -y
sudo service httpd start
sudo su -c "cat > /var/www/html/index.html <<EOL
<html>
<head>
<meta charset="utf-8">
<title> call to Arms</title>
<style type="text/css"></style>
</head>
<body>
<img src="https://media.giphy.com/media/rgTB82z9P63fTGhxQo/giphy.gif" height="100%">
</body>
</html>
EOL"
EOF
tags = {
Name = "dev-web-server"
}
}
main.tfに全てのコード
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}
# Configure the AWS Provider
provider "aws" {
region = "ap-northeast-1"
access_key = "xxxxxxxxxxxx"
secret_key = "xxxxxxxxxxxxxxx"
}
# 1.create vpc
resource "aws_vpc" "dev-vpc" {
cidr_block = "10.0.0.0/16"
}
# 2.create Internet Gateway
resource "aws_internet_gateway" "dev-igw" {
vpc_id = aws_vpc.dev-vpc.id
tags = {
Name = "dev-igw"
}
}
# 3.create Custom Route Table
resource "aws_route_table" "dev-route-table" {
vpc_id = aws_vpc.dev-vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.dev-igw.id
}
route {
ipv6_cidr_block = "::/0"
gateway_id = aws_internet_gateway.dev-igw.id
}
tags = {
Name = "dev-route-table"
}
}
# 4.create a subnet
resource "aws_subnet" "dev-subnet" {
vpc_id = aws_vpc.dev-vpc.id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-northeast-1c"
tags = {
Name = "dev-subnet"
}
}
# 5.associate subnet with Route Table
resource "aws_route_table_association" "dev-route-table-association" {
subnet_id = aws_subnet.dev-subnet.id
route_table_id = aws_route_table.dev-route-table.id
}
# 6.create Security Group to allow prot 22,80,443
resource "aws_security_group" "allow_web" {
name = "allow_web_traffic"
description = "Allow web inbound traffic"
vpc_id = aws_vpc.dev-vpc.id
ingress {
description = "HTTPS"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["xx.xx.xx.xx/32"]
}
ingress {
description = "HTTP"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["xx.xx.xx.xx/32"]
}
ingress {
description = "SSH"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["xx.xx.xx.xx/32"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "allow_web"
}
}
# 7.create a network interface with an ip in the subnet that created in step 4
resource "aws_network_interface" "dev-network-interface" {
subnet_id = aws_subnet.dev-subnet.id
private_ips = ["10.0.1.50"]
security_groups = [aws_security_group.allow_web.id]
}
# 8.Assign an elastic IP to the network interface created in step7
resource "aws_eip" "one" {
vpc = true
network_interface = aws_network_interface.dev-network-interface.id
associate_with_private_ip = "10.0.1.50"
depends_on = [aws_internet_gateway.dev-igw]
}
# 9.create Ec2 server and install/start apache
resource "aws_instance" "dev-web-server" {
ami = "ami-0b7546e839d7ace12"
instance_type = "t2.micro"
availability_zone = aws_subnet.dev-subnet.availability_zone
key_name = "terraform-key"
network_interface {
device_index = 0
network_interface_id = aws_network_interface.dev-network-interface.id
}
user_data = <<-EOF
#!/usr/bin/env bash
su ec2-user
sudo yum install httpd -y
sudo service httpd start
sudo su -c "cat > /var/www/html/index.html <<EOL
<html>
<head>
<meta charset="utf-8">
<title> call to Arms</title>
<style type="text/css"></style>
</head>
<body>
<img src="https://media.giphy.com/media/rgTB82z9P63fTGhxQo/giphy.gif" height="100%">
</body>
</html>
EOL"
EOF
tags = {
Name = "dev-web-server"
}
}
Terraformを実行
terraform apply
結果を確認
Ec2を起動成功
パブリック IPv4にアクセスして、成功
SSH接続テスト
% ssh -i "terraform-key.pem" ec2-user@35.79.171.109
The authenticity of host '35.79.171.109 (35.79.171.109)' can't be established.
ED25519 key fingerprint is SHA256:1pBw7U6RD6sluMPNs3Lk4gzHRooDIGtuVq7Ld5P1mEE.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '35.79.171.109' (ED25519) to the list of known hosts.
Last login: Wed Jul 6 11:06:32 2022
__| __|_ )
_| ( / Amazon Linux 2 AMI
___|\___|___|
https://aws.amazon.com/amazon-linux-2/
-bash: warning: setlocale: LC_CTYPE: cannot change locale (UTF-8): No such file or directory
[ec2-user@ip-10-0-1-50 ~]$
無事にローカルからec2にsshしました。
片付ける
以下のコマンドで今回作成したインフラを削除します。
terraform destroy --auto-approve
以上となります。