【AWS】実務でEC2にLAMP環境を構築した流れをザックリかつわかりやすくまとめた

## はじめに
最近、実務でAWS（EC2）にCakePHP用の開発環境を構築するタスクを担当したので、その時に行ったざっくりした作業の流れをまとめておきます。

※著者の業務での構築手順・仕様なのでこれがデファクトスタンダード・ベストプラクティスではないと思います。
※あくまで一例として読んでいただければ嬉しいです
※新規開発ではなく現行環境のリプレイスです

## 構築する環境

||種類|バージョン等|
|:--:|:--:|:--:|
|OS|Linux|Amazon Linux 2|
|Webサーバー|Apache|2.4.46|
|DBサーバー|MariaDB|10.2.10|
|アプリケーション|PHP|5.4.16|

※あとはmemcachedも

## AWS（EC2）で環境構築するざっくりした流れ
### VPCを作成
VPCはAWS上で仮想化されたネットワークのこと。
このネットワークを介してEC2やRDSなどをインターネットなどと通信する。
AWSで作業する際にまずVPCの作成から始める。

### サブネットを作成
サブネットはVPCを細かく区切ったネットワーク。
弁当箱全体を`VPC`とするとご飯スペース、おかずスペースがそれぞれ`サブネット`、みたいなイメージだと思います。

VPCをサブネットに分けるメリット
- 冗長化：サブネット異なるアベイラビリティゾーンに配置することができる
- セキュリティ向上：インターネットに接続しないサブネットを作ることができる

開発環境ということで今回はパブリックサブネットを１つだけ作成し、そこにEC2インスタンスを立てて`Apache`、`MariaDB`、`PHP`をインストールしていきます。

※本来はプライベートサブネットにEC2やRDSを配置して、インターネットとのやりとりはロードバランサーが担当するのが好ましい（らしい）です。
（会社によりけりなのかもしれないので間違ってたらすみません）

### ルーティングを作成
デフォルトではサブネットはインターネットに接続できないので、インターネットに接続するためにルーティングを設定する。

- インターネットゲートウェイ（IGW）を作成
- インターネットゲートウェイを作成したVPCにアタッチする
- ルートテーブルを作成
- ルートテーブルをパブリックサブネットにも関連づける
- ルートテーブルのデフォルトルート（0.0.0.0）をインターネットゲートウェイに設定する

## Webサーバーを構築する／EC2
### EC2
- Elastic Compute Cloudの略
- AWSクラウド上の仮想サーバー
- インスタンス＝EC2から立てられたサーバー

### EC2インスタンスを設置する

- AMI（OSのイメージ）の選択
- インスタンスタイプの選択
- ストレージの追加
- セキュリティグループの設定
- SSHキーペアの設定

セキュリティグループはインバウンドルールは以下のポート番号を設定する

- 22：SSH用
- 80：HTTP用
- 443：HTTPS用

※許容するIPアドレスは会社・プロジェクトによりけり

## Elastic LPをEC2インスタンスに割り当てる

デフォルトのIPアドレスはEC2インスタンスが起動／停止する度にパブリックIPが変更されてしまうので、Elastic IPで固定化する

## EC2にSSH接続する
まず、秘密鍵の権限を変更する

```
$ chmod 600 {秘密鍵のパス}/{秘密鍵の名前}.pem
```

EC2にSSH接続する

```
ssh -i {秘密鍵のパス}/{秘密鍵の名前}.pem ec2-user@{パブリック IPv4 アドレス}
```
{パブリック IPv4 アドレス}はAWSマネージメントコンソール上から確認できます。

```
The authenticity of host '{パブリック IPv4 アドレス}' can't be established.
（略）
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '{パブリック IPv4 アドレス}' (ECDSA) to the list of known hosts.

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
2 package(s) needed for security, out of 5 available
Run "sudo yum update" to apply all updates.
[ec2-user@{プライベートIP} ~]$
```
こうなったら接続成功。

＜補足＞
`.ssh/config`に色々定義すればもっと簡単なコマンドでSSH接続できます。

```
HOST {任意の名前}
  HOSTNAME {EC2のパブリックIPアドレス}
  User ec2-user
  Port 22
  IdentityFile {秘密鍵のパス}/{任意の名前}.pem
```

この設定をすれば以下コマンドでEC2にSSH接続できる

```
$ ssh {HOSTの右に書いた任意の名前}
```
EC2に限らず使えるので便利。

## root権限でコマンドを実行できるようにする

```
$ sudo -i
```

これはしなくても良いけどこの後のコマンド全ての頭に`sudo`をつける必要があります。

## yumのアップデート

```
$ yum update -y
```

## Apacheのインストール

インストールできるApacheのパッケージ確認（しなくてもOK）

```
$ yum list | grep httpd24
```

Apacheインストール

```
$ yum -y install httpd
```

Apacheバージョン確認

```
$ httpd -v
Server version: Apache/2.4.46 ()
```

Apacheの設定ファイル（`httpd.conf`）の確認

```
$ cat /etc/http/conf/httpd.conf
```

Apacheの起動

```
$ systemctl start httpd.service
```

＜補足＞

```
Apacheの起動
$ systemctl start httpd.service

Apacheが起動しているか確認
$ systemctl status httpd.service

Apacheの自動起動設定
$ systemctl enable httpd.service

Apacheの自動起動設定ができているか確認
$ systemctl is-enabled httpd.service
「enable」と表示されればOK
```

## PHPインストール
### PHP7系をインストールする方法
インストールできるバージョンを確認

```
$ amazon-linux-extras | grep php
 15  php7.2                   available    \
 17  lamp-mariadb10.2-php7.2  available    \
 31  php7.3                   available    \
 42  php7.4                   available    [ =stable ]
```

PHP7.4をインストール

```
$ amazon-linux-extras install php7.4
```

PHPのバージョン確認（インストールの確認）

```
$ php -v
PHP 7.4.9 (cli) (built: Aug 21 2020 21:45:11) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
```

これでPHP7系のインストール完了。

参考：[AWS EC2にPHP7.4をインストールする](https://px-wing.hatenablog.com/entry/2020/09/23/081355)

### 古いバージョンのPHPをインストールする方法
プロジェクトの都合上、PHP5.4.16をインストールする必要があったのでこちらも記録に残します。

インストールできるPHPのパッケージを確認

```
$ yum list | grep php
graphviz-php.x86_64                    2.30.1-21.amzn2.0.1            amzn2-core
php.x86_64                             5.4.16-46.amzn2.0.2            amzn2-core
php-bcmath.x86_64                      5.4.16-46.amzn2.0.2            amzn2-core
php-cli.x86_64                         5.4.16-46.amzn2.0.2            amzn2-core
...（略）
```

PHPインストール

```
$ yum -y install php
```

PHPのバージョン確認（インストールの確認）

```
$ php -v
PHP 5.4.16 (cli) (built: Oct 31 2019 18:34:05)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies
```

### PHP関連のパッケージをインストール（必要に応じて）
PHP関連のパッケージインストール

```
$ yum install -y php-cli php-mysqlnd php-gd ...（略）
```

インストールされたPHP関連のパッケージを確認

```
$ yum list installed | grep php
php.x86_64                            5.4.16-46.amzn2.0.2            @amzn2-core
php-cli.x86_64                        5.4.16-46.amzn2.0.2            @amzn2-core
...（略）
```

１つ前のインストールコマンドで指定したパッケージが表示されればOK

## MariaDBインストール
インストール可能なMariaDB関連のパッケージを確認

```
$ yum list | grep mariadb
mariadb-libs.x86_64                    1:5.5.68-1.amzn2               installed
mariadb.x86_64                         1:5.5.68-1.amzn2               amzn2-core
mariadb-bench.x86_64                   1:5.5.68-1.amzn2               amzn2-core
mariadb-devel.x86_64                   1:5.5.68-1.amzn2               amzn2-core
mariadb-embedded.x86_64                1:5.5.68-1.amzn2               amzn2-core
mariadb-embedded-devel.x86_64          1:5.5.68-1.amzn2               amzn2-core
mariadb-libs.i686                      1:5.5.68-1.amzn2               amzn2-core
mariadb-server.x86_64                  1:5.5.68-1.amzn2               amzn2-core
mariadb-test.x86_64                    1:5.5.68-1.amzn2               amzn2-core
```

インストールしたい`10.2.10`のバージョンではなく`5.5.68`になっている。

以下コマンドを実行

```
$ amazon-linux-extras list | grep php
 15  php7.2                   available    \
 17  lamp-mariadb10.2-php7.2  available    \
 31  php7.3                   available    \
 42  php7.4                   available    [ =stable ]
```

`lamp-mariadb10.2-php7.2`を有効（enable）にする

```
$ amazon-linux-extras enable lamp-mariadb10.2-php7.2
```

もう一度確認

```
$ amazon-linux-extras list | grep php
 15  php7.2                          available    \
 17  lamp-mariadb10.2-php7.2=latest  enabled      \
  _  php7.3                          available    \
  _  php7.4                          available    [ =stable ]
```

この状態で再度、インストール可能なMariaDB関連のパッケージを確認

```
$ yum list | grep mariadb
...（略）
mariadb.x86_64                         3:10.2.10-2.amzn2.0.3          amzn2extra-lamp-mariadb10.2-php7.2
mariadb-backup.x86_64                  3:10.2.10-2.amzn2.0.3          amzn2extra-lamp-mariadb10.2-php7.2
mariadb-bench.x86_64                   3:10.2.10-2.amzn2.0.3          amzn2extra-lamp-mariadb10.2-php7.2
mariadb-common.x86_64                  3:10.2.10-2.amzn2.0.3          amzn2extra-lamp-mariadb10.2-php7.2
mariadb-config.x86_64                  3:10.2.10-2.amzn2.0.3          amzn2extra-lamp-mariadb10.2-php7.2
mariadb-connect-engine.x86_64          3:10.2.10-2.amzn2.0.3          amzn2extra-lamp-mariadb10.2-php7.2
mariadb-cracklib-password-check.x86_64 3:10.2.10-2.amzn2.0.3          amzn2extra-lamp-mariadb10.2-php7.2
mariadb-devel.x86_64                   3:10.2.10-2.amzn2.0.3          amzn2extra-lamp-mariadb10.2-php7.2
mariadb-embedded.x86_64                3:10.2.10-2.amzn2.0.3          amzn2extra-lamp-mariadb10.2-php7.2
mariadb-embedded-devel.x86_64          3:10.2.10-2.amzn2.0.3          amzn2extra-lamp-mariadb10.2-php7.2
mariadb-errmsg.x86_64                  3:10.2.10-2.amzn2.0.3          amzn2extra-lamp-mariadb10.2-php7.2
mariadb-gssapi-server.x86_64           3:10.2.10-2.amzn2.0.3          amzn2extra-lamp-mariadb10.2-php7.2
mariadb-libs.i686                      1:5.5.68-1.amzn2               amzn2-core
mariadb-libs.x86_64                    3:10.2.10-2.amzn2.0.3          amzn2extra-lamp-mariadb10.2-php7.2
mariadb-oqgraph-engine.x86_64          3:10.2.10-2.amzn2.0.3          amzn2extra-lamp-mariadb10.2-php7.2
mariadb-rocksdb-engine.x86_64          3:10.2.10-2.amzn2.0.3          amzn2extra-lamp-mariadb10.2-php7.2
mariadb-server.x86_64                  3:10.2.10-2.amzn2.0.3          amzn2extra-lamp-mariadb10.2-php7.2
mariadb-server-galera.x86_64           3:10.2.10-2.amzn2.0.3          amzn2extra-lamp-mariadb10.2-php7.2
mariadb-server-utils.x86_64            3:10.2.10-2.amzn2.0.3          amzn2extra-lamp-mariadb10.2-php7.2
mariadb-sphinx-engine.x86_64           3:10.2.10-2.amzn2.0.3          amzn2extra-lamp-mariadb10.2-php7.2
mariadb-test.x86_64                    3:10.2.10-2.amzn2.0.3          amzn2extra-lamp-mariadb10.2-php7.2
mariadb-tokudb-engine.x86_64           3:10.2.10-2.amzn2.0.3          amzn2extra-lamp-mariadb10.2-php7.2
...（略）
```

バージョン`10.2.10`がインストール可能になっているのでMariaDBをインストール

```
$ yum -y install mariadb
```

MariaDBバージョン確認（インストールの確認）

```
$ mysql --version
mysql  Ver 15.1 Distrib 10.2.10-MariaDB, for Linux (x86_64) using  EditLine wrapper
```

必要に応じてMariaDB関連のパッケージをインストール

```
$ yum install -y php-cli mariadb-backup mariadb-common ...（略）
```

インストールされたMariaDB関連のパッケージを確認

```
$ yum list installed | grep mariaDB
jemalloc.x86_64                       3.6.0-1.amzn2.0.1              @amzn2extra-lamp-mariadb10.2-php7.2
mariadb.x86_64                        3:10.2.10-2.amzn2.0.3          @amzn2extra-lamp-mariadb10.2-php7.2
mariadb-backup.x86_64                 3:10.2.10-2.amzn2.0.3          @amzn2extra-lamp-mariadb10.2-php7.2
mariadb-common.x86_64                 3:10.2.10-2.amzn2.0.3          @amzn2extra-lamp-mariadb10.2-php7.2
...（略）
```

１つ前のインストールコマンドで指定したパッケージが表示されればOK

参考：[AWSでWeb開発環境構築　その5：MariaDBをセットアップ](https://www.51weblab.jp/cloud/aws-webdev-05/)


MariaDB起動

```
$ systemctl start mariadb
```

MariaDBの初期設定（セットアップ？）

```
$ mysql_secure_installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user.  If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none):
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

Set root password? [Y/n] y
New password:
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
 ... Success!


By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] y
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!
```

MariaDBに接続

```
$ mysql -u root -p
Enter password:{パスワードを打ち込む}
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 437
Server version: 10.2.10-MariaDB MariaDB Server

Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>
```

＜補足＞

```
MariaDB状態確認
$ systemctl status mariadb

MariaDB自動起動設定
$ systemctl enable mariadb

MariaDB自動起動設定ができているか確認
$ systemctl is-enabled mariadb
「enable」と出ればOK
```

## memcachedインストール

インストール可能なmemcached関連のパッケージを確認

```
$ yum list | grep memcached
libmemcached.i686                      1.0.16-5.amzn2.0.2             amzn2-core
libmemcached.x86_64                    1.0.16-5.amzn2.0.2             amzn2-core
libmemcached-devel.x86_64              1.0.16-5.amzn2.0.2             amzn2-core
memcached.x86_64                       1.4.15-10.amzn2.1.2            amzn2-core
memcached-devel.x86_64                 1.4.15-10.amzn2.1.2            amzn2-core
php-pecl-memcached.x86_64              3.0.4-3.amzn2.0.1              amzn2extra-lamp-mariadb10.2-php7.2
python-memcached.noarch                1.48-4.amzn2                   amzn2-core
```

今回インストールしたい`1.5.17`がない。
amazon-linux-extrasの方も確認

```
$ amazon-linux-extras list | grep memcached
  3  memcached1.5                    available    \
```

memcachedインストール

```
$ amazon-linux-extras install -y memcached1.5
```

memcachedバージョン確認（インストールの確認）

```
$ yum list installed | grep memcached
memcached.x86_64                      1.5.17-1.amzn2.0.1             @amzn2extra-memcached1.5

もしくは

$ memcached -h
memcached 1.5.17
...（略）
```

memcached起動

```
$ sudo service memcached start
```

＜補足＞

```
memcached自動起動設定（どちらでも良い）
$ systemctl enable mariadb
$ sudo chkconfig memcached on

memcached自動起動設定ができているか確認
$ systemctl is-enabled memcached
「enable」が出ればOK

memcached再起動
$ sudo service memcached restart
```

## 参考で知っておいた方が良い（と思った）知識・コマンド

### EC2（AWS）
- amazon-linux-extras
amazon-linux-extras とは、Amazon Linux 2 インスタンスにある PHP、Python、Golang、MariaDB などのパッケージをより新しいバージョンで利用できるようマネジメント管理するコマンド

- yum
LinuxのRedHat系ディストリビューション（CentOSやFedoraなど）で利用されるパッケージ管理ツール

＜参考＞
- [Amazon Linux 2 を実行している EC2 インスタンスに Extras Library からソフトウェアパッケージをインストールする方法を教えてください。](https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-install-extras-library-software/)
- 参考：[AWS EC2 の amazon-linux-extras の話](https://hapicode.com/server/aws-amazon-linux-extras.html)

### CloudWatch(AWS）

CloudWatchを使用することで、簡単にEC２インスタンスの自動起動・停止を設定することができます。
僕は以下の記事を参考に設定しました。

＜参考＞
- [[AWS] CloudWatchでEC2の自動起動・停止をスケジュールする](https://agohack.com/scheduled-start-and-stop-ec2-with-aws-cloudwatch-event/)
- [CloudWatch Eventsを使ってEC2を自動停止する](https://tech-dive.xyz/2018/11/15/post-98/)

### Apache
- Apacheの設定ファイル（http.conf）で間違っている箇所を特定

```
$ sudo service httpd configtest
```

### MariaDB（MySQL）

- ユーザーとホストを一覧表示

```
SELECT Host, User FROM mysql.user;
```

- ユーザー作成

```
create user {ユーザー名}@{ホスト名} identified by '{パスワード}';
```

- データベースを一覧表示

```
show databases;
```

- ユーザーの権限を表示

```
show grants for {ユーザー名}@{ホスト名};
```

## さいごに

これで一通りのEC2にLAMP環境の構築ができるはずです。
（DBはMySQLの方が多いと思いますが...）

業務の都合上、古いバージョンのミドルウェアをインストールする必要があったのですが、新しいバージョンをインストールする場合はもう少しシンプルな作業になるかなと思いました。