TerraformでAWS環境構築

最近、災害復旧（Disaster Recovery: ディザスタリカバリ）の準備の一環として、AWSインスタンスを迅速に構築する方法について考えています。その中で、Terraformを使用したサーバーのプロビジョニングが有力な手段の一つです。

# Terraform紹介
Terraformは、インフラストラクチャをコードで管理するためのオープンソースのインフラストラクチャ自動化ツールです。このツールは、AWS、Azure、Google Cloudなどのクラウドプロバイダー、およびオンプレミスのリソースを統一的に扱い、インフラストラクチャのプロビジョニングと管理を効率的かつシンプルに行うために使用されます。

Terraformの公式ウェブサイト:https://www.terraform.io/

# 環境構築（事前準備）

・AWS CLI インストール
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html
・Terraform用のIAMユーザー作成
・GitBashインストール
https://git-scm.com/downloads
・Terraformをインストール
Terraformのバージョンやオペレーティングシステムに応じて詳細が異なる場合があります。以下公式ページで各OSのインストール手順が記入されています。
https://developer.hashicorp.com/terraform/downloads


# 環境構築確認

```shell
#AWS CLIのバージョン確認
$ aws --version                                                                                                                                                                                                                                                     
aws-cli/2.13.26 Python/3.11.6 Linux/5.10.197-186.748.amzn2.x86_64 exe/x86_64.amzn.2 prompt/off

#terraformのバージョン確認
$ terraform -v                                                                                                                                                                                                                                                     
Terraform v1.6.2
on linux_amd64

#gitのバージョン確認
$ git -v                                                                                                                                                                                                                                                      
git version 2.40.1

#tfenvのインストール(Terraformのバージョン管理用)
$ git clone https://github.com/tfutils/tfenv.git ~/.tfenv

#パスを通す
$ sudo ln -s ~/.tfenv/bin/* /usr/local/bin  

#tfenvのバージョン確認
$ tfenv -v
tfenv 3.0.0-18-g1ccfddb
```

# コードの実装
今回は以下の構成を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457891/6e0a3d4d-c4fe-1f82-e18d-c8c228f732c5.png)





まず、フォルダを作成して移動します。

```shell
$ mkdir terraform-test && cd terraform-test
#以下3つのファイルを作成
$ touch provider.tf
$ touch aws_network.tf
$ touch aws_ec2.tf
```

provider.tfファイルの内容です。
```shell
provider "aws" {
  region = "ap-northeast-1"
}
```
provider.tfファイルには、構築するリソースのプロバイダー情報を記述します。今回は"aws"を定義しています。regionには、リソースを構築するためのAWSリージョンを指定します。今回は、東京リージョン（ap-northeast-1）を指定しています。

※他のTerraformで対応しているプロバイダーは以下の公式ドキュメントをご確認ください。
https://registry.terraform.io/browse/providers


#### Terraformコードの構文について簡単に説明します。

Terraformのコードは、HCL（HashiCorp Configuration Language）という言語で記述されています。 HCLの構文は非常にシンプルで、初心者にも理解しやすい言語です。

例えば、
```shell
resource "リソースの種別" "リソース名" {
    項目1 = 項目のオプション
    項目2 = 項目のオプション
    項目3 = 項目のオプション
}
```
「リソースの種類」⇒例えば、aws_instance、aws_vpc
※リソースの種類の公式ページ：https://registry.terraform.io/providers/hashicorp/aws/latest/docs

「リソース名」⇒任意の文字列を記載することがOK

aws_network.tf
```shell
# VPCの作成
resource "aws_vpc" "terraform_vpc" {
  cidr_block           = "172.17.0.0/16"
  enable_dns_hostnames = true
}

# Publicサブネット作成
resource "aws_subnet" "terraform_publicSubnet" {
  vpc_id                  = aws_vpc.terraform_vpc.id
  cidr_block              = "172.17.1.0/24"
  availability_zone       = "ap-northeast-1a"
  map_public_ip_on_launch = true
}

# インターネットゲートウェイ作成

resource "aws_internet_gateway" "terraform_igw" {
  vpc_id = aws_vpc.terraform_vpc.id
}

# Publicルートテーブルの作成

resource "aws_route_table" "terraform_public_rtb" {
  vpc_id = aws_vpc.terraform_vpc.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.terraform_igw.id
  }
}

# Publicサブネットにルートテーブルを紐づけ

resource "aws_route_table_association" "terraform_public_rtable_assoc" {
  subnet_id      = aws_subnet.terraform_publicSubnet.id
  route_table_id = aws_route_table.terraform_public_rtb.id
}


# セキュリティグループの作成
resource "aws_security_group" "terraform_sg" {
  name   = "terraform-security01"
  vpc_id = aws_vpc.terraform_vpc.id
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
```

aws_ec2.tf
```shell
# EC2インスタンスの作成
resource "aws_instance" "terraform_server" {
  ami                    = "ami-04f0680f68f076681" # Amazon Linux 2
  instance_type          = "t2.micro"
  subnet_id              = aws_subnet.terraform_publicSubnet.id
  vpc_security_group_ids = [aws_security_group.terraform_sg.id]
  user_data = <<EOF
#!/bin/bash
# サーバーの設定変更
sudo yum install -y httpd
sudo systemctl start httpd
sudo systemctl enable httpd
EOF
}
```

# AWS環境上にリソース構築

```shell
#terraform初期化、AWS操作に必要なバイナリファイルをダウンロードします。
$ terraform init

#terraformのコードフォーマットする
$ terraform fmt

# 実施内容の確認
$ terraform plan

# 実環境への反映します。
# Enter a valueと表示されると、問題がなければ、「Yes」を入力しましょう。
$ terraform apply
```
# 結果確認
インスタンス作成できています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457891/6286c933-9b75-bb77-0a58-6c16f82ab424.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457891/41f8cfff-b327-9c74-ca5f-a01053b572fd.png)


VPC,Subnet, internet gateway,rounttableも作成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457891/b56ff04f-f833-4e2d-3a61-28d497c2dd4a.png)

# 最後にクリーンアップ
```shell
$ terraform destroy
```