WordpressをEC2で構築したときのAutoScaling環境におけるサーバ間コンテンツ同期について

# 対応にあたる経緯
### :one: 業務で複数のサイトをEC2＋ALB＋RDSという構成で運用管理をしているのですが、構築されるサイトがとても多くなってきており、負荷が高くなってきた :sweat_drops: 
### :two: 今後も構築するサイトが増えていくことが想定されるなかで、特定のサイトでのスパイクがあった場合に他のサイトへも影響を与えてしまい、運用品質が悪くなってくることが想定された :thinking: 
### :three: 今のインスタンスが死ぬと全サイトが一気に死ぬので、はっきり言ってちょーやばい状態だった :exclamation: :exclamation: :exclamation: :exclamation: 

# AutoScaling導入にあたり同期方法の考察
## :exclamation: 注意 :exclamation: 
下記は全て対応時に調査した参考サイトからの情報や自分で軽く検証してみて検討した結果です。
特定の条件下において検討した結果の考察となっているので、実際に自分のサイトへ導入するのは自己責任でお願いします :bow: :bow: :bow: 

## :x: 【不採用】Lsyncd+rsync
- configファイル内部にIPアドレスを持つしかなさそう・・・ :sweat: だが、AutoScalingと相性悪いので<font color="Red">不採用</font>

## :x: 【不採用】最新AMIを取得して入れ替え
- コンテンツ反映がリアルタイム性に欠けるので、<font color="Red">不採用</font>

## :x: 【不採用】EFSマウントして同期
- 期待されてたみたいだが、調べてみると遅いらしいので<font color="Red">不採用</font>

## :x: 【不採用】s3fsとかgoofysとかでS3マウント
- ベンチマークとってる記事とか結構あがってるがEFSマウントと同じようにやっぱり少し遅いみたいなので、<font color="Red">不採用</font>

## :small_red_triangle: 【一部採用】aws s3 syncでの同期
- 調査するとCronとか仕込んで、起動時と定期実行で他のサーバへ同期を実行するこのパターンが多かった :eyes: 
- この方法で検証したが、保持しているサイト数とコンテンツ数が多く、完了まで時間がかかることもあり、設定した **定期実行** の実行間隔で同期が完了できるかわからない :cry: 
- 加えて、この方法はコマンド実行時のCPUへの負荷がやばり :sweat_drops: :sweat_drops: :sweat_drops: ため、<font color="Red">不採用</font>
- しかし、スケールアウトしたインスタンスの起動時のコンテンツ同期には利用するため<font color="Red">一部採用</font>

## :o: 【採用】Lsyncd -> S3 -> Lambda -> System Manager(Run Command) -> aws cp or rm で変更のあったファイルのみ反映
- Lsyncdでファイル更新・削除があった場合にS3へ該当ファイルを上書きアップロード
    - Lsyncdもファイルアップロードの成功、失敗の可視性が悪いので、 `lsyncd.log` をDatadogに転送するか検討中 :thinking: 
- S3のオブジェクト作成 or 削除イベントを発生させ、Lambda起動
- Lambdaにて、System Manager(Run Command)を実行し、成功、失敗が画面 or CloudWatch Logsでわかるように実装

# :sweat_drops: はまったとこ
- とりあえず既存インスタンス内部のコンテンツを全てS3にアップロードするだけで結構時間かかった・・・(これだけで２日くらいかかってる :question:) :sweat: 
- S3のオブジェクトからLambda起動してSystem Manager(Run Command)が動かない :question: :question: :question: 
    - インスタンス自体がPublicサブネットで動作してるのでAutoScalingしてもパブリックサブネットで起動させながらも起動したインスタンスにはGIPがないためにインターネット疎通が取れないこともあり、実行してもどこにもログがでない＆タイムアウトしてるとかで原因がわかりにくすぎて辛かったｗ
    - PrivateサブネットならNATゲートウェイあるからGIPは存在するので、Lambda自体の起動はそっちに変更して試したが、それでも動かず、、、 :sweat: 
    - VPCのPrivate Linkで s3,ssmのエンドポイント作って、ルートテーブルにも反映させてゴリゴリ試したらうまくいった :exclamation: 

# 環境整備にあたりインストールしたモジュール
## 取り急ぎ、aws-cliは必要になりそうだったので、導入

```
# 新しめのaws-cliをインストールするためにPython3.x系をインストールしていく
$ sudo yum list installed | grep python

# 既存のPython2.6もアップデートしてみた
$ sudo yum update python python-* audit-libs-python libselinux-pythonlibsemanage-python libxml2-python newt-python policycoreutils-python rpm-python setools-libs-python

# ベースサーバがCentOSなので下記のRPMをインストール
$ sudo yum install -y https://centos6.iuscommunity.org/ius-release.rpm

# Python3.6系のインストール
$ sudo yum install -y python36 python36-debug python36-devel python36-gunicorn python36-idle python36-libs python36-lxml python36-mod_wsgi python36-pip python36-redis python36-setproctitle python36-setuptools python36-test python36-tkinter python-rpm-macros python-srpm-macros python3-rpm-macros

# シンボリックリンクはる
$ sudo ln -s /usr/bin/python3.6 /usr/bin/python3
$ sudo ln -s /usr/bin/pip3.6 /usr/bin/pip3

# これが必要らしいので実行したが、これをやるとインストールしたpipが動かなくなる 
$ sudo python3 -m ensurepip --upgrade

# だからインストールしなおす
$ sudo yum remove -y python36-pip
$ sudo yum install -y python36-pip

# 再実行
$ sudo python3 -m ensurepip --upgrade

# シンボリックリンクはる
$ sudo ln -s /usr/bin/pip3.6 /usr/bin/pip3
$ sudo python3 -m pip install --upgrade pip
$ sudo ln -s /usr/bin/pip3.6 /usr/bin/pip3

# キャッシュ？が残るらしいのでこれ叩く
$ hash -r
$ pip3 --version

# aws-cliインストール
$ sudo /usr/local/bin/pip3 install awscli
$ sudo /usr/local/bin/pip3 install awscli --upgrade
$ aws --version

# S3にアクセスできるか確認
$ aws s3 ls s3://prd-example.com-wp

# S3にコンテンツ同期する
$ sudo /usr/local/bin/aws s3 sync s3://prd-example.com-wp /var/www/html/

# SSM-Agentインストール　※今後のNoOpsでの運用のためにも
$ sudo yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm

# Linux インスタンスの SSM エージェント ログは以下の場所で確認できます。
$ sudo less /var/log/amazon/ssm/amazon-ssm-agent.log
$ sudo less /var/log/amazon/ssm/errors.log
```

# 参考サイト
**※皆さまよりご提供いただいた情報のおかげです！ ありがとうございますｍｍ**
- [AutoScaling環境においてGitを使わないでEC2を冗長化する方法 - Qiita](https://qiita.com/unoemon/items/2301d49c1200083379d6)
- [AWS CLI のインストール - AWS Command Line Interface](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-install.html)
- [AWS CLI をインストールする - Qiita](https://qiita.com/mokuo/items/0484feefbaddb70a9b06)
- [～AutoScalingのコンテンツ同期～ | ナレコムAWSレシピ](https://recipe.kc-cloud.jp/archives/8652)
- [S3 sync で s3からファイルを同期させる時の注意点 ｜ Developers.IO](https://dev.classmethod.jp/cloud/aws/s3-sync-exact-timestamps/)
- [Python3.6 インストール on Amazon Linux AMI - Qiita](https://qiita.com/hitobb/items/62bcd1c4995d996d4652)
- [CentOS6系にpython3をインストール - ていちゅらの備忘録](http://teityura.wjg.jp/engineer/centos6%E7%B3%BB%E3%81%ABpython3%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)
- [s3 sync uses high CPU when wrapped with trickle to limit bandwidth · Issue #1078 · aws/aws-cli](https://github.com/aws/aws-cli/issues/1078)
- [Amazon EC2 Linux インスタンスに SSM エージェント を手動でインストールする - AWS Systems Manager](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/sysman-manual-agent-install.html#agent-install-centos)
- [Amazon S3 データ転送を最適化する](https://aws.amazon.com/jp/premiumsupport/knowledge-center/s3-optimize-transfer/)
- [AWS CLI S3 Configurationを試したら想定以上にaws s3 syncが速くなった話 ｜ Developers.IO](https://dev.classmethod.jp/cloud/aws/aws-s3-sync-with-aws-cli-s3-configuration/)
- [\[AWS\]lsyncdでEC2のディレクトリとS3を同期する\[Linux\] | 自動化について考えた](https://allautoengr.com/aws-lsyncd-ec2-s3/)
- [ファイルをsftp経由でEC2にアップロード→lsyncdでS3へのアップロード連携を行う ｜ Developers.IO](https://dev.classmethod.jp/cloud/aws/file-upload-to-s3-from-ec2-using-sftp/)
- [AWS CLI S3でパフォーマンスが出ないときの対処法 | 社内SEのITメモブログ](https://notepad-blog.com/content/77/)
- [AWSでS3の利用料を節約するためにやって置いた方がよいこと](https://public-cloud-pci-dss.jp/aws/200/)
- [amazon web services - AWS S3 Sync very slow when copying to large directories - Stack Overflow](https://stackoverflow.com/questions/41836439/aws-s3-sync-very-slow-when-copying-to-large-directories)
- [CentOSでlsyncdを使ってファイルを同期する - Qiita](https://qiita.com/trisland/items/09ad116b6a477d979f53)
- [AWS CLIがS3とのトラフィックを帯域制御できるようになりました ｜ Developers.IO](https://dev.classmethod.jp/cloud/aws/rate-limit-aws-cli-s3-transfer/)
- [goofysを使ってAmazon LinuxにS3をマウントする。 - Qiita](https://qiita.com/kooohei/items/a14f22cb0381342d1861)
- [プライベートサブネットに配置したEC2にAWS Systems Manager Session Managerを使ってアクセスする ｜ Developers.IO](https://dev.classmethod.jp/cloud/ssm-session-manager-private/)
- [Systems Manager Run Command をプライベートサブネット上の EC2インスタンスに対して実行する手順と注意点 ｜ Developers.IO](https://dev.classmethod.jp/cloud/aws/ssm-run-command-on-purivate-subnet/)
- [AWS Lambda functionと EC2 Run Commandで、かんたんSlash Commandデプロイ - Qiita](https://qiita.com/terukizm/items/6d5d3ad4bf7e82c193a3)