WordPressのuploadsディレクトリを複数のEC2インスタンスで共有するために前回はS3をgoofysでマウントするという方法で解決しました。今回はElastic File System(以後EFS)というAWSのサービスを使った場合のテンプレート作成を行いました。
EFSについて
EFSを使うにあたって以下のタイプのリソースの作成が必要です。
- AWS::EFS::FileSystem
- 大元のEFSリソース
- AWS::EFS::MountTarget
- 大元のEFSリソースに1:nで紐づけるリソース
- アベイラビリティゾーンごとに紐づけるサブネットを1つ選択して作る
AWS::EFS::FileSystemリソースはRefでマウントを行う際に使用するファイルシステムIDという値を返します。EC2インスタンスを立ち上げる際のスクリプト内で以下のようなmountコマンドと組み合わせて使用します。
"mount -t efs ", { "Ref": "ElasticFileSystem" }, ":/ /var/www/html/", { "Fn::If": [ "WordPressInstallDirectoryNameIsEmpty", "", { "Fn::Join": [ "", [ { "Ref": "WordPressInstallDirectoryName" }, "/" ] ] } ] }, "wp-content/uploads\n",
NGパターン(サブネットとマウントターゲットの数が合わない件)
スタックを構築する時に入力パラメータで選択したサブネットに対応したマウントターゲットを作らないとけないのですが、サブネットは複数個選択できるのに対して、作成するリソースを可変にすることができませんでした。
私のAWSアカウントのデフォルトVPCには3個のサブネットが存在しているので最大で3つのサブネット上にインスタンスを構築することが出来ます。が、リソースとしてEFSマウントターゲットを1つしか作っていなかったため、マウントターゲットが作られなかったアベイラビリティゾーンに所属するインスタンスからのEFSマウントが行えない状態になってしまいました。
以下がNGパターンのテンプレートになります。一応パラメータの入力画面でサブネットの選択数とEFSマウントターゲットの個数が一致すれば正常にスタックが作成できると思います。
マウントターゲットが固定で1個:aws-cloudformation-templates/wordpress_efs.json at fae2c9a3a9009cc3f639ccb570f0e1f2b170fbfa
マウントターゲットが固定で2個:aws-cloudformation-templates/wordpress_efs.json at 7a9d0951b2e2ed1f0141400f40ab44cfb1fb1076
上記の「マウントターゲットが固定で1個」のテンプレートを使用して以下のようなパラメータで作りました。今回はどのように失敗してしまうのかを確認するため、サブネットのリスト項目でap-northeast-1cとap-northeast-1dの2つのサブネットを選択しています。
スタックの構築が完了した状態でそれぞれのインスタンスにSSH接続してdfコマンドを叩いてみたところの様子です。左側がap-northeast-1dで右側がap-northeast-1cになります。
ap-northeast-1cの方のみEFSのマウントが通っていることがわかります。
テンプレート内でEFSMountTarget1リソースのSubnetIdプロパティに対してサブネットパラメータで1つ目に選択したサブネットIDを指定しているため、2つ目の選択値となったap-northeast-1dに関連付いたマウントターゲットが作れませんでした。
このような問題を解決するためにスタックを作成するときにVPCとサブネットを新規作成することにしました。
以下は、手動でEFSのファイルシステムにap-northeast-1d用のマウントターゲットを追加してみたときの様子。
ap-northeast-1d用のマウントターゲットを追加したことで先ほどマウントに失敗したインスタンスでも一応EFSをマウントできることは確認できました。
VPC、サブネットを新規作成してから各リソースを作成する
新規作成するVPCには2つのパブリックサブネットを作成し、それぞれに対応したEFSマウントターゲットを作成します。
VPCとサブネットのパラメータは不要となるので削除し、Refで参照している箇所を書き換えました。
VPC、サブネットを作成するテンプレートはこちらの記事を参考にさせていただきました。
参考:CloudFormationを使ってVPCを構築する – Qiita
プライベートサブネットは今回使わないのでその辺は削りました。
デザイナー画面で出力してみたスタックの構成図は以下のようになりました。正直矢印だらけでよくわからないです(^q^
完成したテンプレートは以下になります。
VPCから新規作成するテンプレート:aws-cloudformation-templates/wordpress_efs.json at ee5faa7a3306d0d5c65b38a45ad6f03d1fd2006a
パラメータ画面からVpcIdとSubnetsが消えて以下のようになりました。
作成が完了したときのイベントの状況は画像だと1つにまとまらないくらい長くなってしまってたのでテキストをコピーしてみました。
約12分ほどで構築に完了していることがわかりました。やはりRDSの構築が微妙に長い。
タイムスタンプ 論理 ID ステータス 状況の理由 2019-11-17 21:43:27 UTC+0900 teststack CREATE_COMPLETE - 2019-11-17 21:43:24 UTC+0900 WebServerGroup CREATE_COMPLETE - 2019-11-17 21:43:23 UTC+0900 WebServerGroup CREATE_IN_PROGRESS Received SUCCESS signal with UniqueId i-0aedf452f085ac537 2019-11-17 21:43:23 UTC+0900 WebServerGroup CREATE_IN_PROGRESS Received SUCCESS signal with UniqueId i-0b2bc5a774ce4fdda 2019-11-17 21:42:00 UTC+0900 WebServerGroup CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:41:59 UTC+0900 WebServerGroup CREATE_IN_PROGRESS - 2019-11-17 21:41:53 UTC+0900 LaunchConfig CREATE_COMPLETE - 2019-11-17 21:41:52 UTC+0900 LaunchConfig CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:41:52 UTC+0900 LaunchConfig CREATE_IN_PROGRESS - 2019-11-17 21:41:47 UTC+0900 DBInstance CREATE_COMPLETE - 2019-11-17 21:36:49 UTC+0900 EFSMountTargetC CREATE_COMPLETE - 2019-11-17 21:36:48 UTC+0900 EFSMountTargetA CREATE_COMPLETE - 2019-11-17 21:35:18 UTC+0900 DBInstance CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:35:17 UTC+0900 EFSMountTargetC CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:35:17 UTC+0900 EFSMountTargetA CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:35:16 UTC+0900 DBInstance CREATE_IN_PROGRESS - 2019-11-17 21:35:16 UTC+0900 EFSMountTargetC CREATE_IN_PROGRESS - 2019-11-17 21:35:16 UTC+0900 EFSMountTargetA CREATE_IN_PROGRESS - 2019-11-17 21:35:12 UTC+0900 EFSSecurityGroup CREATE_COMPLETE - 2019-11-17 21:35:12 UTC+0900 DBEC2SecurityGroup CREATE_COMPLETE - 2019-11-17 21:35:11 UTC+0900 DBEC2SecurityGroup CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:35:11 UTC+0900 EFSSecurityGroup CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:35:06 UTC+0900 DBEC2SecurityGroup CREATE_IN_PROGRESS - 2019-11-17 21:35:05 UTC+0900 EFSSecurityGroup CREATE_IN_PROGRESS - 2019-11-17 21:35:01 UTC+0900 WebServerSecurityGroup CREATE_COMPLETE - 2019-11-17 21:35:00 UTC+0900 WebServerSecurityGroup CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:34:55 UTC+0900 ALBListener CREATE_COMPLETE - 2019-11-17 21:34:55 UTC+0900 ALBListener CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:34:55 UTC+0900 WebServerSecurityGroup CREATE_IN_PROGRESS - 2019-11-17 21:34:55 UTC+0900 ALBListener CREATE_IN_PROGRESS - 2019-11-17 21:34:51 UTC+0900 ApplicationLoadBalancer CREATE_COMPLETE - 2019-11-17 21:32:34 UTC+0900 PublicSubnetCRouteTableAssociation CREATE_COMPLETE - 2019-11-17 21:32:34 UTC+0900 PublicSubnetARouteTableAssociation CREATE_COMPLETE - 2019-11-17 21:32:20 UTC+0900 DBSubnetGroup CREATE_COMPLETE - 2019-11-17 21:32:20 UTC+0900 DBSubnetGroup CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:32:19 UTC+0900 DBSubnetGroup CREATE_IN_PROGRESS - 2019-11-17 21:32:19 UTC+0900 PublicSubnetCRouteTableAssociation CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:32:19 UTC+0900 ApplicationLoadBalancer CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:32:18 UTC+0900 PublicRouteA CREATE_COMPLETE - 2019-11-17 21:32:18 UTC+0900 PublicRouteC CREATE_COMPLETE - 2019-11-17 21:32:18 UTC+0900 PublicSubnetARouteTableAssociation CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:32:18 UTC+0900 PublicSubnetCRouteTableAssociation CREATE_IN_PROGRESS - 2019-11-17 21:32:17 UTC+0900 ApplicationLoadBalancer CREATE_IN_PROGRESS - 2019-11-17 21:32:17 UTC+0900 PublicSubnetARouteTableAssociation CREATE_IN_PROGRESS - 2019-11-17 21:32:14 UTC+0900 PublicSubnetC CREATE_COMPLETE - 2019-11-17 21:32:14 UTC+0900 PublicSubnetA CREATE_COMPLETE - 2019-11-17 21:32:13 UTC+0900 InternetGatewayAttachment CREATE_COMPLETE - 2019-11-17 21:32:05 UTC+0900 ElasticFileSystem CREATE_COMPLETE - 2019-11-17 21:32:04 UTC+0900 ALBSecurityGroup CREATE_COMPLETE - 2019-11-17 21:32:03 UTC+0900 PublicRouteA CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:32:03 UTC+0900 PublicRouteC CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:32:02 UTC+0900 PublicRouteA CREATE_IN_PROGRESS - 2019-11-17 21:32:02 UTC+0900 ALBSecurityGroup CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:32:02 UTC+0900 PublicRouteC CREATE_IN_PROGRESS - 2019-11-17 21:31:58 UTC+0900 PublicRouteTableA CREATE_COMPLETE - 2019-11-17 21:31:58 UTC+0900 PublicRouteTableC CREATE_COMPLETE - 2019-11-17 21:31:58 UTC+0900 ALBTargetGroup CREATE_COMPLETE - 2019-11-17 21:31:57 UTC+0900 PublicSubnetA CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:31:57 UTC+0900 ALBTargetGroup CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:31:57 UTC+0900 PublicSubnetC CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:31:57 UTC+0900 InternetGatewayAttachment CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:31:57 UTC+0900 PublicRouteTableC CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:31:57 UTC+0900 PublicRouteTableA CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:31:57 UTC+0900 ALBSecurityGroup CREATE_IN_PROGRESS - 2019-11-17 21:31:57 UTC+0900 PublicSubnetA CREATE_IN_PROGRESS - 2019-11-17 21:31:57 UTC+0900 InternetGatewayAttachment CREATE_IN_PROGRESS - 2019-11-17 21:31:57 UTC+0900 ALBTargetGroup CREATE_IN_PROGRESS - 2019-11-17 21:31:57 UTC+0900 PublicRouteTableC CREATE_IN_PROGRESS - 2019-11-17 21:31:57 UTC+0900 PublicSubnetC CREATE_IN_PROGRESS - 2019-11-17 21:31:57 UTC+0900 PublicRouteTableA CREATE_IN_PROGRESS - 2019-11-17 21:31:53 UTC+0900 NewVPC CREATE_COMPLETE - 2019-11-17 21:31:51 UTC+0900 InternetGateway CREATE_COMPLETE - 2019-11-17 21:31:36 UTC+0900 NewVPC CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:31:35 UTC+0900 NewVPC CREATE_IN_PROGRESS - 2019-11-17 21:31:35 UTC+0900 InternetGateway CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:31:35 UTC+0900 ElasticFileSystem CREATE_IN_PROGRESS Resource creation Initiated 2019-11-17 21:31:35 UTC+0900 InternetGateway CREATE_IN_PROGRESS - 2019-11-17 21:31:34 UTC+0900 ElasticFileSystem CREATE_IN_PROGRESS - 2019-11-17 21:31:29 UTC+0900 teststack CREATE_IN_PROGRESS User Initiated
作成されたVPCについて確認。
Nameタグを入れるようにしたので少し見やすくなったような気がします。
サブネットは以下の通り。新規作成されたVPCと紐づいていることがわかります。
次にEFSリソースについて確認。作成されたサブネットとそれぞれ紐づいたマウントターゲットが作られていることがわかります。
画面の方は問題なく動作することを確認。
マウント中のuploadsディレクトリも正常に稼働している模様。
RLoginでSSH接続しての確認。
dfコマンドでEFSファイルシステムがマウントできていることを確認しました。
動作確認として左側でhogeファイルを作って、右側で中身を確認しました。
また、WordPressの管理画面で画像をアップロードして両方のインスタンスから参照できることを確認しました。
まとめ?
今回のEFSを使ったパターンはS3,goofysを使ったパターンよりも正しくAWSのサービスを使えているような気がする。
費用的なところがちょっとよくわかってない。以下の見積ツールでざっと調べてみた感じ数GB程度だと料金が変わりませんでした( ・`ー・´)??
参考:Amazon Web Services Simple Monthly Calculator
EFSでもS3も使用せずに、スケーリングしないEC2を1個立ててnfsサーバーを構築し共有するというパターンについてもそのうち書こうと思います。
その他(EC2のメタデータについて)
EC2インスタンス内からインスタンスのメタ情報を取得するhttp://169.254.169.254~~が便利でした。
参考:【小ネタ】EC2のインスタンスメタデータからリージョンを取得する | Developers.IO
今回は2つのインスタンスに接続した状態でそれぞれどのアベイラビリティゾーンに所属してるかを表示するのに使用しました。
EC2インスタンス内で自身のパブリックDNS名を取得して何らかのファイルに設定したい、みたいなケースのときにRefで参照すると循環参照となってしまいスタック作成時にエラーとなってしまいます。こういったときにメタデータをcurlで取得すると良いのかなーと思いました。
以下はwp-cliを使ってWordPressのインストールを行う際に–urlパラメータに指定するDNS名をメタデータから取得して設定してみたときのサンプルコードになります。
"sudo -u apache /usr/local/bin/wp core install --title='", { "Ref": "WordPressSiteName" }, "' --admin_user='", { "Ref": "WordPressAdminUser" }, "' --admin_password='", { "Ref": "WordPressAdminPass" }, "' --admin_email='", { "Ref": "WordPressAdminEmail" }, "' --url=\"https://$(curl -s http://169.254.169.254/latest/meta-data/public-hostname)/", { "Ref": "WordPressInstallDirectoryName" }, "\"\n",
その他(WordPressのアップデートについて)
WordPressが5.3にアップデートされたことが原因か、セキュリティSALTの辺りの自動設定処理がうまく行かなくなってしまいました。。
調べてみたとこdefine()の括弧内の前後に半角スペースが入るようになったことが原因でした。
sedによる置換処理を微修正して、プッシュしていますので今回のテンプレートを使ってみたい方がいらっしゃいましたらGitHubから最新のソースを取得するか以下のリンクからどうぞ。
SALTキーのとこ修正したやつ:aws-cloudformation-templates/wordpress_efs.json at f69d31b2fc199855f6bd0856ad9c5c50e3aefb3a