AWS勉強会(補足1) / ユーザーデータでEC2作成時の初期設定を行う

「ユーザーデータ」を使って、EC2の作成時に、追加で`httpd`パッケージを入れたりタイムゾーンを設定することができる。

[Linux インスタンスでの起動時のコマンドの実行 - Amazon Elastic Compute Cloud](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/user-data.html)

以下、基本的にAmazon Linux AMI 2018.03.0 (HVM)の場合。
(2018.09.04: Ubuntu(Ubuntu Server 16.04 LTS)の場合の設定を追記)

# ユーザーデータってどこで設定するの？

EC2のインスタンス作成の「ステップ3: インスタンスの詳細の設定」の下のところの「高度な詳細」(日本語変だよな)を押下すると設定画面がでてくる。
(スクリプトはrootユーザで実行される)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/256859/15c75e5d-d1b1-8f0c-7140-cfa7e75210f2.png)

# シェルスクリプトを設定する

## 設定

一番単純な設定方法は、ここにシェルスクリプトを記述する。

たとえば、`httpd`をインストールし、EC2起動後にwebサーバも起動しておくのであれば、次のようなシェルスクリプトをテキストフィールドに入力する。

```sh
#!/bin/sh

yum install -y httpd
/etc/init.d/httpd start
```

※ debian/ubuntu系であれば`apt install -y apache2`、systemd系であれば`systemctl start`とか使用する(要は環境に合わせて作成してください)

## 実行結果

EC2起動後、ユーザーデータの実行結果は、`/var/log/cloud-init-output.log`で確認できる。


※ ちなみにこのシェルスクリプトでタイムゾーンの設定(`/etc/localtime`,`/etc/sysconfig/clock`)を行っても起動したEC2には反映されなかったので、処理のタイミングの問題かな？

# cloud-initを使った設定

入力欄の1行目に`#cloud-config`と記述すると、以降の内容はcloud-initを使った設定として認識される。
コマンドの実行だけでなく、EC2の様々な設定が可能。

- [ユーザーデータと cloud-init ディレクティブ](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/user-data.html#user-data-cloud-init)
- [Documentation — Cloud-Init 18.3 documentation](https://cloudinit.readthedocs.io/en/latest/index.html)

機能一覧は [Modules](https://cloudinit.readthedocs.io/en/latest/topics/modules.html) のページ、設定例は [Cloud config examples](https://cloudinit.readthedocs.io/en/latest/topics/examples.html) を見ると良さそう。

## パッケージインストール

`packages`を使う。
`httpd`と`php`をインストールする場合は以下のように書く。

```
#cloud-config

packages:
 - httpd
 - php
```

## タイムゾーン設定

https://cloudinit.readthedocs.io/en/latest/topics/modules.html#timezone

"Asia/Tokyo"にタイムゾーンを設定する場合は以下のように書く。

```
#cloud-config

timezone: "Asia/Tokyo"
```

これでEC2が9時間ズレなくなる。

## 任意のコマンドを実行する

sshdのListen Portをデフォルトの22でなく10022に変更する。
([SSH Modules](https://cloudinit.readthedocs.io/en/latest/topics/modules.html#ssh)はあるけどポート番号の変更に関する設定はなさげだったので、設定ファイルを直接書き換えている)

```
#cloud-config

runcmd:
 - sed -i -e 's!#Port 22!Port 10022!' /etc/ssh/sshd_config
 - /etc/init.d/sshd restart
```

※ デフォルトポートを変更すると、ピンポンダッシュが激減しますが、この有効性についてはとりあえずここでは議論しません

## 全てまとめると…

```
#cloud-config

packages:
 - httpd
 - php

timezone: "Asia/Tokyo"

runcmd:
 - sed -i -e 's!#Port 22!Port 10022!' /etc/ssh/sshd_config
 - /etc/init.d/sshd restart
```

EC2が起動してログインしてチェック。

```
zaki@wensley% date
2018年 9月  2日 日曜日 14:28:12 JST
zaki@wensley%
zaki@wensley% ssh -i ~/.ssh/aws-practice.pem ec2-user@13.115.229.127 -p 10022
The authenticity of host '[13.115.229.127]:10022 ([13.115.229.127]:10022)' can't be established.
ECDSA key fingerprint is SHA256:5H8syAwUi6DdSlJlsnKWnrdlzuSAmQ466RXxjLLn8NY.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[13.115.229.127]:10022' (ECDSA) to the list of known hosts.

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/
2 package(s) needed for security, out of 3 available
Run "sudo yum update" to apply all updates.
[ec2-user@ip-172-26-10-207 ~]$ date
Sun Sep  2 14:28:22 JST 2018
[ec2-user@ip-172-26-10-207 ~]$ rpm -qa | grep httpd
httpd-tools-2.2.34-1.16.amzn1.x86_64
httpd-2.2.34-1.16.amzn1.x86_64
[ec2-user@ip-172-26-10-207 ~]$ rpm -qa | grep php
php-cli-5.3.29-1.8.amzn1.x86_64
php-5.3.29-1.8.amzn1.x86_64
php-common-5.3.29-1.8.amzn1.x86_64
[ec2-user@ip-172-26-10-207 ~]$ sudo netstat -tanp | grep ssh
tcp        0      0 0.0.0.0:10022               0.0.0.0:*                   LISTEN      2695/sshd           
tcp        0     36 172.26.10.207:10022         119.224.241.162:50449       ESTABLISHED 2740/sshd           
tcp        0      0 :::10022                    :::*                        LISTEN      2695/sshd           
[ec2-user@ip-172-26-10-207 ~]$ 
```

httpdもphpもインストールされてタイムゾーンも正しくsshも10022でListenしている。

ubuntuで同じことをやろうとする場合の変更点は以下の通り。

- webサーバのパッケージ名が`apache2`
- `sshd_config`のポートの設定はコメントアウトされてない
- init.dスクリプトは`sshd`でなく`ssh`
- ※ タイムゾーンの設定は変更なし

```
#cloud-config

packages:
 - apache2
 - php

timezone: "Asia/Tokyo"

runcmd:
 - sed -i -e 's!Port 22!Port 10022!' /etc/ssh/sshd_config
 - /etc/init.d/ssh restart
```