Amazon AWS Cloud9 開発環境を速攻で作る方法

2021.01.22 追記

この方法では開発環境が作れなくなっていました。
新しい作り方を記事にしましたので、こちらを参照してください

https://qiita.com/qwe001/items/d3270b0de7f8b17a4f85

## はじめに

https://docs.aws.amazon.com/ja_jp/cloud9/latest/user-guide/sample-lamp.html

公式サイトに書いてある手順に従うだけです。
新しい開発環境を作るたび、毎回手順を忘れてしまう鶏頭なので、
自分用の備忘録ついでに書き留めました。

これからの時代はAWSですよ。

## 要件

* Apache 2.4以上
* PHP 7.3以上

Cloud9のデフォルトはPHP5.6.40なので、
バージョンアップする必要があります(環境構築のところで行います)

## インスタンスを作成

https://ap-northeast-1.console.aws.amazon.com/cloud9/home?region=ap-northeast-1

1. 上記のサイトにアクセス
2. 画面右上のリージョン表記が「東京」であることを確認。違う場合は「東京」に変更
 * 何か特別な理由がある場合は別のリージョンでも良い。
 * 筆者は「バージニア北部」でも作っている。
 * 特に理由はなかったと思う。(昔は東京リージョンがなかったからとか、そんな理由だったような)
3. 「Create environment」ボタンをクリック
4. Step 1 Name environment
 * 開発環境の名前と説明。
 * 各項目の入力内容を次のとおり設定する
 * 「Name」に開発予定のプロジェクト名を入力する ※必須
     * なんでもいいが、英数字のみで入力するのが無難
 * 「Description」にプロジェクトの説明を入力する ※任意
     * 日本語を入力しても良し
5. Step 2 Configure settings
 * 開発環境の基本的な設定。
 * 各項目の入力内容を次のとおり設定する
 * Environment type - Create a new instance for environment (EC2)
 * Instance type - t2.micro (1 GiB RAM + 1 vCPU)
 * Platform - Amazon Linux
 * Cost-saving setting - After 30 minutes (default)
 * IAM role - AWSServiceRoleForAWESCloud9 ※変更できない
 * Network settings (advanced) - 何も変更しない
 * Add new tag - 何も設定しない
 * ここまで出来たら「Next step」ボタンをクリック
6. Step 3 Review
 * 設定内容の確認。
 * 「Create environment」ボタンをクリック
7. 開発環境の構築が完了するまで待つ
 * ネットワーク速度にもよるが、だいたい5分以内に完了する
 * ターミナル画面( `bash - "ip-***-**-**-***"` みたいなのが書いてあるタブ)が操作できるようになったらOK

## 【初回のみ】環境構築

### 外観のカスタマイズ

デフォルトだと文字サイズが12pxで、老眼にはつらいので、もうちょっち上げます

1. 画面左上 ツールバー Cloud9アイコン -> Preferences (Ctrl-,) をクリック
2. サイドバーから User Settings -> Terminal をクリック
 * Font Size を 14 にする
 * Antialiased Fonts を チェック
 * Blinking Cursor を チェック
3. サイドバーから User Settings -> Code Editor (Ace) をクリック
 * Font Size を 14 にする
 * Antialiased Fonts を チェック

あとデフォルト背景が白のため、ドライアイにもきついので、黒系の外観にします

1. 画面左上 ツールバー View -> Themes -> UI Themes -> Jett Dark をクリック
2. 画面左上 ツールバー View -> Themes -> Monokai をクリック
 * お好みで。私は Sublime Text 3 をよく使ってたので

【重要】隠しファイルを表示する設定にします。「 `.htaccess` 」などを表示するためです

1. 画面左上 プロジェクト名の右の歯車アイコンをクリック
2. Show Hidden Files をクリック

あとはPreferencesの設定項目じっくり眺めてお好みでカスタマイズしてください

### PHPのバージョンアップ

PHPのバージョンを7.3にアップデートします。

ターミナル画面( `bash - "ip-***-**-**-***"` みたいなのが書いてあるタブ)で、
以下のコマンドを上から順に実行する。

単に全行コピペしてCtrl+Vで貼り付ければOK
(貼り付けた瞬間に実行されるので注意)

```bash
# パッケージを更新 念の為
sudo yum -y update
# Apache2.4に更新 念のため 最初から2.4なので特に何も起きないはず
sudo yum install -y httpd24
# php5.6を一式アンインストール(必要ないかもしれんが念のため)
sudo yum remove -y php56*
# PHP7.3をインストール
sudo yum install -y php73*
# 現時点ではphpコマンドはPHP5.6を使用しているので、リンクをつけなおす
sudo unlink /usr/bin/php
# これでPHP7.3が使用される
sudo ln -s /etc/alternatives/php7 /usr/bin/php
# PHPバージョンの確認(PHP 7.3.17が表示されたら成功。失敗したら知らん)
php -v
```

### ウェブサイトの設定

現時点では、 `sudo service httpd start` としたところでウェブページが表示されません
それを表示されるようにします。書き込み権限割り当てとかそんな感じのことしてます。
一種のおまじないです。

ターミナル画面( `bash - "ip-***-**-**-***"` みたいなのが書いてあるタブ)で、
以下のコマンドを上から順に実行する。

単に全行コピペしてCtrl+Vで貼り付ければOK
(貼り付けた瞬間に実行されるので注意)

```bash
sudo groupadd web-content # Create a group named web-content.

sudo usermod -G web-content -a ec2-user # Add the user ec2-user (your default user for this environment) to the group web-content.

sudo usermod -G web-content -a apache # Add the user apache (Apache HTTP Server) to the group web-content.

sudo chown -R ec2-user:web-content /var/www/html # Change the owner of /var/www/html and its files to user ec2-user and group web-content.

sudo find /var/www/html -type f -exec chmod u=rw,g=rx,o=rx {} \; # Change all file permissions within /var/www/html to user read/write, group read-only, and others read/execute. 

sudo find /var/www/html -type d -exec chmod u=rwx,g=rx,o=rx {} \; # Change /var/www/html directory permissions to user read/write/execute, group read/execute, and others read/execute.

sudo touch /var/www/html/index.php && sudo chown -R ec2-user:web-content /var/www/html/index.php && sudo chmod u=rw,g=rx,o=rx /var/www/html/index.php && sudo printf '%s\n%s\n%s' '<?php' '  phpinfo();' '?>' >> /var/www/html/index.php
```

2020.07.16 追記

大事なおまじないが抜けていました…
何やってるのかよくわかんないですが、全行コピペしてターミナルに貼り付けてください(初回のみ)

```bash
MY_INSTANCE_ID=$(curl http://169.254.169.254/latest/meta-data/instance-id) # Get the ID of the instance for the environment, and store it temporarily.
           
MY_SECURITY_GROUP_ID=$(aws ec2 describe-instances --instance-id $MY_INSTANCE_ID --query 'Reservations[].Instances[0].SecurityGroups[0].GroupId' --output text) # Get the ID of the security group associated with the instance, and store it temporarily.

aws ec2 authorize-security-group-ingress --group-id $MY_SECURITY_GROUP_ID --protocol tcp --cidr 0.0.0.0/0 --port 80 # Add an inbound rule to the security group to allow all incoming IPv4-based traffic over port 80.

aws ec2 authorize-security-group-ingress --group-id $MY_SECURITY_GROUP_ID --ip-permissions IpProtocol=tcp,Ipv6Ranges='[{CidrIpv6=::/0}]',FromPort=80,ToPort=80 # Add an inbound rule to the security group to allow all incoming IPv6-based traffic over port 80.

MY_SUBNET_ID=$(aws ec2 describe-instances --instance-id $MY_INSTANCE_ID --query 'Reservations[].Instances[0].SubnetId' --output text) # Get the ID of the subnet associated with the instance, and store it temporarily.

MY_NETWORK_ACL_ID=$(aws ec2 describe-network-acls --filters Name=association.subnet-id,Values=$MY_SUBNET_ID --query 'NetworkAcls[].Associations[0].NetworkAclId' --output text) # Get the ID of the network ACL associated with the subnet, and store it temporarily.

aws ec2 create-network-acl-entry --network-acl-id $MY_NETWORK_ACL_ID --ingress --protocol tcp --rule-action allow --rule-number 10000 --cidr-block 0.0.0.0/0 --port-range From=80,To=80 # Add an inbound rule to the network ACL to allow all IPv4-based traffic over port 80. Advanced users: change this suggested rule number as desired.

aws ec2 create-network-acl-entry --network-acl-id $MY_NETWORK_ACL_ID --ingress --protocol tcp --rule-action allow --rule-number 10100 --ipv6-cidr-block ::/0 --port-range From=80,To=80 # Add an inbound rule to the network ACL to allow all IPv6-based traffic over port 80. Advanced users: change this suggested rule number as desired.

MY_PUBLIC_IP=$(curl http://169.254.169.254/latest/meta-data/public-ipv4) && echo http://$MY_PUBLIC_IP/index.php # Get the URL to the index.php file within the web server root.
```

### シンボリックリンクを設定

Apacheのドキュメントルートは `/var/www/html/index.php` になっています。
ただ、Cloud9のデフォルトディレクトリは `/home/ec2-user/environment/` になっています。
ドキュメントルートをお気に入りのパスに設定してもいいんですが、
私は横着なのでCloud9のデフォルトディレクトリの下にドキュメントルートのシンボリックリンクを貼って、
すぐに開発作業が出来るようにしました。

Apacheの設定ファイルの記述的に、
`/home/{{ サイト名 }}/public_html/` みたいな構成にしたほうがよさそうですが、
動けばなんでもええねん。

```bash
sudo ln -s /var/www/html /home/ec2-user/environment/
```

### ブラウザで表示確認

ターミナル画面(bash - "ip-***-**-**-***"みたいなのが書いてあるタブ)で、
以下のコマンドを上から順に実行する。

```bash
sudo service mysqld start
sudo service httpd start
curl -q http://169.254.169.254/latest/meta-data/public-ipv4 -w "\n"
```

最後のコマンドで、IPアドレスが表示されます。
それが開発環境のURLです。
そのIPアドレスをコピペして、ブラウザのURL欄に貼り付けてアクセスします。

phpinfoの内容が出てくればOKです。

以上で環境構築は完了です。お疲れ様でした。

## 【次回以降】開発環境を立ち上げるには

### インスタンスの起動

https://ap-northeast-1.console.aws.amazon.com/cloud9/home?region=ap-northeast-1

1. 上記のサイトにアクセス(リージョン確認などの手順は割愛)
2. 任意のプロジェクトをクリック
3. 「Open IDE」ボタンをクリック

### WEBサーバーを立ち上げる

ターミナル画面( `bash - "ip-***-**-**-***"` みたいなのが書いてあるタブ)で、
以下のコマンドを実行する。

```bash
sudo service mysqld start; sudo service httpd start; curl -q http://169.254.169.254/latest/meta-data/public-ipv4 -w "\n"
```

表示されるIPアドレスをコピペして、ブラウザのURL欄に貼り付けてアクセスします。

## 開発環境を終了するには

単にタブを閉じれば良いです。
無操作状態が30分継続すれば、自動でインスタンスを停止してくれます。

## おまけ

Cloud9のデフォルトのタイムゾーン設定はUTC(国際標準時)になっています。
開発するプロジェクトによってはJST(日本時間)のほうが良いので、
変更方法を追記します。

```bash
sudo cp /etc/sysconfig/clock /etc/sysconfig/clock.org

sudo vim /etc/sysconfig/clock
```

「ZONE="UTC"」を「ZONE="Asia/Tokyo"」へ書き換えます。

```bash
ZONE="UTC"
UTC=true
↓
ZONE="Asia/Tokyo"
UTC=true
```

ローカル時間を日本時間に変更します

```bash
sudo ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
```

また、PHPのデフォルトタイムゾーンが設定されていないので、
現時点では `date()` 関数を使ってもUTC時間が表示されます。
同様に日本時間を設定しましょう

```bash
sudo cp /etc/php-7.3.ini /etc/php-7.3.ini.org
sudo vi /etc/php-7.3.ini
```

```php
[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
;date.timezone =

↓
[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
;date.timezone =
date.timezone = "Asia/Tokyo"
```

ここまでできたら再起動します(IPアドレスが変わるので注意)

```bash
sudo reboot
```

再起動後、動作確認

```bash
$ cat /etc/sysconfig/clock
ZONE="Asia/Tokyo"
UTC=true

$ cat /etc/localtime
TZi۫ڀ~~JDTJSTTZif2
                        e¤p۫ڀLMTJDTJST
JST-9

$ date
Tue Jul  7 10:23:08 JST 2020

$ php -r 'print(date("Y-m-d H:i:s") . "\n");'
2020-07-07 10:23:08
```

## 追記(2020.07.30)

久しぶりに環境構築してみたら、PHPフレームワークが動かないという問題が発生しました。
原因は、リダイレクトが効いていないためでした。

私がPHPをアンインストールしたことが原因でしょうか？
もし、同じような現象に遭遇したら、次の通りすれば動くと思います。

```bash

$ sudo cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.bak
$ sudo vi /etc/httpd/conf/httpd.conf
```

/Directory "/var/www/html" を入力して、ドキュメントルートへの記述を探し、
AllowOverride None を AllowOverride All に変更する

```apache

    #
    # AllowOverride controls what directives may be placed in .htaccess files.
    # It can be "All", "None", or any combination of the keywords:
    #   Options FileInfo AuthConfig Limit
    #
    #AllowOverride None
    AllowOverride All
```

そしてApacheを再起動

```bash

$ sudo service httpd restart
```