概要
EC2にWebサーバを立て、ドメイン経由でアクセスできるように構築する手順の備忘録です。
2025年1月時点での情報となります。
想定する読者として、AWSの主要サービスの基本的な内容について理解されている方向けの内容となっております。
そのため基本的に手順のみ記載し、各設定項目の意味などは省略しております。
利用サービス
- AWS
- VPC
- EC2
- Route 53
- Lambda
- EventBridge
- ドメイン取得サービス(今回はお名前.comを利用)
構成図
- パブリックサブネットにEC2サーバを設置し、インターネットゲートウェイを通じてHTTPでアクセスする
- ドメインをお名前.comで取得し、Route 53に登録して名前解決する
- EC2インスタンス起動時にEventBridge経由でLambda Functionを呼び出し、Route53の名前解決用レコードを更新する
手順
VPC作成
VPC→「VPCを作成」を押下し、VPC作成画面に遷移
「作成するリソース」で「VPCなど」を選択することにより、アベイラビリティゾーンやサブネット等を同時に作成可能
今回はデフォルトから以下の通り変更
設定項目 | デフォルト | 設定値 |
---|---|---|
名前タグの自動生成 | 自動生成ON プロジェクト |
自動生成ON <任意の値> |
アベイラビリティゾーン (AZ) の数 | 2 | 1 |
パブリックサブネットの数 | 2 | 1 |
プライベートサブネットの数 | 2 | 0 |
VPC エンドポイント | S3ゲートウェイ | なし |
EC2インスタンス作成
EC2→「インスタンスを起動」を押下し、インスタンス作成画面に遷移
Amazon マシンイメージとインスタンスタイプは種類によっては料金が発生する
今回は無料利用枠の対象の「Amazon Linux 2023 AMI」と「t2.micro」を選択
キーペア設定
「キーペア (ログイン) 」の「新しいキーペアを作成」を押下し、「キーペア名」に任意の値を入力して「キーペアを作成」を押下
作成後、 .pem
ファイルがダウンロードされるので任意の場所に保管
ネットワーク設定
デフォルトから以下の通り変更
設定項目 | デフォルト | 設定値 |
---|---|---|
VPC | <未選択> | <作成したVPC> |
サブネット | <未選択> | <作成したサブネット> |
パブリックIPの自動割り当て | 無効化 | 有効化 |
セキュリティグループ名 | launch-wizard-1 | <任意の値> |
インバウンドセキュリティグループのルールを以下の通り変更
ルール | タイプ | ソースタイプ | 備考 |
---|---|---|---|
1 | ssh | 自分のIP | 最初から存在する |
2 | HTTP | 自分のIP | 「セキュリティグループルールを追加」押下で追加 |
設定後、「インスタンスを起動」を押下し、処理が成功すればOK
Apache導入
SSHでインスタンスに接続する(今回は Tera Term を利用)
EC2 Instance Connect にて接続する場合
セキュリティグループのインバウンドルールにて、
EC2 Instance Connect エンドポイントからの通信を許可する必要がある
(東京リージョンの場合はcom.amazonaws.ap-northeast-1.ec2-instance-connect
)
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/eice-security-groups.html#resource-security-group-rules
- Host: インスタンス起動時に割り当てられた「パブリック IPv4 アドレス」の値
- User name: ec2-user
-
Authentication methods:
「Use RSA/DSA/ECDSA key to log in」→保存した.pem
ファイルを選択
Apache をインストール
sudo yum install httpd -y
Apache を起動
sudo systemctl start httpd
EC2起動時に Apache が自動起動するように設定
sudo systemctl enable httpd.service
ブラウザから http://{パブリック IPv4 アドレス}
にアクセスし、ページが表示されればOK
HTTPS ではなく HTTP で接続する必要がある
ドメイン取得
お名前.comのアカウントを作成
https://www.onamae.com/
料金を確認し、任意の支払い方法を選択して「申込む」を押下
今回は「その他の支払い方法はこちら」→「コンビニ」を選択
管理画面に戻り、「ご利用中のサービス」にドメインが表示されていればOK
ドメイン設定
Route 53→左側メニューの「ホストゾーン」→「ホストゾーンの作成」を押下し、ホストゾーン作成画面に遷移
「ドメイン名」に取得したドメインを入力し、「ホストゾーンの作成」を押下
ホストゾーンが正常に作成されていることを確認
このとき、NSレコードの「値/トラフィックのルーティング先」の4つの値を控えておく
「レコードを作成」を押下し、以下の通り入力して「レコードを作成」を押下
- レコード名: 未入力
- レコードタイプ: A
- 値: インスタンス起動時に割り当てられた「パブリック IPv4 アドレス」の値
お名前.comにて取得したドメインの詳細画面を開き、「ネームサーバーの変更」を押下
「2.ネームサーバーの選択」で「その他のサービス」タブを開く
ネームサーバー1~4に、先ほど控えておいた4つの値を入力し「確認」→「OK」を押下
AWSでは「ns-23.awsdns-02.com.」のように末尾が「.」となっているが、
お名前.comに登録時は除去する
ブラウザから http://{ドメイン名}
にアクセスし、ページが表示されればOK
ここまででドメイン経由でのWebページアクセスが可能となりました。
しかし、EC2インスタンスにElastic IPアドレスを持たせない場合の課題として、インスタンス起動ごとにパブリックIPアドレスが変更されるためRoute 53にAレコードを再登録する必要があります。
ここからは上記を自動化する手順について記載します。
Lambda Function作成
Lambda→「関数の作成」を押下し、インスタンス作成画面に遷移
各種情報入力後、「関数の作成」を押下(今回はPythonで作成)
EventBridge設定
Lambda→左側メニューの「ルール」→「ルールを作成」を押下し、ホストゾーン作成画面に遷移
以下の通り入力する
ルールの詳細を定義
イベントパターンを構築
-
イベントソース: AWS のサービス
-
AWS のサービス: EC2
-
イベントタイプ: EC2 Instance State-change Notification
-
イベントタイプの仕様 1: 特定の状態
-
特定の状態: running
-
イベントタイプの仕様 2: 個別のインスタンス ID
ターゲットを選択
レビューと作成
入力内容を確認し、「ルールの作成」を押下
Lambda Function設定
作成したLambda Functionの詳細画面を開く
「設定」タブにて以下の通り設定する
一般設定
アクセス制限
「ロール名」のリンクを押下→「許可を追加」から以下のポリシーをアタッチ
- AmazonEC2FullAccess
- AmazonRoute53FullAccess
環境変数
以下の環境変数を登録
Lambda Functionコーディング
作成したLambda Functionの詳細画面を開く
コードソースを以下の内容に変更してデプロイする
import json
import os
import boto3
from datetime import datetime
def datetime_isoformat(o):
if isinstance(o, datetime):
return o.isoformat()
def lambda_handler(event, context):
print("event:")
print(json.dumps(event, default=datetime_isoformat))
instance_id = event["detail"]["instance-id"]
if event["detail"]["state"] == "running":
action = "UPSERT"
else:
action = ""
ec2 = boto3.client("ec2")
ec2_data = ec2.describe_instances()
reservations = ec2_data["Reservations"]
for reservation in reservations:
instances = reservation["Instances"]
for instance in instances:
if instance_id == instance["InstanceId"]:
public_ip_address = instance["PublicIpAddress"]
route53 = boto3.client("route53")
change_batch = {
"Changes": [
{
"Action": action,
"ResourceRecordSet": {
"Name": os.environ.get("DomainName"),
"Type": "A",
"TTL": 300,
"ResourceRecords": [{"Value": public_ip_address}],
},
}
]
}
response = route53.change_resource_record_sets(
HostedZoneId=os.environ.get("HostedZoneId"), ChangeBatch=change_batch
)
print("response:")
print(json.dumps(response, default=datetime_isoformat))
return "Success"
EC2インスタンスを起動し、以下を確認できればOK
- 作成したホストゾーンのAレコードの値が、インスタンス起動時に割り当てられた「パブリック IPv4 アドレス」の値で更新されていること
- ブラウザから
http://{ドメイン名}
にアクセスし、ページが表示されること