Route53にDNS自動登録

  • EC2インスタンスを起動すると内部DNSにAレコードを登録し、停止するとAレコードを削除するinitスクリプトを作成しました。
    ”ZONE_NAME”だけ書き換えてあとはコピペでいける!はずです!

起動停止スクリプト作成

/etc/init.d/aws_route53_edit
#!/bin/bash
# chkconfig: 2345 99 10
# description: regist A record to aws route53
# Author:



ZONE_NAME="ゾーン名"
HOST_NAME=$(aws ec2 describe-tags --output text --query "Tags[?ResourceId==`$(curl -s http://169.254.169.254/latest/meta-data/instance-id)` && Key==`Name`].Value")
IP_ADDRESS=$(curl -s http://169.254.169.254/latest/meta-data/local-ipv4)
HOSTED_ZONE_ID=$(aws route53 list-hosted-zones | grep "Id" | awk '{print $2}' | sed -e 's//hostedzone///' | sed -e 's/,//' | sed -e 's/"//g')
LOCK=/var/lock/subsys/aws_route53_edit


case "$1" in
  "start" )

  ARECORD_JSON="{
    "Changes" : [
      { "Action" : "UPSERT",
        "ResourceRecordSet" : {
          "Name" : "${HOST_NAME}.${ZONE_NAME}",
          "Type" : "A",
          "TTL"  : 60,
          "ResourceRecords": [
            { "Value" : "${IP_ADDRESS}" }
          ]
        }
      }
    ]
  }"
  touch $LOCK
  ;;

  "stop" )

  ARECORD_JSON="{
    "Changes" : [
      { "Action" : "DELETE",
        "ResourceRecordSet" : {
          "Name" : "${HOST_NAME}.${ZONE_NAME}",
          "Type" : "A",
          "TTL"  : 60,
          "ResourceRecords": [
            { "Value" : "${IP_ADDRESS}" }
          ]
        }
      }
    ]
  }"
  rm -f $LOCK
  ;;

  *)
  echo $"Usage: $0 {start|stop}"
  exit 2
  ;;

esac

自動起動停止登録

sudo chmod 755 /etc/init.d/aws_route53_edit
sudo chkconfig --add aws_route53_edit
sudo chkconfig --list aws_route53_edit

確認

  • マネジメントコンソールから落とし上げをして別ウィンドウでRoute53を監視

ハマったところ

  • ロックファイル
    /var/lock/subsys/以下にファイルが無いとうまく動かないことがしばらくわからず時間をかけてしまった。ない状態でやると起動時のレコード登録はうまくいくがレコード削除がされなかった

その他

  • 起動停止時にCloudWatch登録削除なども作成予定なのでスクリプト名やロックファイル名は”aws_サービス名_動作名”などがよさそう

続きを読む

Fresh Install bitnami redmine stack on AWS, then migrate old data and database from old instance.

Fresh Install bitnami redmine stack on AWS, then migrate old data and database from old instance.

目的: Redmine のバージョンアップ と HTTPS化

ですが、新環境の構築手順のみやっていただければ新規構築手順としても使えます。

  • 前回書いた記事から1年ちょっと経過しました。
  • bitnami redmine stack AMI のバージョンも以下のように変化しました。(2017/06/21 現在)
    • Old version 3.2.1
    • New version 3.3.3
  • 前回は GUI でぽちぽち作成しましたが、今回は AWS CLI を中心に進めます。
  • ついでに前回書いてなかった HTTPS化 についても簡単に追記します。
  • 以下の AWS の機能を利用します。
    • Route53: ドメイン名取得、名前解決(DNS)
    • ACM(Amazon Certificate Manager): 証明書発行
    • ELB(Elastic Load Balancer): 本来は複数インスタンスをバランシングする用途に使うものですが今回は EC2 インスタンス 1台 をぶら下げ、ACM で取得した証明書を配布し外部との HTTPS通信 のために利用します。

注意と免責

  • 無料枠でない部分は料金が発生します。
  • データの正常な移行を保証するものではありません。

前提

  • 現環境が正常に動作していること。
  • 新環境を同一リージョン、同一VPC、同一サブネット内に新たにたてます。
    • インスタンス間のデータ転送を SCP で簡易に行いたいと思います。
    • 適宜セキュリティグループを解放してください。
  • aws cli version
% aws --version
aws-cli/1.11.47 Python/2.7.12 Darwin/16.6.0 botocore/1.5.10

段取り

  • 大まかに以下の順序で進めます
  1. Version 3.3.3 の AMI を使って EC2 インスタンスを起動
  2. Version 3.2.1 のデータバックアップ
    • Bitnami Redmine Stack の停止
    • MySQL Dump 取得
  3. Version 3.3.3 へのデータ復元
    • Bitnami Redmine Stack の停止
    • MySQL Dump 復元
    • Bitnami Redmine Stack の開始
  4. 動作確認

参考資料

作業手順

1. Newer Bitnami redmine stack インスタンス作成

以下の条件で作成します。

  • Common conditions

    • AMI: ami-15f98503
    • Type: t2.micro
    • Public IP: あり
  • User defined conditions
    • Region: N.Virginia
    • Subnet: subnet-bd809696
    • Security Group: sg-5b5b8f2a
    • Keypair: aws-n.virginia-default001
    • IAM Role: ec2-001
    • EBS: 20GB

WEB GUI から作るも良し、AWS CLI から作るも良し
以下コマンド実行例

set-env
KEY_NAME=aws-nvirginia-default001.pem
echo $KEY_NAME
check-ami
aws ec2 describe-images \
    --filters "Name=image-id,Values=ami-15f98503"
check-ami-name
aws ec2 describe-images \
    --filters "Name=image-id,Values=ami-15f98503" \
    | jq ".Images[].Name" \
    | grep --color redmine-3.3.3
create-instance
aws ec2 run-instances \
    --image-id ami-15f98503 \
    --count 1 \
    --instance-type t2.micro \
    --key-name aws-n.virginia-default001 \
    --security-group-ids sg-5b5b8f2a \
    --subnet-id subnet-bd809696 \
    --block-device-mappings "[{\"DeviceName\":\"/dev/sda1\",\"Ebs\":{\"VolumeSize\":20,\"DeleteOnTermination\":false}}]" \
    --iam-instance-profile Name=ec2-001 \
    --associate-public-ip-address
set-env
INSTANCE_ID=i-0f8d079eef9e5aeba
echo $INSTANCE_ID
add-name-tag-to-instance
aws ec2 create-tags --resources $INSTANCE_ID \
    --tags Key=Name,Value=redmine-3.3.3

注意書きにもありますが以下に表示される MySQL Database の root パスワードは初期起動時にしか表示されません。
このときに保管しておくか MySQL のお作法にしたがって変更しておいても良いでしょう

check-instance-created
aws ec2 describe-instances --filter "Name=instance-id,Values=$INSTANCE_ID"
wait-running-state
aws ec2 describe-instances \
    --filter "Name=instance-id,Values=$INSTANCE_ID" \
    | jq '.Reservations[].Instances[].State["Name"]'
get-redmine-password
aws ec2 get-console-output \
    --instance-id $INSTANCE_ID \
    | grep "Setting Bitnami application password to"
get-publicip
aws ec2 describe-instances \
    --filter "Name=instance-id,Values=$INSTANCE_ID" \
    | jq '.Reservations[].Instances[].NetworkInterfaces[].Association'
set-env
PUBLIC_IP=54.243.10.66
echo $PUBLIC_IP
site-check
curl -I http://$PUBLIC_IP/
HTTP/1.1 200 OK
(snip)
ssh-connect
ssh -i .ssh/$KEY_NAME bitnami@$PUBLIC_IP
first-login
bitnami@new-version-host:~$ sudo apt-get update -y
bitnami@new-version-host:~$ sudo apt-get upgrade -y
bitnami@new-version-host:~$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.5 LTS"
bitnami@new-version-host:~$ sudo ./stack/ctlscript.sh status
subversion already running
php-fpm already running
apache already running
mysql already running
bitnami@new-version-host:~$ sudo ./stack/ctlscript.sh help
usage: ./stack/ctlscript.sh help
       ./stack/ctlscript.sh (start|stop|restart|status)
       ./stack/ctlscript.sh (start|stop|restart|status) mysql
       ./stack/ctlscript.sh (start|stop|restart|status) php-fpm
       ./stack/ctlscript.sh (start|stop|restart|status) apache
       ./stack/ctlscript.sh (start|stop|restart|status) subversion

help       - this screen
start      - start the service(s)
stop       - stop  the service(s)
restart    - restart or start the service(s)
status     - show the status of the service(s)

2. 旧バージョンのバックアップ取得

login_to_oldversion
Welcome to Ubuntu 14.04.3 LTS (GNU/Linux 3.13.0-74-generic x86_64)
       ___ _ _                   _
      | _ |_) |_ _ _  __ _ _ __ (_)
      | _ \ |  _| ' \/ _` | '  \| |
      |___/_|\__|_|_|\__,_|_|_|_|_|

  *** Welcome to the Bitnami Redmine 3.2.0-1         ***
  *** Bitnami Wiki:   https://wiki.bitnami.com/      ***
  *** Bitnami Forums: https://community.bitnami.com/ ***
Last login: Sun May 29 07:33:45 2016 from xxx.xxx.xxx.xxx
bitnami@old-version-host:~$
check-status
bitnami@old-version-host:~$ sudo stack/ctlscript.sh status
subversion already running
php-fpm already running
apache already running
mysql already running
stop
bitnami@old-version-host:~$ sudo stack/ctlscript.sh stop
/opt/bitnami/subversion/scripts/ctl.sh : subversion stopped
Syntax OK
/opt/bitnami/apache2/scripts/ctl.sh : httpd stopped
/opt/bitnami/php/scripts/ctl.sh : php-fpm stopped
/opt/bitnami/mysql/scripts/ctl.sh : mysql stopped
start-mysql
bitnami@old-version-host:~$ sudo stack/ctlscript.sh start mysql
170621 10:04:34 mysqld_safe Logging to '/opt/bitnami/mysql/data/mysqld.log'.
170621 10:04:34 mysqld_safe Starting mysqld.bin daemon with databases from /opt/bitnami/mysql/data
/opt/bitnami/mysql/scripts/ctl.sh : mysql  started at port 3306
check-available-filesystem-space
bitnami@old-version-host:~$ df -h /
Filesystem                                              Size  Used Avail Use% Mounted on
/dev/disk/by-uuid/6cdd25df-8610-4f60-9fed-ec03ed643ceb  9.8G  2.7G  6.6G  29% /
load-env-setting
bitnami@old-version-host:~$ . stack/use_redmine
bitnami@old-version-host:~$ echo $BITNAMI_ROOT
/opt/bitnami
dump-mysql
bitnami@old-version-host:~$ mysqldump -u root -p bitnami_redmine > redmine_backup.sql
Enter password:
bitnami@old-version-host:~$ ls -ltrh
  • scp 準備

手元の作業PCから新Redmine環境へssh接続するときに使用した証明書(pem)ファイルを旧Redmine環境にも作成します。

  • 今回は作業PC上で cat で表示させておいて旧環境のコンソール上にコピペしました。
example
bitnami@old-version-host:~$ vi .ssh/aws-nvirginia-default001.pem
bitnami@old-version-host:~$ chmod 600 .ssh/aws-nvirginia-default001.pem
  • ファイル転送
file_transfer
bitnami@old-version-host:~$ scp -i .ssh/aws-nvirginia-default001.pem redmine_backup.sql <new-version-host-ipaddr>:~
  • 新バージョン側にファイルが届いているか確認
check-transfered-files
bitnami@new-version-host:~$ ls -alh redmine*

3. 新バージョンへの復元

stop-stack
bitnami@new-version-host:~$ sudo stack/ctlscript.sh status
subversion already running
php-fpm already running
apache already running
mysql already running

bitnami@new-version-host:~$ sudo stack/ctlscript.sh stop

/opt/bitnami/subversion/scripts/ctl.sh : subversion stopped
Syntax OK
/opt/bitnami/apache2/scripts/ctl.sh : httpd stopped
/opt/bitnami/php/scripts/ctl.sh : php-fpm stopped
/opt/bitnami/mysql/scripts/ctl.sh : mysql stopped
start-mysql
bitnami@new-version-host:~$ sudo stack/ctlscript.sh start mysql
initial-database
bitnami@new-version-host:~$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.35 MySQL Community Server (GPL)

(snip)

mysql> drop database bitnami_redmine;

mysql> create database bitnami_redmine;

mysql> grant all privileges on bitnami_redmine.* to 'bn_redmine'@'localhost' identified by 'DATAB
ASE_PASSWORD';

mysql> quit
restore-dumpfile
bitnami@new-version-host:~$ mysql -u root -p bitnami_redmine < redmine_backup.sql
Enter password:
bitnami@new-version-host:~$
edit-line-18
bitnami@new-version-host:~$ vi /opt/bitnami/apps/redmine/htdocs/config/database.yml

    18    password: "DATABASE_PASSWORD"
db-migrate
bitnami@new-version-host:~$ cd /opt/bitnami/apps/redmine/htdocs/
bitnami@new-version-host:/opt/bitnami/apps/redmine/htdocs$ ruby bin/rake db:migrate RAILS_ENV=production
bitnami@new-version-host:/opt/bitnami/apps/redmine/htdocs$ ruby bin/rake tmp:cache:clear
bitnami@new-version-host:/opt/bitnami/apps/redmine/htdocs$ ruby bin/rake tmp:sessions:clear
stack-restart
bitnami@new-version-host:/opt/bitnami/apps/redmine/htdocs$ cd
bitnami@new-version-host:~$ sudo stack/ctlscript.sh restart

bitnami@new-version-host:~$ exit
site-check
curl -I http://$PUBLIC_IP/
HTTP/1.1 200 OK
(snip)

ブラウザでも http://$PUBLIC_IP/ でアクセスして旧環境のユーザー名とパスワードでログイン出来ることを確認してください。

この時点で旧環境のインスタンスを停止させておいて良いでしょう。
いらないと判断した時に削除するなりしてください。

4. おまけ HTTPS化

  • 4-1. Route53 でドメイン名を取得してください

    • .net で 年額 11 USドル程度ですので実験用にひとつくらい維持しておくと便利
  • 4-2. Certificate Manager で証明書を取得します
    • コマンドでリクエストしてます
aws acm request-certificate --domain-name redmine.hogefuga.net
check-status-pending
aws acm describe-certificate \
    --certificate-arn "arn:aws:acm:us-east-1:942162428772:certificate/fdf099f9-ced7-4b97-a5dd-f85374d7d112" \
    | jq ".Certificate.Status"
"PENDING_VALIDATION"
  • 4-3. 承認する

    • ドメインに設定しているアドレスにメールが飛んできます
  • 4-4. ステータス確認
check-status-ISSUED
aws acm describe-certificate \
    --certificate-arn "arn:aws:acm:us-east-1:942162428772:certificate/fdf099f9-ced7-4b97-a5dd-f85374d7d112" \
    | jq ".Certificate.Status"
"ISSUED"
  • 4-5. Classic タイプの HTTPS ELB をつくる
example
aws elb create-load-balancer \
    --load-balancer-name redmine-elb1 \
    --listeners "Protocol=HTTPS,LoadBalancerPort=443,InstanceProtocol=HTTP,InstancePort=80,SSLCertificateId=arn:aws:acm:us-east-1:942162428772:certificate/fdf099f9-ced7-4b97-a5dd-f85374d7d112" \
    --availability-zones us-east-1a \
    --security-groups sg-3c90f343
  • 4-6. インスタンスをくっつける
example
aws elb register-instances-with-load-balancer \
    --load-balancer-name redmine-elb1 \
    --instances i-0f8d079eef9e5aeba
  • 4-7. State が InService になるまで待ちます
example
aws elb describe-instance-health \
    --load-balancer-name redmine-elb1
  • 4-8. DNS Name を確認する(4-10. で使います)
example
aws elb describe-load-balancers \
    --load-balancer-name redmine-elb1 \
  | jq ".LoadBalancerDescriptions[].DNSName"
  • 4-9. 今の設定を確認
example
aws route53 list-resource-record-sets \
    --hosted-zone-id Z3UG9LUEGNT0PE | jq .
  • 4-10. 投入用の JSON をつくる
example
vi change-resource-record-sets.json
example
{
  "Comment": "add CNAME for redmine.hogefuga.net",
  "Changes": [
    {
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "redmine.hogefuga.net",
        "Type":"CNAME",
        "TTL": 300,
        "ResourceRecords": [
          {
            "Value": <DNSName>
          }
        ]
      }
    }
  ]
}

4-11. 設定投入

example
aws route53 change-resource-record-sets \
    --hosted-zone-id Z3UG9LUEGNT0PE \
    --change-batch file://change-resource-record-sets.json

4-12. 設定確認

example
aws route53 list-resource-record-sets \
    --hosted-zone-id Z3UG9LUEGNT0PE

4-13. ブラウザ確認

https://redmine.hogefuga.net

4-14. EC2 インスタンスのセキュリティグループ再設定

  • グローバルの TCP:80 削除
  • サブネット内の TCP:80 許可
check
aws ec2 describe-security-groups --group-ids sg-b7d983c8
change
aws ec2 modify-instance-attribute \
    --instance-id i-0f8d079eef9e5aeba \
    --groups sg-b7d983c8

4-15. 再度ブラウザからアクセス可能か確認

続きを読む

AWSでWebサイトを作りますか。

AWSのEC2でWordPressを使ってサイトを作った備忘録。変な所でハマったので。
EC2上にAmazon Linux AMI乗っけてその上でApache起動させてそこにWordPress乗せるという回りくどいことをやっているのであんまり参考にならないかも……。

AWSへの登録

AWS公式の「まずは無料で登録」から。日本語だからわかりやすい。

使えるクレジットカードが必要なのは要注意。
AU WalletはMastercardなはずなんだけどダメでした。

EC2インスタンスの作成

認証が終わったら、左上の「サービス」をクリック。
使うことの出来るサービス一覧がずらりと並んでます。
その中で左上の「EC2」を選択。
170617.PNG

青い「インスタンスの作成」ボタンを押すとインスタンスが作成できる……のだが、その前に自分が今どこのリージョンを使っているのかを確認する。
これは右上、自分の名前の横に書いてある。
170617-1.PNG
自分の場合はバージニア北部ですね。

AWSでは、作成したインスタンスは「(アカウント名)が(リージョン名)に作ったインスタンス」ではなく「(リージョン名)に保管されている(アカウント名)が作ったインスタンス」みたいな感じで管理されているみたいです。
なので、インスタンスを作ってから右上を弄ってリージョンを変えると見た目上作成したインスタンスが消えます
あくまで見た目上なので、当然リージョンを移動すればまた見えるようになります。よいこのみなさんはわたしみたいに「き、消えた!?」と焦らないようにしてください。
逆に、インスタンスが消えた!?と思ったらまずは自分のいるリージョンを確認しましょう。

この時参考にしたブログ

リージョンを確認したらインスタンスを作っていきます。
とは言っても、画面に表示されるものを読みながらやっていけばできます。
自分はこのあたりを参考にしつつやりました。

この時、下の青いボタンを押すとその後の設定をすっ飛ばしてインスタンスを作ってくれます。
親切なんだか不親切なんだかわからん……。

自分はここでAMIにAmazon Linux AMIを入れてしまいましたが、実はここで直にWordPressが選べるみたいです。左メニューの「AWS Marketplace」をクリックしてから検索窓に「WordPress」と入れて検索してみてね!

最後に公開鍵と秘密鍵のキーペアを作成します。プルダウンから「新しいキーペアの作成」を選び、適当な名前を付けてDL。これは後で必要になるので、どこに保存したか忘れないようにしておきましょう。

セキュリティグループ

無事にインスタンスが作成出来たらインスタンスの管理画面になります。
インスタンスの状態が「Running」になったら(大体一分位?)、SSH接続に必要なセキュリティグループの設定をします。
インスタンスを選択して「説明」タブを見ると、今使っているセキュリティグループがわかります。
これをクリックするとセキュリティグループの設定へ飛べます。

170617-2.PNG

セキュリティグループの設定ページで「インバウンド」タブを選択するとこんな感じ。
最初は「HTTP」しか無いと思うので、「編集」→「ルールの追加」でSSHを作ってやりましょう。
170617-3.PNG

本当はソースをちゃんと指定してあげたほうがいいんですが、使ってる回線が可変IPなので……。
固定IPを持っているよいこのみなさんはちゃんと指定しましょうね。

SSH接続

さっき作った秘密鍵をPuTTYごった煮版内のPuTTYgenから「読込」してやってPuTTY用の秘密鍵ファイルを作ります。
「全てのファイル(*.*)」で探すのを忘れずに。じゃないと見えません。
そして.ppk形式で保存。パスワードはかけておいたほうが良いでしょう。

PuTTYの設定は下記の通り。

フィールド
セッション>ホスト名 ec2-user@(パブリック DNS (IPv4))
セッション>ポート 22
セッション>接続タイプ SSH
接続>SSH>認証>認証のためのプライベートキーファイル (上で作った.ppkファイル)

セッション一覧で適当な名前をつけて「保存」したら「開く」で接続を始めます。
初回はダイアログが出ますが「OK」でスルー。
秘密鍵のパスワードの入力を求められたら入力。
AMIの起動画面が出たら成功です。

この辺の話は公式のガイドページが詳しいです。

Apacheのインストール

インストール。

# sudo yum -y install httpd

起動。

# sudo service httpd start

わーいらくちーん。
この時点でブラウザからhttp://(パブリック DNS (IPv4))を見てみるとテストページが見れます。

WordPressのインストール

まずはWordPressに必要なPHPとMySQLをインストール。

# yum install httpd mysql-server php php-mysql wget

/etc/php.iniを弄ってタイムゾーンの設定をしときます。

# vi /etc/php.ini
 ; Defines the default timezone used by the date functions
 ; http://www.php.net/manual/en/datetime.configuration.php#ini.date.timezone
 date.timezone = "Asia/Tokyo"

ここを参考にしつつMySQLの設定。
このページに沿ってやるとwpという名前のデータベースとwpという名前のユーザが出来上がっています。

WordPress本体を落としてきて解凍。
さらにApacheがWordPressを読み込めるようにしておく。

# cd /tmp
# wget http://ja.wordpress.org/wordpress-4.8-ja.tar.gz
# tar zxvf wordpress-3.5.1-ja.tar.gz 
# cp -r wordpress /var/www/
# chown -R apache.apache /var/www/wordpress

/etc/httpd/conf/httpd.confを弄って、

  • DocumentRootをWordPressにし、
  • DocumentRootのディレクトリに対して.htaccessによる上書きを許可しておく。
# vi /etc/httpd/conf/httpd.conf
 DocumentRoot "/var/www/wordpress"
 (中略)
 <Directory "/var/www/wordpress"> ←ここをちゃんとDocumentRootと同じにしておく
     AllowOverride All

WordPressの設定ファイルを作る。
予めサンプルファイルが用意されているので、それをコピーして……

# cd /var/www/wordpress
# sudo cp wp-config-sample.php wp-config.php

書き換え。

# vi wp-config.php

 // データベース情報を設定します。
 define('DB_NAME', 'wp');
 define('DB_USER', 'wp');
 define('DB_PASSWORD', 'password');
 define('DB_HOST', 'localhost');
 define('DB_CHARSET', 'utf8');

 // 「put your unique phrase here」を 適当な文字列に置き換えます。
 define('AUTH_KEY',         'put your unique phrase here');
 define('SECURE_AUTH_KEY',  'put your unique phrase here');
 define('LOGGED_IN_KEY',    'put your unique phrase here');
 define('NONCE_KEY',        'put your unique phrase here');
 define('AUTH_SALT',        'put your unique phrase here');
 define('SECURE_AUTH_SALT', 'put your unique phrase here');
 define('LOGGED_IN_SALT',   'put your unique phrase here');
 define('NONCE_SALT',       'put your unique phrase here');

自分はここでPuTTYの文字コードをUTF-8にしていなかったため、viでwp-config.phpを開いた瞬間に画面を文字化けしたものが覆うという大惨事になってしまいました。
その時にwp-config.phpが壊れてしまったようで、ファイルの上半分が消失するという事態に……。
バックアップって大事だね!(もう一度cp wp-config-sample.php wp-config.phpしながら)

ここで再びhttp://(パブリック DNS (IPv4))を覗いてみるとWordPressの初期設定画面が開きます。
もしも「データベース接続確立エラー」と出るならwp-config.phpのデータベース情報のどこかが間違ってます。
もしもwp-config.phpの中身が表示されているようならSyntax Errorです。直しましょ。

独自ドメイン設定

サイト自体は完成したので次はドメインとパブリックDNSを紐付けてやります。

これを参考にしてElastic IPを作成、ついでRoute53を設定。Whoisが更新されたのを確認してからドメインをブラウザに入れてみると……。

動かない。何故だ。

正確に言うと、動いてはいるっぽいけどサイトのテキストしか表示されない。
その状態で色々弄っていたら、あることに気づく。

管理画面に遷移しようとすると新たに設定したElastic IPではなく以前のパブリックDNSが出る。

ちょっと調べてみたらこんなページが。
なるほど、DBには前のパブリックDNSしか登録されてないからこうなるのね。
変えてやったら無事動きましたー!よかったー。

さて、あとはサイト本体を作るだけだ……。

続きを読む

Mastodonインスタンス構築(鯖:AWS EC2、ドメイン:お名前.com、SSL:Let’s Encrypt)

まずは

QiitaはROM専(死語?)だったので初投稿。
こちらの記事に勇気付けられた。

「僕が書いたことはみんな書いている、ハマっていることは共有しなくてもいい」という考えも浮かぶと思うが…
・情報鮮度の観点で出す価値あり

http://qiita.com/hinom77/items/dfa9e0c734e47271edb7

たしかにググって記事がたくさん出てくると学んでて損はない技術なんだろうと思えてくる。
ビッグウェーブに乗りたいというのもある。
というわけで何番煎じかわからないがマストドンのインスタンス構築記録を書く。
見せ方、引用の仕方など作法があればご容赦。
Qiitaのマークダウンすらままならず…。

基本的な軸

基本的には↓↓を参考にさせていただきました。
私の環境で違ったところだけ横道に反れたりしながら追記してます。
基本は参考URLを見ていただき、たまにこっちに戻ってくるという感じがよいかと。
※以降【】でかこっている中項目は下記参考先の中項目タイトルに準じています。

■マストドンAWS構築チュートリアル完全版|初心者から大規模運用まで 5.お手軽な手順
http://webfood.info/mastodon-aws-tutorial/#section-5

【EC2インスタンスの作成】

インスタンススペックはt2.microを選択。
無料枠で選択できたので。

【Route53でHosted Zoneを作る】

丸々飛ばし。
DNSはお名前.comに任せる。

AWS EC2のインスタンスに固定グローバルIPを付与

AWSでは固定グローバルIP=Elastic IPと呼ばれている。
↓↓に書かれている通りに沿って進める。

■AWS EC2インスタンスにElastic IP(固定グローバルIPアドレス)を割り当てる
https://ac-5.net/aws/aws_elasticip_allocation

AWSのElastic IPを独自ドメインと関連付ける

DNSの設定。関連付ける、という言葉が正しいのかどうか。

■(お名前.com)ネームサーバーのAレコード設定
http://rensrv.com/domain/onamae-com/a_record-setting-onamae-com/

【SSHでログインする】

そのまま。

【Let’s EncryptでSSL証明書を取得する】

$ ./certbot-autoの箇所で途中、エラーで正常終了しなかった。

Requesting root privileges to run certbot...
/home/ubuntu/.local/share/letsencrypt/bin/letsencrypt
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Failed to find executable apache2ctl in PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
Certbot doesn't know how to automatically configure the web server on this system. However, it can still get a certificate for you. Please run "certbot-auto certonly" to do so. You'll need to manually configure your web server to use the resulting certificate.

apache2の起動コマンド(?)が見つからないようだ。
そもそもデフォルトでインストールされていないぽい。
↓↓
●対応:apache2インストール→再度実行

$ sudo apt-get update
$ sudo apt-get install apache2
$ ./certbot-auto

結果としてこれで成功したが、完了までにいろいろ聞かれたので参考までに記載。

●ドメイン名を入力してくれー
No names were found in your configuration files. Please enter in your domain
name(s) (comma and/or space separated) (Enter ‘c’ to cancel):

自前のドメイン名を入力して、エンター。

●HTTPSのみの接続にする?
Please choose whether HTTPS access is required or optional.
——————————————————————————-
1: Easy – Allow both HTTP and HTTPS access to these sites
2: Secure – Make all requests redirect to secure HTTPS access
——————————————————————————-
Select the appropriate number [1-2] then enter:

2の方が無難かと考え、2を入力してエンター。

●成功の確認
——————————————————————————-
Congratulations! You have successfully enabled https://(設定したドメイン)

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=(設定したドメイン)
——————————————————————————-

一応言われている通りにアクセスしたら、A評価(多少時間かかる)。

【ミドルウェアの設定】

t2.microなのでスワップ設定は飛ばし。

と思ったら後ほど出てくるdocker-composeでひっかかった。
処理が途中で止まってしまうのだが、どうやらメモリ不足が原因らしい…。

$docker-compose run --rm web rails assets:precompile

http://uyamazak.hatenablog.com/entry/2017/05/22/151210

たしかにスワップの設定後、再トライしたら処理が完了できた。

あと、念のためnginxの編集前の設定ファイルをコピーして残しておく。

cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.ort

【マストドンのセットアップ】

ここでだいぶ時間を食った…。

Docker動いてない?

ERROR: Couldn’t connect to Docker daemon at http+docker://localunixsocket – is it running?

●いろいろ対応:
・鯖再起動←たぶん関係ない。
・pip3のupgrade←アップグレードは成功したがたぶん関係ない。
 ただ、一応やったことなので残しておく。

$sudo pip3 install --upgrade pip

・インストール済かの確認

$pip3 list
docker-compose (1.13.0)

結局よくわからず↓↓を参考に入れ直す。

■今何かと話題のマストドン(mastodon)鯖を自分用に無料で立てる方法
【必要なものをインストールする】のセクション
http://jtwp470.hatenablog.jp/entry/2017/04/15/174036

その後、再度実行→成功!

$ sudo docker-compose build

以降、

$ sudo docker-compose run --rm web rake secret

から続行。
以降、assetsのdocker-composeで躓くも何とかAbout画面表示までこぎ着けた…。
まずは一旦の達成感。

【メールの設定】

今回はとりあえず自分のテスト用鯖なのでSESの制限は解除しない。
他はそのまま。

【cronの設定】

今回参照させていただいているところはマストドンのインストールディレクトリを指定しているのでcron内のパスを修正。
/home/ubuntu/mastodon→/home/ubuntu/live
他はそのまま。

ログインと管理画面

最後に、今回はとりあえず個人用インスタンスということにしているのでユーザ認証は手動で実行。
ということで↓↓を参考にさせていただきました。

■今何かと話題のマストドン(mastodon)鯖を自分用に無料で立てる方法
【初期登録と管理画面をだす方法】【管理画面の出し方】
http://jtwp470.hatenablog.jp/entry/2017/04/15/174036

なぜか手動認証のコマンドを打っても自前のgmailアカウントが見つからないと言われたので、適当な捨てアドを作り、登録し、管理画面から認証するという手順を踏みました。

さいごに

最初は探り探りだったので時間としては朝から晩までかかりました。
2回目はこの手順を残しておいたので2時間強くらいでできました。
1回目構築終わったあと、疲れなのか何なのかAWSのインスタンを消去してしまい、朝起きたときは絶望しましたが逆にこの手順が間違ってなかったことを自分で証明できてよかったよかった(?)
インスタンス構築にあたり最近の技術も勉強できたのでそれもよかった。
Dockerのことがまだはっきりと理解しきれていないので引き続き勉強ですね。

最後になりましたが、参考にさせていただいた先人たちには多大なる感謝を。
またこの記事がこれからの誰かの役に立てれば幸いです。

参考サイトまとめ

■マストドンAWS構築チュートリアル完全版|初心者から大規模運用まで
http://webfood.info/mastodon-aws-tutorial/
■AWS EC2インスタンスにElastic IP(固定グローバルIPアドレス)を割り当てる
https://ac-5.net/aws/aws_elasticip_allocation
■(お名前.com)ネームサーバーのAレコード設定
http://rensrv.com/domain/onamae-com/a_record-setting-onamae-com/
■今何かと話題のマストドン(mastodon)鯖を自分用に無料で立てる方法
http://jtwp470.hatenablog.jp/entry/2017/04/15/174036

続きを読む

AWS 認定ソリューションアーキテクト – アソシエイト 合格までに勉強したこと

概要

AWS 認定試験には「これを勉強すればいいよ!」という教科書があるわけではないので、何を勉強したらいいか分からず困っている人も多いと思います。
なので、私の勉強記録を共有します。

勉強前のスペック

AWSの初級者です。
EC2インスタンス起動やEBSのスナップショット取得の経験があるくらいでした。

勉強方法概要

AWS活用本を一冊読んで、
あとはAWS クラウドサービス活用資料集にある BlackBelt のスライド(PDF)を淡々と読みました。

その後、模擬試験を受けて本試験を受験しました。

勉強方法詳細

少し前に買っていた以下の本を読みました。分かりやすいです。

Amazon Web Services 定番業務システム12パターン設計ガイド

BlackBelt

自分が読んだ資料に○を付けました。
また、模擬試験と本試験を受けた経験から、各資料の重要度を評価しました。
※当たり前ですが、読んでいない資料の重要度は評価していません。また、重要度の正確性も保証しません。

コンピューティング

資料 読んだ  重要度 
[Amazon EC2] 
[Amazon EC2] Windows
[Amazon EC2] HPC
[Amazon EC2] リザーブドインスタンス
[Amazon EC2] スポットインスタンス
[Amazon EC2] Instance Store & Elastic Block Store
[Amazon EC2] VMImport/Export
[Elastic Load Balancing]
[Elastic Load Balancing] ロードバランサと Socket 接続を使用したイベント通知サーバの負荷分散
[Elastic Load Balancing] ELBを評価するためのベストプラクティス
[Auto Scaling]
[Amazon EC2 Container Service]
[AWS Elastic Beanstalk]
[AWS Lambda]
[AWS Lambda] update
[Amazon Lightsail]
[AWS Batch]

ストレージ & コンテンツ配信

資料 読んだ  重要度 
[Amazon EBS]
[Amazon S3] 
[Amazon CloudFront]
[Amazon CloudFront] Flash Media Server on AWS
[Amazon CloudFront] CloudFront 上限緩和申請 計算方法&申請手順
[Amazon CloudFront] まだ間に合う! Amazon CloudFront で ATS 対応
[Amazon Glacier]
[Amazon Glacier] 機能編
[AWS Storage Gateway]
[Amazon Elastic File System]

データベース

資料 読んだ  重要度 
[Amazon RDS]
[Amazon RDS] Aurora
[Amazon DynamoDB]
[Amazon ElastiCache]
[Amazon ElastiCache] Redis QA資料
[Amazon Redshift] 
[Amazon Database Migration Service]

ネットワーキング

資料 読んだ  重要度 
[Amazon VPC]
[Amazon VPC] VPN接続設定 参考資料
[AWS Direct Connect] 
[Amazon Route53]

開発者用ツール

資料 読んだ  重要度 
[AWS CodeCommit]
[AWS CodeBuild]
[AWS CodeDeploy]
[AWS CodePipeline]
[AWS SDK]
[AWS SDK] Java & .NET
[AWS SDK] PHP & Ruby & Boto(Python) & Javascript in Node.js
[AWS SDK] AWS Client side SDK Android & iOS & Javascript
[AWS CLI]
[AWS AWS Tools for Windows Powershell]

管理ツール

資料 読んだ  重要度 
[Amazon CloudWatch]
[AWS CloudFormation]
[AWS CloudTrail]
[AWS Config]
[AWS OpsWorks] AWS OpsWorksのご紹介
[AWS OpsWorks]
[AWS OpsWorks] ハンズオン
[AWS Service Catalog]
[Trusted Advisor] AWS サポート & Trusted Advisor
[Amazon EC2 Systems Manager]

セキュリティ & アイデンティ

資料 読んだ  重要度 
[Identity and Access Management (IAM)] 
[AWS CloudHSM] CloudHSM & Key Management Service
[AWS Key Management Service]
[AWS Directory Service]
[Amazon Inspector]
[AWS WAF]
[AWS Certificate Manager]

分析

資料 読んだ  重要度 
[Amazon EMR(Elastic MapReduce)]
[AWS Data Pipeline]
[Amazon Elasticsearch Service] Amazon CloudSearch & Amazon Elasticsearch Service
[Amazon Kinesis]
[Amazon QuickSight]
[Amazon Athena]

AI

資料 読んだ  重要度 
[Amazon AI]]

IoT

資料 読んだ  重要度 
[AWS IoT]

ゲーム開発

資料 読んだ  重要度 
[Amazon Lumberyard]

モバイルサービス

資料 読んだ  重要度 
[Amazon Cognito]
[Amazon Cognito] Amazon Cognito update
[Amazon Cognito] Amazon Cognito / Amazon Mobile Analytics
[AWS Device Farm]
[Amazon Mobile Analytics] Amazon Cognito / Amazon Mobile Analytics
[Amazon SNS] Amazon SNS/SQS
[Amazon SNS] モバイルプッシュ通知
[Amazon Pinpoint]  

アプリケーションサービス

資料 読んだ  重要度 
[Amazon API Gateway] 
[Amazon AppStream]
[Amazon CloudSearch] Amazon CloudSearch & Amazon Elasticsearch Service
[Amazon Elastic Transcoder]
[Amazon SES]
[Amazon SES] Amazon SES-Easy DKIM 設定サポート資料
[Amazon SQS] Amazon SNS/SQS
[Amazon Simple Workflow Service (SWF)]

エンタープライズアプリケーション

資料 読んだ  重要度 
[Amazon WorkSpaces]
[Amazon WorkDocs]
[Amazon WorkMail]
[Amazon Chime]

その他

資料 読んだ  重要度 
[Cost Explorer]
[AWS Management Console]

補足

重要度の低い資料も読んだ方がいいです。
なぜなら、マネージドサービス自体がAWSの活用事例であり、それらを知ることでシステム設計の勘所が分かるようになるからです。
また、重要度の高い機能との連携についての記載があることもあり、理解が深まります。

続きを読む

AWS Route53でAWSアカウントをまたいだPrivate Host Zoneの共有方法

Route53を使うと,VPC内だけで名前解決ができるPrivate Host Zoneが利用できる.
このPrivate Host ZoneはVPCを追加した場合には,VPCの紐付けを一々やる必要がある.
同一AWSアカウント内であれば,マネジメントコンソールからできる.

AWSアカウントをまたいだPrivate Host Zoneの共有

AWSアカウントをまたいだ場合,同一AWSアカウントのようにマネジメントコンソールから登録ができない.
公式ドキュメントのここにやり方が書いてある.

http://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/hosted-zone-private-associate-vpcs-different-accounts.html

以下のようなawsコマンドで設定する.

aws route53 create-vpc-association-authorization --vpc VPCRegion=ap-northeast-1,VPCId=vpc-xxxxxx --hosted-zone-id YOURHOSTEDZONE
aws route53 associate-vpc-with-hosted-zone --vpc VPCRegion=ap-northeast-1,VPCId=vpc-xxxxxx --hosted-zone-id YOURHOSTEDZONE

続きを読む

DynamicDNSをサーバレスで構築する

独自ドメインでDynamic DNSを実現したい場合,多くのDDNSサービスでは有料なことが多い.あるいは,運営会社の知名度が低いor微妙であることもある.

AWSのRoute53は,非常にパワフルで柔軟性のあるDNSサービスである.ここでは,Route53をDNSサーバとして,DDNSの仕組みを構築する.

シンプルな方法 – aws-cliを使う

AWSは基本的に全ての操作にAPIが用意されており,大抵の場合はAWS CLIで片付いてしまう.
以下の記事のような,スクリプトを作成してCronで更新をおこなえば済むので非常に簡単である.

http://qiita.com/tt2004d/items/21c2001bb758dfa6ddde

DynDNS互換なAPIを用意する方法

DynDNS(今はDynなのか…)はDynamicDNSサービスの老舗で,多くの家庭用ルータで対応していることが多い.
今回はVyOS互換なEdgeOS(EdgeRouterのOS)で使うことを想定した.(EdgeOSだとaws-cliを入れるのがだるい)

これをサーバレスで実現するために,以下のAWSサービスを使う.
これらのサービスであれば,Route53を除けば,定額で掛かるコストが無いので,ほとんどコストを掛けずにDDNSサーバを運用できる.(Route53は1ホストゾーンあたり$0.5/monthかかる)

  • Lambda
  • API Gateway
  • Route 53

ここまで構想があったけれど,既にまさにそれを実現しているものがいくつかあった.
以下を試したところ,EdgeRouterでもきちんと動作した.

https://github.com/sTywin/dyndns53

続きを読む

S3+CloudFrontのHTTPS静的ウェブサイトでwwwありからwwwなしにリダイレクトする

  • 2017.06.08 create

S3+CloudFrontのHTTPS静的ウェブサイトでwwwありからwwwなしにリダイレクトする設定です。
SEO対策として必要になったのでメモしておきます。
本文ではhttps://www.hogehoge.comhttps://hogehoge.com にリダイレクトするものとします。


参照URL: AWS 独自ドメインを使用して静的ウェブサイトをセットアップする


トピック

  1. HTTPS静的サイト本体(wwwなし)を作る
  2. リダイレクト用のS3バケットを作る
  3. CloudFrontのDistributionを作る
  4. DNS設定をする

1. HTTPS静的サイト本体(wwwなし)を作る

まずリダイレクト先であるHTTPS静的サイト本体を作る必要があります。
S3+CloudFront+ACM(AWS Certificate Manager)でHTTPS静的サイトを作ってみたの投稿がとても分かりやすかったので参照してください。
toshihirock様リンクさせていただきます。ありがとうございます。

2. リダイレクト用のS3バケットを作る

ここからが本題。
分かりやすくwww付きのドメイン名でS3バケットを作成します。
バケット名:www.hogehoge.com

作成できたらSバケットプロパティタブのStatic website hostingで「リクエストをリダイレクトする」を有効にします。
– [x] リクエストをリダイレクトする
  ターゲットバケットまたはドメイン: hogehoge.com
  プロトコル: https
「ターゲットバケットまたはドメイン」はwwwなしのドメイン、「プロトコル」はhttpsを指定します。

ここでStatic website hostingのエンドポイントはcloudfrontのオリジンに設定するのでメモっておきます
エンドポイント:www.hogehoge.com.s3-website-ap-northeast-1.amazonaws.com

3. CloudFrontのDistributionを作る

HTTPSなので「1.HTTPS静的サイト本体(wwwなし)を作る」と同様にcloudfrontの設定が必要になります。
先ほどメモったStatic website hostingのエンドポイントをオリジンにする以外は同様に作成します。

Origin Domain Name:www.hogehoge.com.s3-website-ap-northeast-1.amazonaws.com

CloudfrontのDomain NameはDNSの設定で必要になるのでメモっておきます。
Domain Name: hogehoge.cloudfront.net

4. DNS設定をする

Route53でDNSレコードを作成します。
ここではaliasレコードを使用しますがroute53以外のDNS環境ではCNAMEでも問題ないと思います。

Create Record Setから
 Name:www.hogehoge.com
 Type:A-IPv4 address
 Alias:YES
 TTL (Seconds):3600
 Value:hogehoge.cloudfront.net
でCreateします。Valueの値にCloudfrontのDomain Nameを指定します。

cloudfrontとDNSが反映されるまでに数分かかりますがhttps://www.hogehoge.com にアクセスしてhttps://hogehoge.com へリダイレクト出来たら成功です。

続きを読む

【AWS自分用メモ】新しいwebプロジェクトでやること

新しいwebプロジェクトに関して、やることを一覧。AWSは90種類以上のサービスがあり自分は一部しか把握していません。。。
これやったほうがいいよというサービスなどあれば教えていただけると嬉しいです。喜びます。

やることを簡単にまとめると
RDS,EC2はプライベートサブネットに配置
webサーバー2台構成で異なるAZに配置
ALBの前にWAFを使用
cloudwatchでダッシュボードやアラート作成

AWSサービス

使用サービス一覧(()内は必要であれば)
VPC IAM EC2 route53 (RDS) (cloudfront) (ACM) WAF Cloudwatch

◆VPC

構成:
・東京リージョン
・サブネットはプライベートサブネットとパブリックサブネットを各2つずつ、かつ各サブネット異なるAZ
・EC2インスタンスとRDSはすべてプライベートサブネットに作成
・クライアントのhttpリクエストは右のような流れ⇒【IGW-WAF-(cloudfront)-alb-ec2 (レスポンスはこの反対)】
・EC2がIGWを通る方法はNAT経由、右のような流れ⇒【EC2-NATGW-IGW】
・新規EC2インスタンスのsshアクセスは踏み台経由、のような流れ⇒【踏み台はユーザーと鍵認証-踏み台からsshコマンドでユーザーとパスワード認証】
・踏み台用VPC作成、プロジェクトごとのVPC作成後お互いにピアリング接続

踏み台VPC作成(踏み台がない新規AWSアカウントのみ、かつDefaultのVPC使うなら不要)

  • VPC作成
  • サブネット作成(パブリックサブネットを一つ作成)
  • IGW作成
  • ルートテーブル:ルートタブIGWをアタッチ,サブネットの関連付けタブで明示的にサブネットを当てる

新規プロジェクトのVPC作成

  • VPC作成
  • サブネット作成,PrivateSubnetをことなるAZで2つ,PublicSubnetを異なるAZで2つ作成=合計4つ作成
  • IGW作成
  • PCX作成 踏み台VPCと新規プロジェクトのVPCを作成。承認する必要あるので承認する。
  • NATゲートウェイ作成 EIP新規割り当て
  • ルートテーブル1つ作成 合計2つあるテーブルをPraivateとPublicに分けPraivateをメインにする
  • Praivateのルートテーブルのルートタブに作成したPCXとNATを登録、サブネットの関連付けタブで明示的にPrivateSubnetを2つ登録
  • Publicのルートテーブルのルートタブに作成したIGWを登録、サブネットの関連付けタブで明示的にPublicSubnetを2つ登録
  • 踏み台VPCのルートテーブルにPCXを登録

◆IAM

新規ロールをアタッチ。ポリシーは必要に応じて後でつけるので無し。

  • IAMロール作成

◆EC2

構成:
・webサーバーを2つ構成で冗長化(プライベートサブネットで各異なるAZに配置)
・必要に応じてautoscalling、リザーブドインスタンスの権利購入、など

踏み台VPCの構成

  • PublicSubnetにインスタンス作成
  • 作成したインスタンスにEIPを当てる

新規プロジェクトの構成

  • ポートセキュリティの作成 ポート:ssh,http,(https)
  • インスタンスの作成、プライベートサブネットで各異なるAZに配置、ロールの割り当て、セキュリティグループ割り当て、自動割り当てパブリックIP無効

  • ALBを作成 Publicサブネット異なるAZに配置、webサーバーを2つ登録、

  • ALBのロギング設定、セッションの維持、ヘルスチェックの変更

◆route53

  • お名前などのサービスからドメインの取得
  • route53に取得ドメインを登録
  • お名前などドメインをとったサービスからAWSのネームサーバーに変更
  • route53必要なサブドメインなど登録 (AレコードにAliasでELBのドメインを登録)
  • route53のオプション機能geolocationで国を制限

◆WAF

  • プロジェクトごとにあった設定
  • 設定後新規プロジェクトのALBに当てる

◆Cloudwatch

  • ダッシュボードの作成
  • アラートの作成

amazon linuxの中の設定

◆OS amazon linux

続きを読む

AnsibleでRoute53を管理する

はじめに

AnsibleにはAWSのリソースを操作できるモジュールが豊富に用意されています。

今回は、CLIだと何かと心が折れるRoute53をAnsibleで管理してみます。

やること

  • パブリックゾーン作成/削除
  • プライベートゾーン作成/削除
  • Aレコード他各種レコード作成/削除
  • ALIASレコード作成/削除

ポイント

ELBについては、DNS名を自動取得してALIASレコードを登録するようにします。
レコード/ゾーンの削除についてはenable: noを設定することで実現します。
未定義だからといって既存レコードを削除しないようにします。

前提

  • AWS関連のモジュール実行にはbotoが必要です。
  • credential情報は環境変数かaws configureでセットしてある必要があります。

下記リソースを前提に進めます。

  • VPC

    • AnsibleVPC

※プライベートゾーン作成時に必要

注意

ALIASレコード作成時のhosted_zone_idについては、リソースごとに固定となっています。
http://docs.aws.amazon.com/ja_jp/general/latest/gr/rande.html

sample

以下のようなDNSゾーンおよびレコードを作成します。

  • public

    • testdomain.com

      • www.testdomain.com (Aレコード)
      • text.testdomain.com (TXTレコード)
      • cname.testdomain.com (CNAMEレコード)
      • elb.testdomain.com (ALIASレコード:ELB)
      • s3.testdomain.com (ALIASレコード:s3)
  • private
    • testdomain.local

      • test.testdomain.local(Aレコード:複数IPアドレス)

ディレクトリ構成

ディレクトリ構成
site.yml
roles/
|--route53/
|  |--tasks/
|  |  |--main.yml
hosts/aws    #inventory
host_vars/
|--localhost.yml

inventory

AWSリソース関連モジュールはすべてlocalhostで実行するので、下記のようなインベントリファイルを用意します。

hosts/aws
[aws]
localhost

vars

こんな感じに変数を定義します。今回はhost_varsで定義しました。

host_vars/localhost.yml
---
my_vars:
  aws:
    common:
      region: ap-northeast-1
    vpc:
      name: AnsibleVPC    # ターゲットのVPC名
    route53:
      - name: testdomain.com
        enable: yes       # デフォルトはyes。noを指定すると削除になる
        description: public zone
        records:
          - record: www
            type: A       # 指定なしだとAレコード
            ttl: 7200     # 指定なしだと300
            record_values:
              - 10.1.1.1
          - record: text
            type: TXT
            record_values:
              - '"var"'   # このようにクォートする
          - record: cname
            type: CNAME
            record_values:
              - www.example.com
          - record: elb
            alias: yes    # ALIASレコードの場合
            target: elb   # ELBを指定するとrecord_valuesのELB名からDNS名を取得
            record_values:
              - testelb
            hosted_zone_id: Z14GRHDCWA56QT #固定値(ELB)
          - record: s3
            alias: yes
            record_values:
              - s3-website-ap-northeast-1.amazonaws.com
            hosted_zone_id: Z2M4EHUR26P7ZW #固定値(s3)
      - name: testdomain.local
        description: private zone
        private: yes      # プライベートゾーン
        records:
          - record: test
            type: A
            record_values:
              - 192.168.1.2 # 複数指定する場合
              - 192.168.1.3
              - 192.168.1.4
            enable: yes   # デフォルトはyes。noを指定すると削除になる
          - record: test2
            type: A
            record_values:
              - 192.168.1.5
            enable: no    # 削除する場合

Role

Route53はリージョン、VPCに依存しませんが、プライベートゾーン作成にはVPC情報が必要になります。
そのためのVPCを特定するためにはidが必要ですが、こちらと同様、VPC名でidを取得します。

ec2_elb_factsモジュールでELBのエイリアスレコード作成で必要となるELBのDNS名を取得し、ELB名からDNS名を参照するためにディクショナリを生成します。

roles/route53/tasks/main.yml
---
- name: vpc_id取得
  ec2_vpc_net_facts:
    region: "{{ my_vars.aws.common.region }}"
    filters:
      "tag:Name": "{{ my_vars.aws.vpc.name }}"
  register: vpc_net_fact
  check_mode: no

- name: Zone作成
  route53_zone:
    zone: "{{ item.name }}"
    state: >-
      {%- if item.enable is defined and item.enable == False -%}
        absent
      {%- else -%}
        present
      {%- endif -%}
    vpc_id: >-
      {%- if item.private is defined and item.private == True -%}
        {{ vpc_net_fact.vpcs[0].id }}
      {%- else -%}
        {{ omit }}
      {%- endif -%}
    vpc_region: >-
      {%- if item.private is defined and item.private == True -%}
        {{ my_vars.aws.common.region }}
      {%- else -%}
        {{ omit }}
      {%- endif -%}
    comment: "{{ item.description }}"
  register: route53_zone
  with_items: "{{ my_vars.aws.route53 }}"
  when: item.name is defined

- debug: var=route53_zone

- name: elb情報収集
  ec2_elb_facts:
    region: "{{ my_vars.aws.common.region }}"
    names: "{{ item.1.record_values }}"
  register: elb_facts
  with_subelements:
    - "{{ my_vars.aws.route53 }}"
    - records
  when: item.1.target is defined and item.1.target == "elb"
  check_mode: no

- name: elb dict作成
  set_fact:
    elb_dict: >-
      {%- set dict = {} -%}
      {%- for i in range(elb_facts.results|length) -%}
      {%-   if elb_facts.results[i].elbs is defined -%}
      {%-     set _ = dict.update({elb_facts.results[i].elbs[0].name: elb_facts.results[i].elbs[0].dns_name}) -%}
      {%-   endif -%}
      {%- endfor -%}
      {{ dict }}
  when: elb_facts is defined
  check_mode: no

- name: record作成
  route53:
    zone: "{{ item.0.name }}"
    private_zone: "{{ item.0.private | default('False') }}"
    command: >-
      {%- if item.1.enable is defined and item.1.enable == False -%}
        delete
      {%- else -%}
        create
      {%- endif -%}
    overwrite: yes
    record: "{{ item.1.record }}.{{ item.0.name }}"
    type: "{{ item.1.type | default('A')}}"
    alias: "{{ item.1.alias | default('False')}}"
    alias_hosted_zone_id: "{{ item.1.hosted_zone_id | default('ommit')}}"
    ttl: "{{ item.1.ttl | default('300')}}"
    value: >-
      {%- if item.1.target is defined and item.1.target == "elb" -%}
        {{ elb_dict[item.1.record_values.0] }}
      {%- else -%}
        {{ item.1.record_values | join(',') }}
      {%- endif -%}
  register: route53_record
  with_subelements:
    - "{{ my_vars.aws.route53 }}"
    - records
  when: item.0.enable is undefined or item.0.enable == True

- debug: var=route53_record  

site.yml

site.yml
---
- name: route53
  hosts: localhost
  connection: local
  roles:
    - role: route53

実行

Command
$ ansible-playbook -i hosts/aws -l localhost site.yml

まとめ

Route53のコード化については、RoadWorkerというツールが非常に強力で、以前活用していたのですが、Ansibleでも同様のことができます。
リソース定義もYAMLの方が個人的にはわかりやすいです。

参考

AnsibleでAWSリソースを管理するシリーズ

続きを読む