0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Terraform 入門から精通まで(AWS実体験)

Last updated at Posted at 2022-07-06

概要

今回、Terraformを使って、AWS VPCを構築して、VPCのpublic subnetに外部からアクセスできるec2を起動します。

システム構成図

截屏2022-07-07 0.01.44.png

やること

  • 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を起動成功
截屏2022-07-07 0.17.28.png
パブリック IPv4にアクセスして、成功
截屏2022-07-07 0.18.32.png
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

以上となります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?