Re:dashインスタンスを意識高く運用する話
About
Re:dashインスタンスを使ってログデータを確認できるようにしましたが、普通に運用しているだけではつまらなかったのでいろいろ仕込んでみました。細かいことはいいから全体の構成だけ知りたいという方は構成図をご覧下さい。
- About
- 話さないこと
- lambdaを使って定時内だけ閲覧できるようにする
- Route53のfailoverを使って定時後にはSorryページを表示させる
- サーバ起動時に自動でIPアドレスを書き換える
- https対応のためS3の前段にCloudfrontを導入する
- 最終的な全体の構成図
- まとめ
- 参考
話さないこと
- Re:dashの使い方
- Re:dashでどういうデータを表示させているか(勉強中です)
lambdaを使って定時内だけ閲覧できるようにする
EC2インスタンスをずっと動かしておくとその分課金されてしまいます。余ったお金はその分ポケモンGOに投資したいので、lambdaを使って定時内だけインスタンスを起動させておきます。こちらの記事を参考に設定しました。
Route53のfailoverを使って定時後にはSorryページを表示させる
定時後などはインスタンスが落ちてしまうためアクセスができませんが、なんでサーバが落ちているのか利用者にはわかりません。そこでRoute53を使ってfailoverさせ、S3のSorryページを見せることにしました。
Web hosting機能を有効にする
まず、S3の準備をします。設定したいドメインに合わせたS3バケットを作ります。管理画面上からwebhosting機能を有効化した後にポリシーを設定します。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadForGetBucketObjects", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::<bucket_name>/*", "Condition": { "IpAddress": { "aws:SourceIp": "xxx.xxx.xxx.xxx/32" } } } ] }
今回Re:dashインスタンスはIPアドレス制限をしているため、バケットについても同じ制限をしています。
設定できたら作ったindex.htmlをアップロードしておきます。今のところ設定しているhtmlは素朴な感じです。
本日の運用は停止しましたm(__)m
cloudwatchを設定する
次にfailoverする仕組みを設定します。Route53のヘルスチェックには以下の3つの定義ができます
- cloudwatchでの監視
- エンドポイントの監視(IPアドレスとポート)
- 他のサービスのヘルスチェックと連携(ELBなど)
今回の場合インスタンスにIPアドレス制限をしているので、エンドポイントに対する監視は全てfailになってしまいます。従って、今回はcloudwatchでEC2インスタンスが落ちたことを検知し、failoverさせる仕組みにしました。Re:dashインスタンスがELBに紐付いていればELBでのヘルスチェックがベターかなと思いますが、ELB代がもったいなかったのでEC2インスタンスを直接cloudwatchで監視することにしました。監視項目としてはStatus Check Failed
を選択し、Re:dashインスタンスに設定します。
Route53上でHealth checkを定義する
cloudwatchの準備ができたので、Route53上のhealth checkと紐付けを行います。設定画面もわかりやすいので、そこまで複雑な部分はないかと思います。
Route53にfailoverの設定をする
事前準備ができたのでRoute53のレコードにfailoverの設定をしていきます。
詳細の画面をのせることはできないですが、簡単に言葉で説明すると同じ名前のレコードを2つ作成作成し、primary/secondaryを決め前者はRe:dashのインスタンスのIPを、後者はS3のALIASを設定します。
サーバ起動時に自動でIPアドレスを書き換える
上記まででインスタンスが落ちた際に、Sorryページを見せるところまでいきました。が、このままだとEC2が起動した際にEIPを付けていない限りIPアドレスが変わってしまい、ヘルスチェックが成功しても画面が表示されません。そこで、cloud-initを利用してサーバ起動時に自分のIPを取得してRoute53の設定を書き換えるようにしました。
$ cat /var/lib/cloud/scripts/per-bootset_hostname.sh #!/bin/bash jq=/usr/local/bin/jq aws=/usr/local/bin/aws hosted_zone_id=XXXXXXXX domain=XXXXXXX hostname=XXXXXXX export AWS_DEFAULT_REGION=ap-northeast-1 instance_id=$(curl -s http://169.254.169.254/latest/meta-data/instance-id) json=$($aws ec2 describe-instances --instance-ids $instance_id) public_ip_address=$(echo $json | $jq -r '.Reservations[0].Instances[0].PublicIpAddress') # register to Route53 cat > /etc/cloud/cloud.cfg.d/set_hostname.json <<EOF { "Comment": "${hostname}", "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name": "${hostname}.${domain}", "Type": "A", "TTL" : 60 , "SetIdentifier" : "XXXXXXXXX-Primary" , "ResourceRecords": [ { "Value": "${public_ip_address}" } ], "Failover": "PRIMARY", "HealthCheckId": "XXXXXXXXXXX" } } ] } EOF echo "\$ cat /etc/cloud/cloud.cfg.d/set_hostname.json" cat /etc/cloud/cloud.cfg.d/set_hostname.json echo "\$ $aws route53 change-resource-record-sets --hosted-zone-id $hosted_zone_id --change-batch file:////etc/cloud/cloud.cfg.d/set_hostname.json" $aws route53 change-resource-record-sets --hosted-zone-id $hosted_zone_id --change-batch file:////etc/cloud/cloud.cfg.d/set_hostname.json
/var/lib/cloud/script/per-boot
に任意のスクリプトを入れておくとサーバの起動時に毎回処理が走ります。例えばset_hostname.sh
というようなスクリプトを置いて、内部でawscliを使ってmetadataからpublic_ipを取得し、Route53のレコードを書き換えています。
https対応のためS3の前段にCloudfrontを導入する
ここまでで一応の構成はできました。しかし、S3のWebhosting機能ではhttpsに対応していないため、httpsでアクセスはできません。せっかくSorryページを作ったのにアクセスできず悲しいので、若干大げさと思いつつ前段にCloudfrontをおきます。
カスタムのSSL証明書を設定したい場合は、cloudfrontは初期費用が高いイメージがありますが、SNIを使っていればカスタム証明書の設置代はかからないので安く運用できます。今回は事前に証明書を取得済みなのでACMは使っていません。cloudfrontの設定ができたら最後に、Route53の向き先をcloudfrontのALIASにすることでhttpsでS3バケットにアクセスできます。
最終的な全体の構成図
最後に全体の構成を貼っておきます。
まとめ
ほぼほぼRe:dash関係ない話でしたが、httpsにもできて個人的には満足しました!インスタンスの監視にStatusCheckFailedを使っていますが、若干反応が遅いのでもっと即時に反映できるように監視項目の変更なり調整をしていきたいと思います。
参考
- https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/HostingWebsiteOnS3Setup.html
- http://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-tech-amazon-route53
- S3でIP制限 - Qiita
- Route53のヘルスチェックでInternalELBをフェイルオーバさせてみた | Developers.IO
- S3+CloudFront+Route53で503なSorryページを安価に実現する - hiroohiのメモ
- CloudFrontで独自ドメインSSL設定 - Qiita
- ELBとCloudFrontで同じSSL証明書を使う方法 - Qiita