今日学んだこと#
Terraformの user_data を使って、EC2起動時にApacheを自動インストールする方法を学びました。手動でSSH接続してセットアップする手間を省き、インフラ構築を完全に自動化できます。
学習内容#
user_dataとは#
EC2インスタンスの初回起動時に実行されるスクリプトです。OSの初期設定やソフトウェアのインストールを自動化できます。
Terraformコード#
resource "aws_instance" "web" {
ami = data.aws_ami.amazon_linux_2023.id
instance_type = "t3.micro"
subnet_id = aws_subnet.public.id
vpc_security_group_ids = [aws_security_group.web.id]
key_name = aws_key_pair.main.key_name
user_data = <<-EOF
#!/bin/bash
dnf update -y
dnf install -y httpd
systemctl start httpd
systemctl enable httpd
EOF
tags = {
Name = "practice-web"
}
}
ヒアドキュメント構文#
user_data = <<-EOF
#!/bin/bash
コマンド1
コマンド2
EOF
| 要素 | 説明 |
|---|---|
<<-EOF | ヒアドキュメント開始。- があると先頭のタブを除去 |
#!/bin/bash | シェバン。Bashで実行することを指定 |
EOF | ヒアドキュメント終了(任意の文字列でOK) |
<<EOF と <<-EOF の違い#
# <<EOF(ハイフンなし): インデントがそのまま含まれる
user_data = <<EOF
#!/bin/bash
echo "hello"
EOF
# <<-EOF(ハイフンあり): 先頭のタブを除去
user_data = <<-EOF
#!/bin/bash
echo "hello"
EOF
Terraformコードのインデントを揃えたい場合は <<-EOF を使います。
💡 補足:標準のシェルでは
-はタブのみ除去しますが、Terraform/HCLでは独自処理でインデントを適切に処理します。
スクリプトの内容#
#!/bin/bash
dnf update -y # パッケージを最新化
dnf install -y httpd # Apacheをインストール
systemctl start httpd # Apacheを起動
systemctl enable httpd # OS再起動時に自動起動
Amazon Linux 2023ではパッケージマネージャーが dnf になっています(旧Amazon Linux 2は yum)。
動作確認#
EC2作成後、パブリックIPにHTTPアクセスします。
http://<パブリックIP>
「It works!」が表示されれば成功です。
トラブルシューティング#
接続できない場合の確認ポイント:
- セキュリティグループ: ポート80(HTTP)が許可されているか
- user_dataログ: SSH接続して以下で確認
sudo cat /var/log/cloud-init-output.log - Apache状態:
systemctl status httpdで起動状態を確認
user_dataの注意点#
| 注意点 | 詳細 |
|---|---|
| 初回起動時のみ | 再起動しても再実行されない |
| 変更時は再作成 | user_dataを変更すると、EC2はdestroy→createになる |
| ログ確認 | /var/log/cloud-init-output.log で実行結果を確認可能 |
| 実行完了を待たない | EC2が「running」でもスクリプト実行中の場合がある |
応用:変数を埋め込む#
variable "app_name" {
default = "myapp"
}
resource "aws_instance" "web" {
# ...
user_data = <<-EOF
#!/bin/bash
echo "Deploying ${var.app_name}" > /var/www/html/index.html
EOF
}
ヒアドキュメント内でも ${var.xxx} で変数展開が可能です。
まとめ#
| トピック | 内容 |
|---|---|
| user_data | EC2初回起動時に実行されるスクリプト |
| ヒアドキュメント | <<-EOF ... EOF で複数行文字列を記述 |
- の意味 | 先頭のタブを除去(Terraformではスペースも処理される) |
| 初回のみ | 再起動では再実行されない。変更時はEC2再作成 |