AWS 構築順序

### 1. アカウント作成
* CloudWatchの設定で請求の見える化
* CloudTrailの設定で、作業ログの見える化

### 2. ルートユーザーとIAMユーザーの作成

### 3. VPCの設定
* VPCでリージョンとアヴェイラビリティゾーン(AZ)を設定
* AZにサブネットを設定（パブリックIPアドレスとプライベートIPアドレスを設定）
* パブリックIPアドレスにWebサーバー、プライベートIPアドレスにMySQLやOSを後ほど設置する。
* パブリックIPアドレスにインターネットから接続できる様にインターネットゲートウェイの設定を行う。
* パブリックIPアドレスにルートテーブルの設定を行う。

### 5. EC2インスタンスを作成し、Apachやファイアーウォールを入れる
#### ssh接続
* ターミナルでssh接続をする。その際、秘密鍵は最初に一度だけ```chmod 600 ~/〇〇/himitsu_key.pem```とし、権限を変更する
接続は```ssh -i /Users/yourname/〇〇/himitsu_key.pem ec2-user@EC2のパブリックIPv4アドレス```
#### アパッチのインストール
* ```sudo yum -y install httpd```でApachをインストール```httpd```がApachのこと
* ```sudo systemctl start httpd.service```でアパッチ起動
* ```sudo systemctl status httpd.service```アパッチの起動確認
その他、```ps -axu```や```ps -axu | grep httpd```でも確認可能
* ```sudo systemctl enable httpd.service```でサーバー起動時にアパッチも起動する様に設定
* ```sudo systemctl is-enabled httpd.service```サーバーの起動を確認

#### ファイアーウォール設定
上記でアパッチをインストールしてもこれだけではwebページへアクセス出来ない。それはアパッチをインストールしただけでは通信がファイアーウォールによって遮断される為。
その為、現状はEC2の「パブリック IPv4 アドレス」を開いても一向に開かれず、読み込み画面がぐるぐるするだけ。
これを解除するために、EC2インスタンスの該当「セキュリティグループ」を確認する。
インバウンドのルールにタイプSSH、ポート範囲22などと記載されている場合、ssh接続以外では接続できない。その為、httpアクセスが出来る様に設定を変える。
インバウンドのルールにHTTPを追加し、ソースの部分は「Anywhere-IPv4」にすると接続可能に。


### 6. Route53
* お名前.com等で独自ドメインを取得する
* Route53で取得したドメインを登録する。
* EC2インスタンスを作成し、ElasticIPを設定しておく
* 作成したEC2インスタンスのパブリックIPアドレスにssh接続する
* ```dig hoge.com NS +short```(hoge.comの部分は自分のドメイン）を実行する。
これによりそのドメインの現在のネームサーバーが確認できる。最初はお名前.comのネームになっている。
これをRoute53へ変更する為に一度お名前.comの管理画面へ戻り、ゾーンの場所を、AWS内へ変更する。
方法は
お名前.comの管理画面からネームサーバーの選択へ行き、デフォルトで「お名前.com」になっている所を「その他のサービス」へ変更し、Route53の自身の登録したドメインのホストゾーンを確認し、NSのタイプの４つの記述をお名前.comのその他のサービス内のネームサーバーに記述する（この設定が完了するまでに24~72時間かかる」
* Aレコードの作成 : Route53のホストゾーンで「レコードセットの作成」を選択し、作成を行う。作成する際にEC２のETCアドレスを指定する。
* ```dig hoge.com NS +short```を再度実行し、お名前.comではなくAWSになっていればOK
* 取得したドメインでURLを叩いて表示されればこれで完了

### 7. RDS設定
1. プライベートサブネット作成（VPC)
2. RDSの作成準備
 - セキュリティグループの作成（EC2)
 - DBサブネットグループの作成
 - DBパラメータグループの作成
 - DBオプショングループの作成
 
3.RDSの作成
 - DBエンジン
 - 本番環境
 - DB詳細の指定
 - [詳細設定]の設定

RDSを作成したらEC2のElasticIPアドレスを使用してssh接続をターミナルから行う。
```sudo yum -y install mysql```を実行し、mysqlをインストールする。
RDSのデータベースから作成したDBのエンドポイントを確認する。
ターミナルに戻って```mysql -h ＜エンドポイント＞ -u root -p```を実行し、RDSを作成した際のパスワードを入力するとmysqlにログイン出来る。
* -h : エンドポイントを指定している
* -u : ログインするユーザーを指定している（rootはマスターユーザーの事RDS作成時に自分でここは設定している）
* -p : これをする事でこの後にパスワード入力が求められる。これをしないと画面上にパスワードが表示される形でログインする事になる
* 

8. WordPressをインストールする
　 1.WPのデータベース作成
   - RDSインスタンスの中にWP用のDB作成
   - 上記で作成したDBに紐づけてMySQLユーザー作成（現状はrootユーザー設定していないので追加設定する）
   - WPの設定
   
#### DB作成
- ETアドレスにssh接続しroot権限でmysqlにログインする
```mysql -h <ETアドレス> -u root -p```
- パスワードを入力しMySQLログイン
*  ```create database aws_and_infra default character set utf8 collate utf8_general_ci;```
上記でDBを作成する。
* ```default character set```でデフォルトの文字コード```utf8```を設定している。
```collate```で文字列の照合順序（比較方法）を指定している。文字コードはutf8、言語は多言語を示す```general```、文字列の比較方法は、大文字と小文字が区別されない```ci```としている。
* ```create user 'aws_and_infra'@'%' identified by '＜パスワード＞';```を実行
```cereate user```でユーザーを作成。```@```以降に指定した```'%'```は接続元のホストを指定しており、%にすると誰でもOKになる。```identified by```で接続時のパスワードを```<パスワード＞```の部分に入れ、設定している。
*  ```grant all on ＜DB名＞.* to '＜ユーザー名＞'@'%';```
グラントコマンドでallを使用し全ての権限をユーザーに渡している
* これだけではまだ権限の設定がMySQLに反映されないので```flush privileges;```を実行する。
* ```select user , host from mysql.user;```を実行し、作成したユーザーが表示されるか確認する。
* 再度mysqlにログインする際にrootではなく作成したユーザー名とパスワードでログイン出来るか確認し、ログインできればOK

##### WPインストール
* ```sudo amazon-linux-extras install -y php7.2```でWPを動かす為に必要なライブラリをインストール
* ```sudo yum install -y php php-mbstring```をPHP関係の必要なライブラリをさらにインストール
* ```cd ~```でホームディレクトリへ移動
* ```wget https://ja.wordpress.org/latest-ja.tar.gz```で最新のワードプレスファイルをダウンロードする
* ```tar xzvf latest-ja.tar.gz```でファイルを解凍して表示する
* ```cd wordpress```でワードプレスディレクトリへ移動する
* ```sudo cp -r * /var/www/html/```WPのプログラムをアパッチから見える様にする
```cp```はコピー。```-r *```は現在のディレクトリ以下全てのディレクトリとファイルを指定。```/var/www/html```はそのパスの直下を指定している。
つまり、これで指定した全てのディレクトリとファイルを/var/www/htmlの直下にコピーしている。
* ```sudo chown apache:apache /var/www/html/ -R```これでWPのファイルの所有者を変更している。
```chown```ファイルの所有者を変更。```apache:apache```ファイルの所有者と所有グループをアパッチに変更。```/var/www/html -R```は/var/www/html以下のディレクトリ、ファイルの全てを対象にすると言う意味。
```sudo systemctl status httpd.service```アパッチの起動状態確認（緑色で「active(running)」なっていれば起動している）。
```sudo systemctl restart httpd.service```でアパッチを再起動させる。
再起動したことでアパッチがwPを参照できる様になる。
**これ以降、ETアドレス（Route53で設定したドメイン）にアクセスすると、ワードプレス画面が表示される。


### WPの設定
データベース名 : ssh接続して作成したDB名
ユーザー名 : 〃　ユーザー名
パスワード : 〃 パスワード
データベースのホスト名 : RDSのコンソール画面の「データベース」の「接続とセキュリティ」内の「エンドポイント」
テーブル接頭辞 : そのまま（wp_)でOK

### 画像の保存場所をS3に設定し、CloudFrontで高速配信する
通常だとWPの画像はサーバー上に保存されてしまう。それだとサーバーの台数を増やす際にスケールアウトが難しくなる。
また、画像とサーバーを分けることでそれぞれにアクセスが分散され、負荷分散になる。

#### S3概要
* バケット
 オブジェクトの保存場所。名前はグローバルで一意である必要がある
* オブジェクト
 データ本体。S3に格納されるファイルであり、URLが付与される。
 バケット内のオブジェクト数は無制限に設定可能
* キー
 オブジェクトの格納URLのパス

#### S3の使用例
* 静的コンテンツの配信
 img画像をS3から配信できる
* ログの出力先
 S3にログを送ることができる
* 静的webホスティング
 HTMLとCSSだけのLP等はS3から公開することができる
* バッチ連携用のファイルの置き場として使用
 S3にCSVファイルなどを置いて、バッチでそのファイルを参照して処理を行える

#### S3バケットの作成
![スクリーンショット 2022-05-01 10.36.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/6a4798ba-472f-29c4-af2f-abbf2cd939e4.png)
上記は「バケット」と「オブジェクト」に外からのアクセスを拒否する為のもの。
外からアクセスされたくないファイルを置く時はチェックをつけておく。
WPに画像を投稿する際の想定だと、Web上に公開して、自分以外の人が見れる様にする必要がある為、全てチェックを外す。
![スクリーンショット 2022-05-01 10.39.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/9de10fc3-45db-0755-2c01-2f56af724159.png)
チェックを外すと上記がひょうじされる。
ここで言っている、「静的ウェブサイトのホスティング」がLPをS3で公開する事などをいう。

#### WPにS3への画像投稿用のプラグインをインストールする
* WPの管理画面で「WP Offload Media Lite for Amazon S3, DigitalOcean Spaces, and Google Cloud Storage」をインストールする。
* サーバーに「WP Offload Media Lite for Amazon S3, DigitalOcean Spaces, and Google Cloud Storage」を使用する為のライブラリが必要なので、インストールする。
* EC2インスタンスのパブリックIPv4アドレスを使用し、ssh接続した後``` sudo yum install -y php-xml```を実行する。
* インストールを反映させる為にアパッチの再起動をする```sudo systemctl restart httpd.service```
ここまで行うとWPの管理画面に「Offload Media Lite」が表示される
![スクリーンショット 2022-05-01 16.10.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/87d7ab45-57e0-47ce-eff0-0f80004d8e5e.png)
* 使用する為にwp-config.phpに
```php
define( 'AS3CF_SETTINGS', serialize( array(
    'provider' => 'aws',
    'access-key-id' => '********************',
    'secret-access-key' => '**************************************',![スクリーンショット 2022-05-01 16.30.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/2c97f86f-4c56-e8bd-2f41-8244e1104bb6.png)

) ) );
		
```
上記を記述する様に記載がある為、ターミナルからwp-config.phpにアクセスする。

```cd /var/www/html/ ```そして```nano wp-config.php```でナノエディタを立ち上げて編集する（vimを使用しても良い）。
上記コードを貼り付ける。
さらに
```php
define( 'AS3CF_SETTINGS', serialize( array(
    'provider' => 'aws',
    'access-key-id' => '********************',
    'secret-access-key' => '**************************************',
) ) );
```
上記の様にアクセスキーとシークレットアクセスキーの設定箇所がある。
ここで、上述でIAMユーザーでS3へアクセスする際のキーをここで入力し、アクセスできる様にする。
変更を保存して、WPの管理画面に戻り「Offload Media Lite」の画面をリロードすると、設定が反映され、次に進める画面になる。
provider: Amazon S3
bucket : 自分で設定したバケット
になっているか確認し、画面下の方に
「Remove Files From Server」という項目がデフォルトでオフになっているので、ONにする。これをONにする事で、サーバーに画像やファイルが保存されなくなる。

ここまで設定すると、WPで画像を投稿した際、保存先がサーバーではなく、S３になる。
#### ※上記ではS3へのアップロードは出来ない。２点追加設定が必要
##### その1
![スクリーンショット 2022-05-01 17.04.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/545412e4-940c-1546-7c89-97918f6dbf36.png)
バケットの「アクセス許可」＞「オブジェクト所有者」を選択し、上記画面にて「ACL有効」にすつひつようがある。
[参考記事](https://zenn.dev/tamago_oic/articles/3d7334546964ee)

##### その２
上記までの設定だと、ssh接続してインストールしたphp関係のデータが

```
php.x86_64                            7.2.34-1.amzn2                 @amzn2extra-php7.2
php-cli.x86_64                        7.2.34-1.amzn2                 @amzn2extra-php7.2
php-common.x86_64                     7.2.34-1.amzn2                 @amzn2extra-php7.2
php-fpm.x86_64                        7.2.34-1.amzn2                 @amzn2extra-php7.2
php-json.x86_64                       7.2.34-1.amzn2                 @amzn2extra-php7.2
php-mbstring.x86_64                   7.2.34-1.amzn2                 @amzn2extra-php7.2
php-mysqlnd.x86_64                    7.2.34-1.amzn2                 @amzn2extra-php7.2
php-pdo.x86_64                        7.2.34-1.amzn2                 @amzn2extra-php7.2
php-xml.x86_64                        7.2.34-1.amzn2                 @amzn2extra-php7.2
```
となっているが、S3への投稿には```php-gd.x86_64 ```が必要の様子
[参考記事](https://hacknote.jp/archives/43851/)
その為、ssh接続して```sudo yum install php-gd.x86_64 ```を実行
その後```sudo systemctl restart httpd.service```でアパッチを再起動後、投稿がS3へされる様になった。

#### CloudFlont
* ディストリビューションとはクラウドフロントのルールのこと。最初にこれを設定する
初期の状態だと画像を配信するドメインがお名前.comで取得した独自ドメインではなく、CloudFlontのドメインになっている為、以下で変更していく（機能的にはこのままで問題はないので、独自ドメインに設定することは必須ではない。但しSEO的には画像とのドメインとサイトのドメインは同じ方が良い）。
独自ドメインを使用しない場合、ディストリビューションの設定をしただけで、画像はCloudFlontから配信される様になる。

#### CloudFlontの独自ドメインの設定とAMCでのSSL証明書取得
* 作成したディストーションの編集画面へ移動する。
![スクリーンショット 2022-05-01 18.28.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/247ecbbf-0e35-106a-3410-815895daa1d8.png)
* 代替ドメイン名にCloudFlontから画像を配信したいドメインを設定する（自身の独自ドメイン(hoge.com)やそのサブドメイン（static.hoge.com)等を設定するとよい）。
* 「証明書をリクエスト」を選択すると別タブが起動しACM（AWS Certificate Manager）の設定画面が表示されるので、ここでSSL証明書を作成する。。
![スクリーンショット 2022-05-01 18.36.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/2ef23643-b0f0-6829-0f66-d03bbd0c5a77.png)
「完全修飾ドメイン名」にはサブドメイン（site.hoge.comやshop.hoge.comなど)をせっていしても平気な様に「*.」を頭につけている。
その後追加でhoge.comを指定している。

* 検証方法を選択
土面の所有権を検証する方法 : 今回リクエストしたお名前.comで取得したドメイン(hoge.com)を確かに所有していることの確認をする方法。
基本は独自ドメインを取っていればDNS検証でOK。
「りクエスト」を選択すると、次の画面で指定したドメインのステータスが「検証中」になる。これを承認させる為にさらに設定をする必要がある。
![スクリーンショット 2022-05-01 21.15.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/f616bea2-1be8-1e6d-bd8a-7b445ecca97e.png)

DNSの設定をRoute53でやっているので、「Route53でレコードを作成」から設定する。
レコードの作成が成功してもしばらくステータスが検証中になる。**数分〜30分で発行済みになる**。
[参考記事](https://zenn.dev/mn87/articles/90609fffd8c634)

#### 改てCloudFlontの設定を再開
CFのディストリビューションから先ほどの使用していたディストリビューションを選択する。
* 「全てのエッジロケーションの使用」
* 代替ドメイン名を自身の独自ドメイン or サブドメインと独自ドメインを指定
* カスタムSSL証明書は先ほど作成したものがセレクトボックスから選択できる
* その他の設定は基本そのまま
* これで「変更を保存」する
そうするとディストリビューション一覧の最終変更日のところが「デプロイ 」になる。
**ディストリビューションドメイン名**の項目に記載の```〇〇.net```がCFのドメイン名。今回これが代替ドメイン名に差し替えされるイメージ。
実際S3へ投稿した画像のパスが代替ドメイン名になるには**後2つ設定事項がある**。

1. Route53に代替ドメイン名がディストリビューションドメイン名の別名（CNAME）である事を設定する。
2. WPのOffload Media Lite に画像投稿をした際のドメイン名を代替ドメインになる様に設定する。それにより、画像投稿時のURLがディストリビューションドメイン名ではなく代替ドメインになる。

##### 1. Route53の設定
* Route53のホストゾーンを開く
* hoge.comを選択
* レコードセットの作成を選択
<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/94ce9cb6-0915-34e6-05ab-a662ea12d029.png' width='400'>

名前 : site.hoge.co.jpであれば「site」のみを記述。
タイプ : CNAME -正規名
値 : CFのディストリビューションドメイン名をコピーして貼り付ける
ルーティングポリシー : シンプル

##### 2. WPの設定
[参考](https://djent.jp/web/wp-s3-domain-ssl/)
WP管理画面の設定から「Offload Media Lite」を開く
![スクリーンショット 2022-05-01 22.24.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/6461bed6-a063-7849-53fc-5407147ccaff.png)
デフォルトでは「DELIVERY」が```Amazon A3```になっているので、changeを選択し、```Cloud　Front```にする。
![スクリーンショット 2022-05-01 22.24.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/3d394566-1bbb-3574-0d38-91a48879212e.png)
するとCustom Domain(CNAME)が表示されるので、ここでRoute53で設定した代替ドメインの```static.hoge.com```を設定する。

これで設定は終了
※　画像投稿後、「画像にalt属性が指定されていません」と出る時がある。サブドメインの設定が悪いのか、検証中。



### AWS Certificate Manager
[AWS Certificate Manager : 公式](https://aws.amazon.com/jp/certificate-manager/)
> AWS Certificate Manager は、AWS のサービスとお客様の内部接続リソースで使用するパブリックとプライベートの Secure Sockets Layer/Transport Layer Security (SSL/TLS) 証明書のプロビジョニング、管理、デプロイを簡単にします。SSL/TLS 証明書は、ネットワーク通信を保護し、プライベートネットワークのリソースと同様にインターネットで Wウェブサイトのアイデンティティを確立するために使用されます。AWS Certificate Manager を使用すれば、SSL/TLS 証明書の購入、アップロード、更新という時間のかかるプロセスを手動で行う必要がなくなります。

>AWS Certificate Manager なら、証明書をすばやくリクエストして、Elastic Load Balancing、Amazon CloudFront ディストリビューション、Amazon API Gateway の API など ACM に統合された AWS リソースでデプロイできます。また、 AWS Certificate Manager で証明書の更新もできます。また内部リソースのためのプライベート証明書を作成し、証明書ライフサイクルを集中的に管理することも可能になります。
```ACM 統合サービスのために AWS Certificate Manager でプロビジョニングされたパブリック証明書やプライベート証明書は、無料です。お支払いいただくのは、アプリケーションを実行するために作成した AWS リソースの料金のみです。AWS Certificate Manager Private Certificate Authority (CA) を使用する場合は、プライベート CA のオペレーションとお客様の発行するプライベート証明書に対して、月額料金をお支払いいただきます```。

#### ACMの料金
> 請求
> Q: ACM 証明書の使用に対する課金と請求は、どのように行われますか?

> AWS Certificate Manager でプロビジョンされたパブリック証明書とプライベート証明書で、Elastic Load  Balancing、Amazon CloudFront、Amazon API Gateway サービスなどの ACM 統合サービスだけで使われるものは無料です。
お支払いいただくのは、アプリケーションを実行するために作成した AWS リソースの料金です。
AWS Certificate Manager プライベート認証機関は、従量制料金です。各 ACM プライベート CA のオペレーションについては、削除するまで月額料金がかかります。また、自身で作成または ACM からエクスポートしたプライベート証明書についても料金が発生します。これは、EC2 やオンプレミスサーバーの証明書、自身でプライベートキーを作成してプライベート CA から直接発行した証明書などが該当します。詳細と例については、料金表のページをご参照ください。
>
[AWS Certificate Manager のよくある質問](https://aws.amazon.com/jp/certificate-manager/faqs/)
[AWS Certificate Manager の料金](https://aws.amazon.com/jp/certificate-manager/pricing/)
[参考記事](https://zenn.dev/sasumasa/articles/e6a2c97dbf1203)




### 詰まったところ
ACMの証明書発行の時に、```*.hoge.com```と```hoge.com```を同時に設定する必要があり、その証明書発行が承認された後、CFでその証明書を選択。次にRoute53のホストゾーンでレコードセットの作成でCNAME: ```static.hoge.com```をするという流れが正しいが。
上記を最初```*.hoge.com```を使用せず、```hoge.com```のみで証明書を発行。その証明書をCFに登録。Route53にもCNAMEをhoge.comのみで登録しようとしたらエラーになって登録できなかった。



### 基本
* パブリックサブネット : WordPressを設置しする場所でインターネットから閲覧できる場所
* プライベートサブネット : MySQLやOSを設置する場所でインターネットから閲覧できない場所