AWS

【Terraform入門】AWSのVPCとEC2を構築してみる

【Terraform入門】AWSのVPCとEC2を構築してみる
エンジニア
TerraformでAWS環境をかんたんに構築できると聞きました。TerraformでVPCとEC2を作成してみたいです。

Terraformを使うとインフラ環境を数分で作成することができます。

本記事ではTerraformでAWSのVPCとEC2 (Amazon Linux 2) を構築する手順をご説明します。

なお、Terraformを実行するクライアントPCはWindows10 (64bit) を使用します。

 

本記事の内容

  • Terraformの概要
  • Terraform (v1.1.9) でVPCとEC2 (Amazon Linux 2) を構築する
  • 作成したVPCとEC2をTerraformで削除する

Terraformとは

Terraformはインフラ環境をコードで構築できるオープンソースのツール。AWS、Azuru、GCPなどのクラウドプラットフォームに対応しています。

インフラをコードで定義することを『IaC』と呼びますが、TerraformはIaCツールの1つになります。

IaC (Infrastructure as Code) とは

  • コードでインフラの構築や変更を自動化できる
  • Terraformの他に、AWSのCloudFormationやRedHatのAnsibleなどが有名
  • インフラ構築の手順書がいらなくなり、作業効率や生産性がアップする
  • プログラミング経験がなくても、少ない学習コストでIaCのコードを書けるようになる

 

TerraformによるVPCとEC2の構築イメージ

TerraformによるVPCとEC2の構築イメージ

今回のTerraformによるVPCとEC2の構築イメージは以下のとおり。

  • 東京リージョンのAZ 1aにパブリックサブネットを構成したVPCを作成
  • EC2をパブリックサブネットに作成
  • クライアントPCからEC2にSSH接続

 

Terraformを使用する前の事前準備

事前準備

ではさっそく作業をスタートしていきましょう。

Terraformを使用する前の事前準備として以下を行います。

  • IAMユーザーのアクセスキー作成
  • AWS CLI インストール
  • AWS CLI 認証情報の設定
  • Terraformインストール

 

IAMユーザーのアクセスキー作成

Terraformを使用するには、IAMユーザーとアクセスキーが必要になります。

本記事では作成済みのIAMユーザー(テスト目的のためAdministratorAccessを付与)を使用し、アクセスキーのみ新規作成することとします。

マネジメントコンソールにログイン -> IAM画面 -> [ユーザー] -> [対象のIAMユーザー] をクリック -> [認証情報] タブ -> [アクセスキーの作成] をクリック。

[アクセスキー ID] と [シークレットアクセスキー] の2つの認証情報をテキストエディタなどにコピペし、 [閉じる] をクリックします。

念のため [.csvファイルのダウンロード] をクリックし、認証情報のファイルをダウンロードしておきましょう。

あとから [アクセスキー ID] と [シークレットアクセスキー] を確認できます。

 

AWS CLI インストール

以下から最新版のAWS CLI インストーラ(Windows 用)をダウンロードし、.msiファイルを実行してインストールします。

【AWS公式】Windows AWS CLI インストーラ (64 ビット)

(参考)AWS公式のAWS CLIインストール手順

AWS CLI の最新バージョンをインストールまたは更新する

 

インストール完了後、デスクトップの左下にあるWindowsのアイコンを右クリック -> [ファイル名を指定して実行] をクリック -> cmdを入力しEnterキー押下でコマンドプロンプトを起動。

コマンドプロンプトでaws --versionを実行し、AWS CLIが使用できることを確認します。


C:\Users\USERNAME> aws --version
aws-cli/2.6.3 Python/3.9.11 Windows/10 exe/AMD64 prompt/off

 

AWS CLI 認証情報の設定

コマンドプロンプトでaws configureを実行し、AWS CLI 認証情報を設定します。


C:\Users\USERNAME> aws configure
AWS Access Key ID [None]: 上記で作成した [アクセスキー ID]
AWS Secret Access Key [None]: 上記で作成した [シークレットアクセスキー]
Default region name [None]: ap-northeast-1
Default output format [None]: 何も入力せずにEnterキーを押下

 

続いてaws configure listを実行し、AWS CLI 認証情報が設定されたことを確認します。


C:\Users\USERNAME> aws configure list
 Name Value Type Location
---- ----- ---- --------
profile <not set> None None
access_key ****************G3Mw shared-credentials-file
secret_key ****************hL6A shared-credentials-file
region ap-northeast-1 config-file ~/.aws/config

 

上記で設定した認証情報は、以下のテキストファイルに保存される。

C:\Users\USERNAME\.aws\config
C:\Users\USERNAME\.aws\credentials

 

ためしにaws iam get-userを実行してみましょう。自分のIAMユーザー情報が出力されれば、AWS CLI 認証情報が正しく設定されていることになります。


C:\Users\USERNAME> aws iam get-user
{
    "User": {
        "Path": "/",
        "UserName": "USERNAME",
        "UserId": "xxxxxxxxxxxxxxxxx",
        "Arn": "arn:aws:iam::123456789012:user/USERNAME",
        "CreateDate": "2022-04-08T22:40:32+00:00",
        "PasswordLastUsed": "2022-05-08T01:18:23+00:00"
    }
}

 

Terraformインストール

以下にアクセスし、[Windows] -> [Amd64] をクリックしてファイルをダウンロードします。

Terraform公式ダウンロードサイト

 

ダウンロードしたファイルterraform_x.x.x_windows_amd64.zip(x.x.xはバージョン名)を解凍しterraform.exeを取り出します。

terraform.exeC:\Windowsに移動します。(「~管理者の権限が必要です」は「続行」をクリック)

  • Terraformはこのexeファイルを実行するだけで使用できる
  • terraform.exeを使用するには、PATHが通っているフォルダに配置する必要がある
  • C:\WindowsはデフォルトでPATHが通っている

 

次にコマンドプロンプトでterraform -vを実行。以下のとおりバージョン情報が表示されればインストール成功です。


C:\Users\USERNAME> terraform -v
Terraform v1.1.9
on windows_amd64

 

Terraformのtfファイル作成

tfファイル作成

Terraformを実行する際に必要なtfファイルを作成していきます。

 

tfファイルはHCLで記述する

Terraformは拡張子が.tfのファイルにインフラ構成を定義し、それを実行するだけでVPCやEC2などが数分で作成できます。

tfファイルはHCL (HashiCorp Configuration Language) と呼ばれる、HashiCorp社開発の独自記法でコードを書く必要があります。

HCLの構文自体はシンプルなので、何回かtfファイルを作成している内に書き方が分かってきます。

以下はVPCやEC2などの「リソース」を作成するときの基本的な構文です。


resource "リソースの種類" "リソース名" {
    設定項目1  =  値1
    設定項目2  =  値2
    設定項目3  =  値3
}

 

  • "リソースの種類" や "設定項目" はTerraformで定義されている名前にする必要がある
  • "リソース名" は自分で任意の名前を設定できる

 

作成するtfファイルについて

tfファイルの名前は自由に設定できます。

今回はtfファイルの一般的な命名パターンを使用し、以下のとおりに5つのtfファイルを作成します。

ファイル名 ファイルの定義内容
main.tf "AWS" などTerraformを実行する環境(プロバイダーと呼ぶ)を定義
variables.tf Terraformで使用する変数を定義(変数は他のtfファイルから${var.変数名}やvar.変数名で参照できる)
vpc.tf VPCを作成するためのリソースを定義
ec2.tf EC2を作成するためのリソースを定義
output.tf 作成したEC2のパブリックIPアドレスを出力する設定を定義

 

クライアントPCに作業用フォルダと空のtfファイルを作成

今回は1つのフォルダにまとめてtfファイルを作成します。

コマンドプロンプトからmkdirで作業用フォルダC:\terraform_handsonを作成した後、cdでそのフォルダに移動します。


C:\Users\USERNAME> mkdir C:\terraform_handson
C:\Users\USERNAME> cd C:\terraform_handson
C:\terraform_handson>

 

次のステップでtfファイルにコードを記述するので、新規テキストファイルとして空のtfファイルを作成しておきます。

コマンドプロンプトからtypeコマンドですばやくファイルを作成できます。(コピペしやすいようにプロンプトC:\terraform_handson>は書いていません)


type nul > main.tf
type nul > variables.tf
type nul > vpc.tf
type nul > ec2.tf
type nul > output.tf

 

tfファイルにコードを書く

次にエクスプローラーで作業用フォルダC:\terraform_handsonを開きます。

上記で作成した5つのtfファイルをテキストエディタなどで開き、以下のコード内容をそれぞれコピペします。

main.tf

# ---------------------------
# プロバイダ設定
# ---------------------------
# AWS
provider "aws" {
  region     = "ap-northeast-1"
}

# 自分のパブリックIP取得用
provider "http" {}

 

今回作成するEC2のセキュリティグループは、自分のパブリックIPのみ22/tcpをインバウンド許可します。

provider "http" {}は「自分のパブリックIP」を取得するために必要になる定義です。

 

variables.tf

# ---------------------------
# 変数設定
# ---------------------------
variable "az_a" {
  default     = "ap-northeast-1a"
}

variable "access_key" {
  default     = "上記で作成したアクセスキー"
}

variable "secret_key" {
  default     = "上記で作成したシークレットキー"
}

 

variables.tfは上記コードをコピペした後、[access_key] と [secret_key] を自分が作成したアクセスキーとシークレットキーの値に置き換えてください。

 

vpc.tf

# ---------------------------
# VPC
# ---------------------------
resource "aws_vpc" "handson_vpc"{
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true   # DNSホスト名を有効化
  tags = {
    Name = "terraform-handson-vpc"
  }
}

# ---------------------------
# Subnet
# ---------------------------
resource "aws_subnet" "handson_public_1a_sn" {
  vpc_id            = aws_vpc.handson_vpc.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "${var.az_a}"

  tags = {
    Name = "terraform-handson-public-1a-sn"
  }
}

# ---------------------------
# Internet Gateway
# ---------------------------
resource "aws_internet_gateway" "handson_igw" {
  vpc_id            = aws_vpc.handson_vpc.id
  tags = {
    Name = "terraform-handson-igw"
  }
}

# ---------------------------
# Route table
# ---------------------------
# Route table作成
resource "aws_route_table" "handson_public_rt" {
  vpc_id            = aws_vpc.handson_vpc.id
  route {
    cidr_block      = "0.0.0.0/0"
    gateway_id      = aws_internet_gateway.handson_igw.id
  }
  tags = {
    Name = "terraform-handson-public-rt"
  }
}

# SubnetとRoute tableの関連付け
resource "aws_route_table_association" "handson_public_rt_associate" {
  subnet_id      = aws_subnet.handson_public_1a_sn.id
  route_table_id = aws_route_table.handson_public_rt.id
}

# ---------------------------
# Security Group
# ---------------------------
# 自分のパブリックIP取得
data "http" "ifconfig" {
  url = "http://ipv4.icanhazip.com/"
}

variable "allowed_cidr" {
  default = null
}

locals {
  myip          = chomp(data.http.ifconfig.body)
  allowed_cidr  = (var.allowed_cidr == null) ? "${local.myip}/32" : var.allowed_cidr
}

# Security Group作成
resource "aws_security_group" "handson_ec2_sg" {
  name              = "terraform-handson-ec2-sg"
  description       = "For EC2 Linux"
  vpc_id            = aws_vpc.handson_vpc.id
  tags = {
    Name = "terraform-handson-ec2-sg"
  }

  # インバウンドルール
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = [local.allowed_cidr]
  }

  # アウトバウンドルール
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

 

ec2.tf

# ---------------------------
# EC2 Key pair
# ---------------------------
variable "key_name" {
  default = "terraform-handson-keypair"
}

# 秘密鍵のアルゴリズム設定
resource "tls_private_key" "handson_private_key" {
  algorithm = "RSA"
  rsa_bits  = 2048
}

# クライアントPCにKey pair(秘密鍵と公開鍵)を作成
# - Windowsの場合はフォルダを"\\"で区切る(エスケープする必要がある)
# - [terraform apply] 実行後はクライアントPCの公開鍵は自動削除される
locals {
  public_key_file  = "C:\\terraform_handson\\${var.key_name}.id_rsa.pub"
  private_key_file = "C:\\terraform_handson\\${var.key_name}.id_rsa"
}

resource "local_file" "handson_private_key_pem" {
  filename = "${local.private_key_file}"
  content  = "${tls_private_key.handson_private_key.private_key_pem}"
}

# 上記で作成した公開鍵をAWSのKey pairにインポート
resource "aws_key_pair" "handson_keypair" {
  key_name   = "${var.key_name}"
  public_key = "${tls_private_key.handson_private_key.public_key_openssh}"
}

# ---------------------------
# EC2
# ---------------------------
# Amazon Linux 2 の最新版AMIを取得
data "aws_ssm_parameter" "amzn2_latest_ami" {
  name = "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
}

# EC2作成
resource "aws_instance" "handson_ec2"{
  ami                         = data.aws_ssm_parameter.amzn2_latest_ami.value
  instance_type               = "t2.micro"
  availability_zone           = "${var.az_a}"
  vpc_security_group_ids      = [aws_security_group.handson_ec2_sg.id]
  subnet_id                   = aws_subnet.handson_public_1a_sn.id
  associate_public_ip_address = "true"
  key_name                    = "${var.key_name}"
  tags = {
    Name = "terraform-handson-ec2"
  }
}

 

output.tf

# 作成したEC2のパブリックIPアドレスを出力
output "ec2_global_ips" {
  value = "${aws_instance.handson_ec2.*.public_ip}"
}

 

TerraformでVPCとEC2を構築

TerraformでVPCとEC2を構築

tfファイルが作成できたので、実際にTerraformでVPCとEC2を構築していきます。

 

terraform initでワークスペース初期化

まずterraform initを実行し、ワークスペース(tfファイルを格納しているフォルダ)を初期化します。

ワークスペース内のtfファイルが読み込まれ、必要なpluginがインターネットからワークスペースにダウンロードされます。


C:\terraform_handson> terraform init

Initializing the backend...
略
Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

 

Terraform has been successfully initialized!が出力されればOK。

 

terraform validateでtfファイルの構文チェック

terraform validateを実行するとtfファイルの構文をチェックをしてくれます。(本コマンドは必須ではない)


C:\terraform_handson> terraform validate

 

tfファイルの構文が問題なければSuccess! The configuration is valid.が出力されます。

 

terraform planで実行計画を作成

terraform planを実行すると、どういったリソースが作成(変更)されるかを事前に確認できます。(本コマンドは必須ではない)


C:\terraform_handson> terraform plan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:

略

 

[+] がついているリソースは、新規で作成されることを意味します。

 

terraform applyでリソースを作成

いよいよリソースの作成です。

terraform applyを実行し、Enter a value:が表示されたあとにyesを入力してEnterキーを押下すると、リソースの作成が開始されます。


C:\terraform_handson> terraform apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
+ create
略
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を入力してEnterキーを押下

 

作成内容が出力されるので1,2分ほど待ち、Apply complete! Resources: 10 added, 0 changed, 0 destroyed.が出力されれば作成完了です。

今回は作成したEC2にSSH接続するので、以下のようにEC2のパブリックIPアドレスも出力するようにしました。


Outputs:

ec2_global_ips = [
"xxx.xxx.xxx.xxx",
]

 

terraform showで作成したリソースを確認

terraform showを実行するとterraform が作成したオブジェクトの内容が出力されます。


C:\terraform_handson> terraform show
略

 

しかし、この出力結果だけでは分からづらいので、マネジメントコンソールからVPCとEC2が作成されたことを確認してみましょう。

 

Terraformで作成したEC2にSSH接続する

マネジメントコンソールから、EC2の [ステータスチェック] が [2/2 のチェックに合格しました] になったことを確認したあと、EC2のパブリックIPアドレスにSSH接続してみましょう。

パブリックIPアドレスは以下のいずれかで確認できます。

  • terraform applyterraform show実行後にOutputsとして出力される
  • マネジメントコンソールの対象EC2における [詳細] タブ -> [パブリック IPv4 アドレス]

 

SSH接続時に使用する秘密鍵は、terraform applyで作成されたC:\terraform_handson\terraform-handson-keypair.id_rsaを使用します。

もし、EC2へのSSH接続方法がわからない場合は、当ブログの以下リンク先を参考にしてください。

【AWS】EC2でAmazon Linux 2を構築しSSH接続してみよう(ステップ3:EC2にSSH接続する)

 

以下のようにEC2に接続できればOKです。

EC2接続

 

Terraformで作成したリソースを更新

Terraformで作成したリソースの更新として、EC2のNameタグを変更してみます。

ec2.tfをテキストエディタで開き、ファイル末尾のコードを以下のとおり変更しファイルを保存します。


# 修正前
  tags = {
    Name = "terraform-handson-ec2"
  }

# 修正後
  tags = {
    Name = "update-terraform-handson-ec2"
  }

 

次にterraform planで変更内容を事前に確認できます。


C:\terraform_handson> terraform plan
略
  # aws_instance.handson_ec2 will be updated in-place
  ~ resource "aws_instance" "handson_ec2" {
        id                                   = "i-xxxxxxxxxxxx"
      ~ tags                                 = {
          ~ "Name" = "terraform-handson-ec2" -> "update-terraform-handson-ec2"
        }
      ~ tags_all                             = {
          ~ "Name" = "terraform-handson-ec2" -> "update-terraform-handson-ec2"
        }
略

 

この状態でterraform applyを実行し、Enter a value:が表示されたあとにyesを入力してEnterキーを押下すると、リソースの更新が開始されます。


C:\terraform_handson> terraform apply
略
Plan: 0 to add, 1 to change, 0 to destroy.

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を入力してEnterキーを押下

 

数秒で処理が完了し、Apply complete! Resources: 0 added, 1 changed, 0 destroyed.が出力されれば更新完了です。

マネジメントコンソールからEC2のNameタグが更新されたことを確認しましょう。

 

Terraformで作成したVPCとEC2を削除

Terraformで作成したVPCとEC2を削除

最後の作業として、今回Terraformで作成したリソースを全て削除しましょう。

 

terraform plan -destroyで削除対象のリソースを確認

terraform destroyで作成したAWSリソースを全て削除できるのですが、その前にterraform plan -destroyで何が削除されるかを確認してみましょう。(本コマンドは必須ではない)


C:\terraform_handson> terraform plan -destroy
略

 

[-] がついているリソースは削除されることを意味します。

 

terraform destroyで作成したリソースを削除

それでは作成したリソースを全て削除してみましょう。

terraform destroyを実行し、Enter a value:が表示されたあとにyesを入力してEnterキーを押下すると、リソースの削除が開始されます。


C:\terraform_handson> terraform destroy
略
Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes     # yesを入力してEnterキーを押下

local_file.private_key_pem: Destroying... [id=xxxxxxxxxxxxxxxxxxxxxxxx]
略
Destroy complete! Resources: 10 destroyed.

 

Destroy complete! Resources: 10 destroyed.が出力されれば削除完了。

マネジメントコンソールから以下を確認します。

  • VPCが削除されたこと
  • EC2の [インスタンスの状態] が [終了済み] になったこと

 

クライアントPCに作成した秘密鍵C:\terraform_handson\terraform-handson-keypair.id_rsaも削除されます。

 

リソース削除後は、terraform showを実行しても何も出力されずにプロンプトが返ってきます。


C:\terraform_handson> terraform show
C:\terraform_handson>

 

TerraformでVPCとEC2を構築してみる:まとめ

TerraformでVPCとEC2を構築してみました。

事前準備さえしてしまえば、次からはtfファイルを用意するだけで、簡単にAWS環境を設定できるのは素晴らしいですよね。

また、Terraformはコードの書き方を学習すれば、AzureやGCPにも応用できる点がCloudFormationにはないメリットだと感じました。

Terraformはとても簡単にリソースを作成できる反面、1つのコマンド(terraform destroy) で作成したリソースを削除できてしまう点には十分に注意しましょう。

 

本記事がTerraformを学習する人の参考になれば幸いです。

-AWS

© 2022 ふにノート