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化

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

- 前回書いた[記事](http://qiita.com/hirofumihida/items/f40b98091588c97629b2)から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

```shell-session
% 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 インスタンスを起動
1. Version 3.2.1 のデータバックアップ
    - Bitnami Redmine Stack の停止
    - MySQL Dump 取得
1. Version 3.3.3 へのデータ復元
    - Bitnami Redmine Stack の停止
    - MySQL Dump 復元
    - Bitnami Redmine Stack の開始
1. 動作確認

## 参考資料

- http://docs.aws.amazon.com/cli/latest/reference/
- https://docs.bitnami.com/aws/apps/redmine/#how-to-upgrade-redmine

## 作業手順

### 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 から作るも良し
以下コマンド実行例

```shell-session:set-env
KEY_NAME=aws-nvirginia-default001.pem
echo $KEY_NAME
```
```shell-session:check-ami
aws ec2 describe-images \
    --filters "Name=image-id,Values=ami-15f98503"
```
```shell-session:check-ami-name
aws ec2 describe-images \
    --filters "Name=image-id,Values=ami-15f98503" \
    | jq ".Images[].Name" \
    | grep --color redmine-3.3.3
```
```shell-session: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
```
```shell-session:set-env
INSTANCE_ID=i-0f8d079eef9e5aeba
echo $INSTANCE_ID
```
```shell-session:add-name-tag-to-instance
aws ec2 create-tags --resources $INSTANCE_ID \
    --tags Key=Name,Value=redmine-3.3.3
```

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

```shell-session:check-instance-created
aws ec2 describe-instances --filter "Name=instance-id,Values=$INSTANCE_ID"
```
```shell-session:wait-running-state
aws ec2 describe-instances \
    --filter "Name=instance-id,Values=$INSTANCE_ID" \
    | jq '.Reservations[].Instances[].State["Name"]'
```
```shell-session:get-redmine-password
aws ec2 get-console-output \
    --instance-id $INSTANCE_ID \
    | grep "Setting Bitnami application password to"
```
```shell-session:get-publicip
aws ec2 describe-instances \
    --filter "Name=instance-id,Values=$INSTANCE_ID" \
    | jq '.Reservations[].Instances[].NetworkInterfaces[].Association'
```
```shell-session:set-env
PUBLIC_IP=54.243.10.66
echo $PUBLIC_IP
```
```shell-session:site-check
curl -I http://$PUBLIC_IP/
HTTP/1.1 200 OK
(snip)
```
```shell-session:ssh-connect
ssh -i .ssh/$KEY_NAME bitnami@$PUBLIC_IP
```
```shell-session:first-login
bitnami@new-version-host:~$ sudo apt-get update -y
bitnami@new-version-host:~$ sudo apt-get upgrade -y
```
```shell-session
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"
```
```shell-session
bitnami@new-version-host:~$ sudo ./stack/ctlscript.sh status
subversion already running
php-fpm already running
apache already running
mysql already running
```
```shell-session
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. 旧バージョンのバックアップ取得

```shell-session: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:~$
```
```shell-session:check-status
bitnami@old-version-host:~$ sudo stack/ctlscript.sh status
subversion already running
php-fpm already running
apache already running
mysql already running
```
```shell-session: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
```
```shell-session: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
```
```shell-session: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% /
```
```shell-session:load-env-setting
bitnami@old-version-host:~$ . stack/use_redmine
bitnami@old-version-host:~$ echo $BITNAMI_ROOT
/opt/bitnami
```
```shell-session: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 で表示させておいて旧環境のコンソール上にコピペしました。

```shell-session:example
bitnami@old-version-host:~$ vi .ssh/aws-nvirginia-default001.pem
bitnami@old-version-host:~$ chmod 600 .ssh/aws-nvirginia-default001.pem
```

- ファイル転送

```shell-session:file_transfer
bitnami@old-version-host:~$ scp -i .ssh/aws-nvirginia-default001.pem redmine_backup.sql <new-version-host-ipaddr>:~
```

- 新バージョン側にファイルが届いているか確認

```shell-session:check-transfered-files
bitnami@new-version-host:~$ ls -alh redmine*
```

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

```shell-session: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
```
```shell-session:start-mysql
bitnami@new-version-host:~$ sudo stack/ctlscript.sh start mysql
```
```shell-session: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
```
```shell-session:restore-dumpfile
bitnami@new-version-host:~$ mysql -u root -p bitnami_redmine < redmine_backup.sql
Enter password:
bitnami@new-version-host:~$
```
```shell-session:edit-line-18
bitnami@new-version-host:~$ vi /opt/bitnami/apps/redmine/htdocs/config/database.yml

    18	  password: "DATABASE_PASSWORD"
```
```shell-session: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
```
```shell-session: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
```
```shell-session: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 で証明書を取得します
    - コマンドでリクエストしてます

```shell-session
aws acm request-certificate --domain-name redmine.hogefuga.net
```
```shell-session: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. ステータス確認

```shell-session: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 をつくる

```shell-session: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. インスタンスをくっつける

```shell-session:example
aws elb register-instances-with-load-balancer \
    --load-balancer-name redmine-elb1 \
    --instances i-0f8d079eef9e5aeba
```

- 4-7. State が InService になるまで待ちます

```shell-session:example
aws elb describe-instance-health \
    --load-balancer-name redmine-elb1
```

- 4-8. DNS Name を確認する(4-10. で使います)

```shell-session:example
aws elb describe-load-balancers \
    --load-balancer-name redmine-elb1 \
  | jq ".LoadBalancerDescriptions[].DNSName"
```
- 4-9. 今の設定を確認

```shell-session:example
aws route53 list-resource-record-sets \
    --hosted-zone-id Z3UG9LUEGNT0PE | jq .
```

- 4-10. 投入用の JSON をつくる

```shell-session:example
vi change-resource-record-sets.json
```
```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. 設定投入

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

4-12. 設定確認

```shell-session:example
aws route53 list-resource-record-sets \
    --hosted-zone-id Z3UG9LUEGNT0PE
```

4-13. ブラウザ確認

```
https://redmine.hogefuga.net
```

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

- グローバルの TCP:80 削除
- サブネット内の TCP:80 許可

```shell-session:check
aws ec2 describe-security-groups --group-ids sg-b7d983c8
```

```shell-session:change
aws ec2 modify-instance-attribute \
    --instance-id i-0f8d079eef9e5aeba \
    --groups sg-b7d983c8
```

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