AWS チュートリアル
AWSの無料枠で出来る範囲のチュートリアルがあったので試してみた経過を簡単にまとめてみました。
AWS等の実際の画面や操作はどんな感じか知りたい方を読者対象としているつもりです。
著者はAWS クラウドプラクティショナー、ソリューションアーキテクト アソシエイト という資格を取得済みで「AWSってなんぞや?」という概要を知識としてある程度理解しているが、実際にAWSの画面を触ったことが無いという状態でAWSのチュートリアルをこなしていくという状況です。
今回の内容としては、Terraform を用いて nginx の自動化をする、というものです。
何をやるのか
今は
EC2作る → 手動でSSH → nginx入れる
これを
terraform apply → すでにnginxが動いている
つまり、サーバーが完成状態で起動する
仕組み(重要)
EC2には「起動時に実行されるスクリプト」があります
→ それが user_data
実際のコード
前回作成した main.tf をこう書き換えます
provider "aws" {
region = "ap-northeast-1"
}
# セキュリティグループ
resource "aws_security_group" "web_sg" {
name = "web-sg"
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
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"]
}
}
# EC2
resource "aws_instance" "web" {
ami = "ami-0c3fd0f5d33134a76"
instance_type = "t3.micro"
vpc_security_group_ids = [aws_security_group.web_sg.id]
user_data = <<-EOF
#!/bin/bash
yum install -y nginx
systemctl start nginx
systemctl enable nginx
EOF
tags = {
Name = "terraform-nginx"
}
}
この1行の意味
vpc_security_group_ids = [aws_security_group.web_sg.id]
aws_security_group.web_sg
→ 上で作ったセキュリティグループ
.id
→ そのID(sg-xxxx)
→ 作ったSGをEC2に紐づけている
実行手順
</> Bash
terraform apply
→ yes
悪戦苦闘ログ
「terraform apply」と打ってみたものの、
XXX@DESKTOP-KAKL1SL MINGW64 /D/Userdata/documents/terraform-test
$ terraform apply
╷
│ Error: Failed to load plugin schemas
│
│ Error while loading schemas for plugin components: Failed to obtain
│ provider schema: Could not load the schema for provider
│ registry.terraform.io/hashicorp/aws: failed to instantiate provider
│ "registry.terraform.io/hashicorp/aws" to obtain schema: timeout while
│ waiting for plugin to start..
╵
AWSプロバイダ(プラグイン)が起動できていない状態です
よくある原因(ほぼこのどれか)
① プラグインが壊れている(最有力)
ダウンロード途中で壊れることがあります
② Windows + Git Bash 特有の問題
TerraformはネイティブWindows前提なので:
👉 Git Bashだとプラグイン起動でコケることがあります
③ セキュリティソフト干渉
Defender
ウイルス対策
👉 プラグイン実行をブロックすることあり
解決方法 (順番にやればOK)
方法①:キャッシュ削除(まずこれ)
Terraformフォルダで
rm -rf .terraform
rm .terraform.lock.hcl
その後
terraform init
terraform apply
方法②:PowerShellで実行(かなり有効)
Git Bashではなく
PowerShell
コマンドプロンプト
方法③:Terraform再インストール
公式から再DL
zip展開し直し
つまづきポイント
パブリック IPv4 アドレス、パブリック DNS アドレスをブラウザで入れてもエラーになって表示されない。
可能性その5
色々試す中で、VPC 周りの設定が良くないのか?と思い
VPC → お使いの VPC → VPC を作成
「VPCなど」 → VPC を作成
このような画面で進捗を見て → VPC を表示
リソースマップ → サブネット
パブリック IPv4 アドレスを自動割り当て
→ いいえなら、
アクション → サブネットの設定を編集
「パブリック IPv4 アドレスの自動割り当てを有効化」にチェックを入れ、「保存」
サブネットID, VPC の名前をメモし、
コードに貼り付け
provider "aws" {
# 東京リージョン
region = "ap-northeast-1"
}
# セキュリティグループ
resource "aws_security_group" "web_sg" {
name = "web-sg"
vpc_id = "vpc-0264525fb389542fc"
#
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
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"]
}
}
# EC2
resource "aws_instance" "web" {
ami = "ami-0c3fd0f5d33134a76"
# 無料枠のものを選択
instance_type = "t3.micro"
subnet_id = "subnet-039e3387eace155c2"
associate_public_ip_address = true
vpc_security_group_ids = [aws_security_group.web_sg.id]
user_data = <<-EOF
#!/bin/bash
exec > /var/log/user-data.log 2>&1
# 初期化待ち
sleep 30
# Extras有効化してnginxインストール: nginx ではなく nginx1
amazon-linux-extras install -y nginx1
# 起動
systemctl start nginx
systemctl enable nginx
EOF
tags = {
Name = "terraform-nginx"
}
}
するも、nginx 画面が出ず…
可能性その 6
VPC → ルートテーブル が
のようになり、正しいルートテーブルは
0.0.0.0/0 → igw-xxxx
のはずなのにターゲットがlocalになっているところが間違っているポイントのようで、
「ルートテーブルの関連付けを編集」
ルートテーブルIDを、ルートでターゲットが「igw」で始まるものが出てくるものを選択し、「保存」

…するもダメ…
「サブネットは正しい」
「ルートテーブルも正しい」
それでもダメ
原因として、「EC2のネットワークインターフェースが正しくパブリック経路に乗っていない」可能性
EC2 → Elastic IP → 「Elastic IP アドレスを割り振る」 → 「割り振る」
「アクション」 → 「関連付け」
「インスタンス」で対象インスタンスを選択 → 「関連付ける」
上記のようにElastic IP を設定し、http://Elastic IP に接続…も、タイムアウト状態は変わらず。(ダメ…)
再点検
セキュリティグループが本当に効いているかチェック
EC2 → インスタンス → 該当するインスタンスを選択 → 「接続」
「接続」
「パブリックIpv4アドレス」をコピーし、
先ほど接続で出した黒背景のターミナル(EC2)で
curl -I http://<自分のパブリックIPv4アドレス>
とすると
HTTP/1.1 200 OK
となった
→ セキュリティグループ or 外部経路の問題
nginxの待ち受け確認
黒背景のターミナル(EC2)で
sudo ss -tuln | grep 80
正常なら
0.0.0.0:80
→ 正常
nginx設定
EC2 で
sudo cat /etc/nginx/nginx.conf | grep listen
正常なら
listen 80;
→ 正常
セキュリティグループの実体確認
EC2コンソール(白背景)で
EC2 → インスタンス → 実行中のもの → セキュリティ → インバウンドルール →
ポート: 80
ソース: 0.0.0.0/0
正常なら
ポート80
0.0.0.0/0
→ 正常
OS Firewall
EC2(黒背景)で
sudo iptables -L
DROP があれば
sudo systemctl stop firewalld
sudo iptables -F
ローカルホスト、プライベートIP, パブリックIPの確認
EC2(黒背景)で
curl -I http://localhost
curl -I http://<プライベートIP>
curl -I http://<パブリックIP>
| 結果 | 原因 |
|---|---|
| localhost OK / private NG | OS |
| private OK / public NG | AWS側 |
| 全部OK | 外部経路 |
→ 全部OKだったので原因は外部経路
EC2 → 外部へ通信できる
EC2 → 自分のパブリックIPにも到達できる
→ AWS内のネットワークは完全に正常
→ インスタンス自体は完全に正常。問題は「VPCの外側(自分のPC側)」
つまり何が起きているか
PC → AWS への通信だけ失敗している
| テスト | 結果 |
|---|---|
| EC2内部 localhost | OK |
| EC2内部 public IP | OK |
| 自PC curl public IP | OK |
| ブラウザ | ❌ |
→ AWS・EC2・nginxは「完全に正常」
→ 問題は「ブラウザ表示だけ」
- シークレットモードでアクセス
→ NG - 別ブラウザで試す
→ NG - URL確認(地味に多い)
これになってないか確認
https://<IP>
正しくは
http://<IP>
ここが間違っていた!
ブラウザが Microsoft edge だったからか、パブリックIPv4アドレス、パブリックDNSのリンクをクリックすると
このように、http:// ではなく https:// でリンクに飛ばされるというのが罠だったのだ
現状で開いているのは http のポート 80 であって、HTTPSではないために、タイムアウトしてしまったということのようである。
httpの表示が隠れているが、http:// で繋いでみると、無事
このように、サーバーを表示することが出来た。
長かった…
最終的な 環境構築ファイル について
############################################
# プロバイダー設定(AWS東京リージョン)
############################################
provider "aws" {
region = "ap-northeast-1"
}
############################################
# VPC(ネットワークの土台)
############################################
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "terraform-vpc"
}
}
############################################
# インターネットゲートウェイ(外部通信)
############################################
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.main.id
tags = {
Name = "terraform-igw"
}
}
############################################
# パブリックサブネット(インターネット接続用)
############################################
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-northeast-1a"
# EC2起動時にパブリックIP自動付与
map_public_ip_on_launch = true
tags = {
Name = "terraform-public-subnet"
}
}
############################################
# ルートテーブル(通信経路の定義)
############################################
resource "aws_route_table" "public_rt" {
vpc_id = aws_vpc.main.id
# インターネットへのルート
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}
tags = {
Name = "terraform-public-rt"
}
}
############################################
# サブネットとルートテーブルの関連付け
############################################
resource "aws_route_table_association" "public_assoc" {
subnet_id = aws_subnet.public.id
route_table_id = aws_route_table.public_rt.id
}
############################################
# セキュリティグループ(通信制御)
############################################
resource "aws_security_group" "web_sg" {
name = "web-sg"
vpc_id = aws_vpc.main.id
# HTTP(Webアクセス)
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# SSH(接続用)※本番では制限推奨
ingress {
from_port = 22
to_port = 22
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"]
}
tags = {
Name = "terraform-web-sg"
}
}
############################################
# EC2インスタンス(Webサーバー)
############################################
resource "aws_instance" "web" {
ami = "ami-0c3fd0f5d33134a76" # Amazon Linux 2
instance_type = "t3.micro"
subnet_id = aws_subnet.public.id
vpc_security_group_ids = [aws_security_group.web_sg.id]
associate_public_ip_address = true
##########################################
# user_data(起動時に自動実行されるスクリプト)
##########################################
user_data = <<-EOF
#!/bin/bash
exec > /var/log/user-data.log 2>&1
# 少し待つ(初期化安定のため)
sleep 30
# nginxインストール(Amazon Linux 2)
amazon-linux-extras install -y nginx1
# nginx起動
systemctl start nginx
# 自動起動設定
systemctl enable nginx
EOF
tags = {
Name = "terraform-nginx"
}
}
############################################
# 出力(IPを表示)
############################################
output "public_ip" {
value = aws_instance.web.public_ip
}
output "public_dns" {
value = aws_instance.web.public_dns
}
このファイルを用意し、そのフォルダで
terraform destroy
→ yes
terraform apply
→ yes
とすることで、環境をコードから構築することができるようになります。
※ 初期化安定のため sleep が入っているので、起動したように見えてから1~2分ほど待つ必要があります。
パブリックDNSを表示させる
main.tfファイルで terraform apply から起動したものの、パブリックDNSが非表示になっている
これを表示させるには、以下の手順を踏む。
VPC → お使いのVPC → 該当のVPCを選択 → アクション → VPCの設定を編集
DNS設定 → DNS解決を有効化・DNSホスト名を有効化に両方チェック → 保存
EC2 → インスタンスに戻り、上部の更新マークを選択することで、パブリックDNSが表示されるようになります。

























