📝

Elastic Beanstalk 環境に Apache の VirtualHost を構築してみた

2023/10/12に公開

今回は Elastic Beanstalk 環境に Apache の VirtualHost を構築する方法を紹介します。

AWS 環境に Apache の VirtualHost を構築する例についてはいくつか紹介されていますが、いずれも Elastic Beanstalk 環境ではなかったため今回は Elastic Beanstalk 環境での設定手順を紹介します。

前提

今回は Route 53 へのドメイン登録が完了している前提ですが、ドメイン未登録の場合にはドキュメントを参考にドメインの登録やホストゾーンの作成を行ってください。

Amazon Route 53 を使用したドメインの登録と管理 - Amazon Route 53

事前準備

まずは Elastic Beanstalk 環境を作成するための環境作りから始めます。

  • Cloud9 環境作成
  • EB CLI のインストール

Cloud9 環境作成

Cloud9 環境の作成についてはドキュメントを参考に実施してください。
私の場合はすべてデフォルト設定で作成しました。

ステップ 1: 環境を作成する - AWS Cloud9

EB CLI のインストール

Cloud9 環境起動後にターミナルを起動して EB CLI をインストールします。
ドキュメントでも紹介されているセットアップスクリプトを使用します。

EB CLI のインストール - AWS Elastic Beanstalk

基本的には GitHub の手順通りにコマンドを実行するだけです。

GitHub - aws/aws-elastic-beanstalk-cli-setup: Simplified EB CLI installation mechanism.

# リポジトリクローン
$ git clone https://github.com/aws/aws-elastic-beanstalk-cli-setup.git

# セットアップスクリプト実行
$ python ./aws-elastic-beanstalk-cli-setup/scripts/ebcli_installer.py

# パスの設定
$ echo 'export PATH="/home/ec2-user/.ebcli-virtual-env/executables:$PATH"' >> ~/.bash_profile && source ~/.bash_profile

# eb コマンドの実行確認
$ eb --version
EB CLI 3.20.10 (Python 3.7.16 (default, Aug 30 2023, 20:37:53) 
[GCC 7.3.1 20180712 (Red Hat 7.3.1-15)])

ここまでで事前準備は完了です。

Elastic Beanstalk 環境の作成

今回使用する Elastic Beanstalk 環境を作成します。

チュートリアルおよびサンプルから「Node.js – nodejs.zip」のリンクをクリックしてサンプルアプリケーションをダウンロードしてください。

チュートリアルおよびサンプル - AWS Elastic Beanstalk

ダウンロード後に zip ファイルを解凍して以下の手順で Cloud9 環境にフォルダごとアップロードします。

Cloud9 上部の「File」> 「Upload Local Files...」>「Select folder」> 解凍した nodejs フォルダ

Elastic Beanstalk アプリケーションの設定

フォルダのアップロード後、ターミナルを開いてアップロードした nodejs フォルダに移動します。

$ cd nodejs

EB CLI で Elastic Beanstalk 環境を作成します。
まずは eb init コマンドで Elastic Beanstalk アプリケーションの設定を行います。

eb init - AWS Elastic Beanstalk

# SSH 接続を設定するために -i オプションで対話モードにしています。
$ eb init -i

# リージョンは東京リージョンを指定するので 9 を入力します。
Select a default region
1) us-east-1 : US East (N. Virginia)
2) us-west-1 : US West (N. California)
3) us-west-2 : US West (Oregon)
4) eu-west-1 : EU (Ireland)
5) eu-central-1 : EU (Frankfurt)
6) ap-south-1 : Asia Pacific (Mumbai)
7) ap-southeast-1 : Asia Pacific (Singapore)
8) ap-southeast-2 : Asia Pacific (Sydney)
9) ap-northeast-1 : Asia Pacific (Tokyo)
10) ap-northeast-2 : Asia Pacific (Seoul)
11) sa-east-1 : South America (Sao Paulo)
12) cn-north-1 : China (Beijing)
13) cn-northwest-1 : China (Ningxia)
14) us-east-2 : US East (Ohio)
15) ca-central-1 : Canada (Central)
16) eu-west-2 : EU (London)
17) eu-west-3 : EU (Paris)
18) eu-north-1 : EU (Stockholm)
19) eu-south-1 : EU (Milano)
20) ap-east-1 : Asia Pacific (Hong Kong)
21) me-south-1 : Middle East (Bahrain)
22) il-central-1 : Middle East (Israel)
23) af-south-1 : Africa (Cape Town)
24) ap-southeast-3 : Asia Pacific (Jakarta)
25) ap-northeast-3 : Asia Pacific (Osaka)
(default is 3): 9

# アプリケーション名はデフォルトのままにします。
Enter Application Name
(default is "nodejs"): 
Application nodejs has been created.

# Node.js の使用で間違いないので続行します。
It appears you are using Node.js. Is this correct?
(Y/n): 
# プラットフォームは 2 の Amazon Linux 2 を選択します。
Select a platform branch.
1) Node.js 18 running on 64bit Amazon Linux 2023
2) Node.js 18 running on 64bit Amazon Linux 2
3) Node.js 16 running on 64bit Amazon Linux 2 (Deprecated)
4) Node.js 14 running on 64bit Amazon Linux 2 (Deprecated)
(default is 1): 2

# SSH キーの設定をしたいので Y で続行します。
Cannot setup CodeCommit because there is no Source Control setup, continuing with initialization
Do you want to set up SSH for your instances?
(Y/n): 

# キーペア名はデフォルトのまま続行します。
Type a keypair name.
(Default is aws-eb): 

# 以下の設定もデフォルトのまま続行します。
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
our identification has been saved in /home/ec2-user/.ssh/aws-eb.
Your public key has been saved in /home/ec2-user/.ssh/aws-eb.pub.
The key fingerprint is:
SHA256:hogehoge aws-eb
The key's randomart image is:
+---[RSA 2048]----+
<>
+----[SHA256]-----+
WARNING: Uploaded SSH public key for "aws-eb" into EC2 for region ap-northeast-1.

以上で Elastic Beanstalk アプリケーションの設定は完了です。

Elastic Beanstalk 環境の作成

eb create コマンドで Elastic Beanstalk 環境を作成します。

eb create - AWS Elastic Beanstalk

# ロードバランサーなしの単一インスタンス環境作成のために --single オプションを付与しています
$ eb create --single
# 以下、デフォルトのまま続行します
Enter Environment Name
(default is nodejs-dev): 
Enter DNS CNAME prefix
(default is nodejs-dev2): 

Would you like to enable Spot Fleet requests for this environment? (y/N): 

~ 以下、環境作成イベントのため略 ~

# 環境の作成が完了すれば OK です
2023-10-12 10:19:05    INFO    Successfully launched environment: nodejs-dev

Elastic Beanstalk 環境の確認

Elastic Beanstalk 環境をコンソールから確認すると以下のリソースが作成されていることがわかります。

  • アプリケーション: nodejs
  • 環境: nodejs-dev

環境のドメインにアクセスするとサンプルアプリケーションのページが表示されます。

Route 53 でエイリアスを設定

デフォルトの Elastic Beanstalk 環境に対して Route 53 に登録したドメインからアクセスできるようにエイリアスを設定します。

エイリアスレコードと非エイリアスレコードの選択 - Amazon Route 53

Amazon Route 53 エイリアスレコード で、DNS 機能に Route 53 固有の拡張機能が追加されます。エイリアスレコードを使用すると、選択した AWS リソース (CloudFront ディストリビューションや Amazon S3 バケットなど) にトラフィックをルーティングできます。

ルートドメインとサブドメインにそれぞれエイリアスを設定します。
VirtualHost へのアクセス用に以下のサブドメインでエイリアスを設定します。

  • test1
  • test2



エイリアスの設定後にルートドメインおよびサブドメインでサンプルアプリケーションのページが表示されることを確認してください。



Elastic Beanstalk 環境の拡張

ドキュメントで紹介されている通り、Elastic Beanstalk では Linux プラットフォームを拡張することが可能です。

Elastic Beanstalk Linux プラットフォームの拡張 - AWS Elastic Beanstalk

AWS Elastic Beanstalk Linux プラットフォームは、アプリケーションの開発と実行をサポートする多くの機能を提供します。

今回はプラットフォームの拡張を使用して Apache の VirtualHost の設定を実施します。

リバースプロキシの設定

ドキュメントに記載されている通り、Linux 2 プラットフォームのデフォルトのプロキシサーバーは nginx です。

Elastic Beanstalk Linux プラットフォームの拡張 - AWS Elastic Beanstalk

すべての Amazon Linux 2 プラットフォームのバージョンは、デフォルトのリバースプロキシサーバーとして nginx を使用します。

ただし、Apache への変更も可能で、設定例も紹介されていますので今回はドキュメントの例をそのまま使用します。

.ebextensions/httpd-proxy.config
option_settings:
  aws:elasticbeanstalk:environment:proxy:
    ProxyServer: apache

Elastic Beanstalk で環境を拡張する場合、特定のディレクトリ構成などが必要となります。
上記 Apache への変更の設定についても .ebextensions というディレクトリ配下に .config ファイルを配置する必要があります。

サンプルアプリケーションにはすでに .ebextensions が存在しており、logging.config という .config ファイルが配置されています。

Apache への設定変更ファイルについても .config ファイルを作成して、ドキュメントの例を記載します。

$ touch .ebextensions/01httpd-proxy.config
.ebextensions/01httpd-proxy.config
option_settings:
  aws:elasticbeanstalk:environment:proxy:
    ProxyServer: apache

VirtualHost 用ディレクトリおよびファイルの作成

VirtualHost 用に各サイトごとのディレクトリを作成する必要があります。
Elastic Beanstalk 環境内の EC2 インスタンスに SSH 接続して作成する方法もありますが、.config ファイルを使用してデプロイ時に自動的に作成する方法もあります。

ドキュメントでもファイルの作成方法やコマンドの実行方法が紹介されています。

Linux サーバーでのソフトウェアのカスタマイズ - AWS Elastic Beanstalk

今回は container_commands を使用してデプロイ時に EC2 インスタンス内でコマンドを実行し、ディレクトリとファイルを作成します。

まずは .config ファイルを作成します。

$ touch .ebextensions/02html.config

02html.config ファイルに以下の内容を記載します。

02html.config
container_commands:
  createfile:
    command: |
      mkdir /var/www/html/test1
      mkdir /var/www/html/test2
      touch /var/www/html/test1/index.html
      touch /var/www/html/test2/index.html
      echo "<h1>test1</h1>" > /var/www/html/test1/index.html
      echo "<h1>test2</h1>" > /var/www/html/test2/index.html

コマンド内容は以下の通りです。

  • 各サイトごとのディレクトリを作成
  • 各ディレクトリに html ファイルを作成
  • html ファイルに表示する内容を記載

想定する動作は以下の通りです。

  • test1 のサブドメインにアクセス: test1 と表示される
  • test2 のサブドメインにアクセス: test2 と表示される

.config ファイルの処理順序

.config ファイルはアルファベット順に処理されます。

Linux サーバーでのソフトウェアのカスタマイズ - AWS Elastic Beanstalk

指定されたコマンドはルートユーザーとして実行され、名前のアルファベット順に処理されます。

そのため、先に実行したいコマンドがある場合にはファイル名にも注意する必要があります。
今回の場合、Apache への設定変更を先に実行したいので以下のファイル名を指定しています。

  • 01httpd-proxy.config
  • 02html.config

デフォルトで作成されている logging.config については今回は関係ないのでリネームはしていません。

Apache 設定の拡張

Linux 2 環境の拡張に加えて、VirtualHost を利用するためには Apache 設定も拡張する必要があります。
Apache 設定の拡張についてもドキュメントに記載されています。

Elastic Beanstalk Linux プラットフォームの拡張 - AWS Elastic Beanstalk

Elastic Beanstalk のデフォルトの Apache 設定を拡張するには、アプリケーションソースバンドルの .conf というフォルダに .platform/httpd/conf.d 設定ファイルを追加します。Elastic Beanstalk の Apache 設定では、このフォルダに .conf ファイルが自動的に含められます。

Linux 2 環境の拡張と同様に特定のディレクトリの作成とファイルの配置が必要なので、ディレクトリおよびファイルを作成します。

$ mkdir -p .platform/httpd/conf.d
$ touch .platform/httpd/conf.d/virtualhost.conf

virtualhost.conf には Apache のサンプルを参考に作成した以下の内容を記載します。

バーチャルホストの例 - Apache HTTP サーバ バージョン 2.4

virtualhost.conf
<VirtualHost *:80>
  ServerName test1.example.com
  DocumentRoot /var/www/html/test1
</VirtualHost>

<VirtualHost *:80>
  ServerName test2.example.com
  DocumentRoot /var/www/html/test2
</VirtualHost>

想定する動作は前述の通り、アクセスしたサブドメインごとに別のサイトが表示されるという動作です。

デプロイ

各種設定ファイルを eb deploy コマンドで Elastic Beanstalk 環境に反映します。

eb deploy - AWS Elastic Beanstalk

$ eb deploy

~ 以下、デプロイイベントのため略 ~

# 環境の更新が完了すれば OK
2023-10-12 11:17:13    INFO    Environment update completed successfully.

動作確認

デプロイが完了したらルートドメインおよびサブドメインにアクセスします。


想定通りの動作になっていることが確認できました。
なお、ルートドメインおよび Elastic Beanstalk 環境のデフォルトのドメインにアクセスした場合は test1 が表示されます。

この挙動は VirtualHost の仕様である旨が Apache のドキュメントに記載されています。

バーチャルホストの例 - Apache HTTP サーバ バージョン 2.4

アスタリスクはすべてのアドレスにマッチしますので、主サーバは リクエストを扱いません。www.example.com は 最初にあるため、優先順位は一番高くなり、default もしくは primary のサーバと考えることができます。つまり、リクエストが どの ServerName ディレクティブにもマッチしない場合、 一番最初の VirtualHost により扱われます。

EC2 インスタンス内部を確認

Elastic Beanstalk 環境内の EC2 インスタンスに SSH 接続して設定ファイルがデプロイされていることを確認してみます。

SSH 接続するためには eb ssh コマンドを実行します。

eb ssh - AWS Elastic Beanstalk

$ eb ssh
INFO: Running ssh -i /home/ec2-user/.ssh/aws-eb ec2-user@13.115.211.233
The authenticity of host '13.115.211.233 (13.115.211.233)' can't be established.
ECDSA key fingerprint is SHA256:Mrerj/hogehoge.
ECDSA key fingerprint is MD5:xx:xx:xx.
Are you sure you want to continue connecting (yes/no)? yes

Warning: Permanently added '13.115.211.233' (ECDSA) to the list of known hosts.
  _____ _           _   _      ____                       _        _ _
 | ____| | __   ___| |_(_) ___| __ )  ___  __ _ _ __  ___| |_ __ _| | | __
 |  _| | |/ _ \/ __| __| |/ __|  _ \ / _ \/ _\ | '_ \/ __| __/ _\ | | |/ /
 | |___| | (_| \__ \ |_| | (__| |_) |  __/ (_| | | | \__ \ || (_| | |   <
 |_____|_|\__,_|___/\__|_|\___|____/ \___|\__,_|_| |_|___/\__\__,_|_|_|\_\

 Amazon Linux 2 AMI

 This EC2 instance is managed by AWS Elastic Beanstalk. Changes made via SSH
 WILL BE LOST if the instance is replaced by auto-scaling. For more information
 on customizing your Elastic Beanstalk environment, see our documentation here:
 http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html

[ec2-user@ip-172-31-35-48 ~]$ 

SSH 接続すると上記のように ec2-user でコマンドを実行できます。
コマンドを実行してディレクトリやファイルを確認してみます。

# ディレクトリの確認
[ec2-user@ip-172-31-35-48 ~]$ ls /var/www/html
test1  test2

# html ファイルの確認
[ec2-user@ip-172-31-35-48 ~]$ ls /var/www/html/test1 /var/www/html/test2
/var/www/html/test1:
index.html

/var/www/html/test2:
index.html

# html ファイルの内容を確認
[ec2-user@ip-172-31-35-48 ~]$ cat /var/www/html/test1/index.html /var/www/html/test2/index.html
<h1>test1</h1>
<h1>test2</h1>

# virtualhost.conf の確認
[ec2-user@ip-172-31-35-48 ~]$ ls /etc/httpd/conf.d
elasticbeanstalk  virtualhost.conf

[ec2-user@ip-172-31-35-48 ~]$ cat /etc/httpd/conf.d/virtualhost.conf
<VirtualHost *:80>
  ServerName test1.wtankm87.com
  DocumentRoot /var/www/html/test1
</VirtualHost>

<VirtualHost *:80>
  ServerName test2.wtankm87.com
  DocumentRoot /var/www/html/test2
  
# 最後にソースコードなども確認
[ec2-user@ip-172-31-35-48 ~]$ ls -al /var/app/current 
total 24
drwxr-xr-x 3 webapp webapp  133 Oct 12 11:16 .
drwxr-xr-x 3 root   root     21 Oct 12 11:16 ..
-rw-r--r-- 1 webapp webapp 1155 Oct 11 11:59 app.js
-rw-r--r-- 1 webapp webapp   84 Oct 11 11:59 cron.yaml
-rw-r--r-- 1 webapp webapp 3139 Oct 11 11:59 index.html
-rw-r--r-- 1 webapp webapp  154 Oct 11 11:59 package.json
-rw-r--r-- 1 webapp webapp  219 Oct 12 11:16 package-lock.json
drwxr-xr-x 3 webapp webapp   19 Oct 12 11:16 .platform
-rw-r--r-- 1 root   root     14 Oct 12 11:16 Procfile

# SSH 接続終了
$ exit
Connection to 13.115.211.233 closed.

以上で動作確認およびデプロイ資材の確認ができました。

Elastic Beanstalk 環境の終了

参考までに Elastic Beanstalk 環境を終了させるコマンドについても紹介します。

Elastic Beanstalk 環境を終了させるには eb terminate コマンドを実行します。

eb terminate - AWS Elastic Beanstalk

# Elastic Beanstalk アプリケーションも削除したいので --all オプションを付与
$ eb terminate --all
The application "nodejs" and all its resources will be deleted.
This application currently has the following:
Running environments: 1
Configuration templates: 0
Application versions: 2

# Elastic Beanstalk アプリケーション名を入力
To confirm, type the application name: nodejs

~ 以下、終了イベントのため略 ~

# 環境およびアプリケーションが終了すれば OK
2023-10-12 12:09:18    INFO    The application has been deleted successfully.

その他のリソース

今回構築した以下のリソースも不要な場合は削除してください。

  • Cloud9 環境
  • Route 53 のエイリアス
  • SSH 接続用キーペア

まとめ

今回は Elastic Beanstalk 環境に Apache の VirtualHost を構築する方法を紹介しました。
Elastic Beanstalk の拡張機能を使用することで簡単に設定できたので、参考になれば幸いです。

参考資料

Discussion