Terraformの検証環境コード一部紹介：AWS CloudShellを使って、たった3分でさまざまな環境を自動デプロイ

## はじめに
AWS CloudShellは、AWSが提供するクラウドベースのターミナルで、ブラウザ上からAWS CLIやさまざまなツールを操作することができます。

:::note warn
**私は普段、検証環境を作成する際にAWS CloudShellを活用し、Terraformを使って約3分で簡単に検証環境を作成しています。**
:::

これまでのブログ記事でもいくつかの方法を紹介してきましたが、***今回は私が最もよく利用している検証環境用のコードを改めて公開しようと思います。***

## 書こうと思ったきっかけ
当初、AWS CloudShellからTerraformを使用して環境を構築するのは技術的に難しいと感じていました。***しかし、インターネット上でその方法に関する記事を見つけたことがきっかけで、自分でも試してみました。***

https://dev.classmethod.jp/articles/terraform-cloudshell/

結果は予想以上に簡単で、環境構築をスピーディーに進めることができました。

:::note info
***検証環境のデプロイもあっという間に完了し、AWSマネジメントコンソールにログインしてからわずか3分程度で検証環境を整えることが可能になりました。***
:::

***今回の記事では、私がAWSマネジメントコンソールを使って、どのように迅速に検証環境を作成しているのか、その手順を実際にご紹介しながらまとめていきます。***

## AWS CloudShellとは

AWS CloudShellは、AWSが提供するブラウザベースのシェル環境です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/ce88c49c-7686-ea91-cb66-dd521adbc117.png)

このサービスには以下のような特徴があります。

:::note
- **事前にAWS CLIが設定済み：**
AWSのコマンドラインインターフェース（CLI）があらかじめ設定されており、セットアップの手間が不要です。

- **無料で利用可能（一部制限あり）：**
基本的な利用は無料で、特定の制限内でサービスを活用できます。
:::

CloudShellに関しては、過去の記事でも詳しくまとめていますので、興味のある方はぜひご参照ください。

https://qiita.com/free-honda/items/cc3f4c68f7d1521830c3

## Terraformとは
Terraformは、インフラストラクチャをコード化（Infrastructure as Code, IaC）して管理するためのツールです。

![スクリーンショット 2024-12-06 20.19.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/5ab32343-efb7-af07-5ddc-625f1e5a14af.png)
引用画像：https://www.whizlabs.com/blog/what-is-terraform-terraform-tutorial/


Terraformには以下のようなメリットがあります。

:::note
- **多くのクラウドをサポート：**
AWS、Azure、Google Cloudなど、さまざまなクラウドプロバイダに対応しています。

- **宣言型：**
必要なインフラの状態を記述し、Terraformがその状態に到達するための処理を自動で行います。

- **バージョン管理：**
インフラの変更履歴を管理でき、変更が追跡可能です。
:::

***Terraformに関する詳細や技術検証については、私のマイページからぜひチェックしてみてください！***

## 私の実際の使い方について
ここでご紹介する内容は、あくまで私個人の使用方法です。その点をご了承ください。

### 起動後にいつも行っている環境構築
CloudShellを起動すると、まずTerraformの環境構築を行います。

:::note warn
**初めて環境構築を行う方は、以下のコマンドを入力することでTerraformの環境が構築できます。**
:::

私はいつも決まったコマンドを使用しており、以下にその手順を記載します。

```memo.txt
wget https://releases.hashicorp.com/terraform/0.14.2/terraform_0.14.2_linux_amd64.zip
sudo unzip terraform_0.14.2_linux_amd64.zip -d /usr/local/bin/
terraform init
terraform apply
terraform destroy
```

### 注意点

- **`wget`コマンド（1行目）については、最初の1回のみ実行すれば問題ありません。**  
  実行後、カレントディレクトリにZIPファイルがダウンロードされます。

- **次回以降は、ダウンロードしたZIPファイルを再利用してください。**  
  `sudo unzip`コマンドを使用して、Terraformの環境を構築します。

### 事前に用意している検証環境のコードについて
私の場合、CloudShell上にTerraformコードのいくつかの検証パターンを事前に用意しています。

***以下のスクリーンショットのように、必要に応じて使いたいコードを `main.tf` という名前のファイルにリネームして利用しています。***

![Screenshot 2025-01-10 at 17.25.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/598571d2-af71-7139-8def-e53005a24d40.png)

これまでは主にLinux環境を構築し、Apacheが導入されたウェブサーバーを手軽に立ち上げることが多かったです。

:::note
***しかし、最近ではTerraformを活用したWindowsサーバーの構築にも興味を持ち、Active DirectoryやDNSといったインフラ環境もTerraformで管理するようになりました。***
:::

## Terraformの検証環境コード一部紹介
今回は、私が最もよく使用しているLinux環境の検証用セットアップコードをご紹介します。

:::note warn
***このコードは、シンプルなAZ構成でApacheウェブサーバーを1台構築する内容です。`user_data` セクションを使用して、OS内で実行するコマンドを設定しています。***
:::

### 注意点

- **キーペアや秘密鍵を設定していない**  
  - このため、SSH接続には **[キーペア（秘密鍵）不要なEC2 Instance Connect](https://qiita.com/free-honda/items/90fddc7b90246f4d3719)** を使用する構成になっています。

- **シンプルで迅速なサーバー構築**  
  - 手早く1台のサーバーが必要な場合によく利用しています。

***コードの内容を確認して、必要に応じて活用してみてください！***

```main.tf
provider "aws" {
  region = "ap-northeast-1" # Tokyo region
}

# VPC作成
resource "aws_vpc" "main_vpc" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
    Name = "terraform-main-vpc"
  }
}

# サブネット作成 (パブリックサブネット)
resource "aws_subnet" "public_subnet" {
  vpc_id                  = aws_vpc.main_vpc.id
  cidr_block              = "10.0.1.0/24"
  map_public_ip_on_launch = true

  tags = {
    Name = "terraform-public-subnet"
  }
}

# インターネットゲートウェイ作成
resource "aws_internet_gateway" "main_igw" {
  vpc_id = aws_vpc.main_vpc.id

  tags = {
    Name = "terraform-main-igw"
  }
}

# ルートテーブル作成
resource "aws_route_table" "public_route_table" {
  vpc_id = aws_vpc.main_vpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.main_igw.id
  }

  tags = {
    Name = "terraform-public-route-table"
  }
}

# サブネットとルートテーブルの関連付け
resource "aws_route_table_association" "public_association" {
  subnet_id      = aws_subnet.public_subnet.id
  route_table_id = aws_route_table.public_route_table.id
}

# セキュリティグループ作成
resource "aws_security_group" "public_sg" {
  vpc_id = aws_vpc.main_vpc.id

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"] # HTTPアクセスを許可
  }

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"] # SSHアクセスを許可
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"] # すべてのアウトバウンドを許可
  }

  tags = {
    Name = "terraform-public-sg"
  }
}

# EC2インスタンス作成
resource "aws_instance" "apache_ec2" {
  ami                         = "ami-0b6fe957a0eb4c1b9" # Amazon Linux 2 AMI (Tokyo region)
  instance_type               = "t2.micro"
  subnet_id                   = aws_subnet.public_subnet.id
  security_groups             = [aws_security_group.public_sg.id] # 修正: IDを参照
  associate_public_ip_address = true # パブリックIPv4アドレスを有効化

  user_data = <<-EOF
    #!/bin/bash
    yum update -y
    yum install -y httpd
    systemctl start httpd
    systemctl enable httpd
    echo "<html><body><h1>Welcome to Apache Server powered by Terraform!</h1></body></html>" > /var/www/html/index.html
  EOF

  depends_on = [aws_security_group.public_sg] # 修正: セキュリティグループに依存

  tags = {
    Name = "terraform-apache-ec2"
  }
}
```

## こんな感じのEC2インスタンスが構築されます
このコードを使えば、わずか3分でウェブサーバーを1台構築することが可能です。

:::note info
***EC2インスタンス上でちょっとしたコマンドを試したいときに、このコードを利用して様々な検証を行っています。***
:::

以下は、実際に構築されたインスタンスの画面です。

![Screenshot 2025-01-10 at 17.37.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/9cdfcc19-da04-33b6-8e35-9d15b9b5bdc1.png)

構築されたEC2のパブリックIPアドレスにブラウザでアクセスすると、以下のようにApacheのHTMLファイルが表示されます。

![Screenshot 2025-01-10 at 17.44.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/bd335646-3d19-a99d-242d-c4edfefd447a.png)

使い終わった場合には、冒頭でご紹介した `terraform destroy` コマンドを実行することで、インスタンスを即座に削除できます。

## まとめ
ここまでお読みいただき、ありがとうございました。***私自身、AWSの検証費用を削減したいと考えており、今後も積極的にTerraformを活用して、コードのテンプレートを増やしていく予定です。***

:::note info
**今回は、ほんの一部のコードのみをご紹介しましたが、今後もタイミングを見て有益なコードを公開していきたいと思っています。**
:::

***この記事の内容が、どなたかの技術的な参考になれば幸いです！***