AWSでゼロからUbuntuを立ち上げるまで

**Amazon EC2** の初期導入を代行した。
2019年7月時点のAWS画面を用いて、クラウド初級者向けに実例を示して手順を説明する。

ここではアカウントの新規作成から始め、下図のような構成を１時間で構築してみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/efb3d122-f3d7-9db2-a017-d97155f6243b.png)

# AWSアカウントの作成
何はともあれアカウントを作成しなければ始まらない。公式チュートリアルの [AWSアカウント作成の流れ](https://aws.amazon.com/jp/register-flow/) に沿って進めよう。
アカウント作成後は、下表チェックリストに従って速やかにセキュリティ対策を行うこと。

| 確認事項 | チェック |
|:--|:-:|
|ルートアカウント（特権ユーザ）のMFA（多要素認証）を有効にしたか？|:heavy_check_mark:|
|日常の操作にルートアカウントを使うことがないように、管理用のIAMユーザを作成したか？|:heavy_check_mark:|
|アクセス許可の管理を容易にするため、IAMグループを作成したか？|:heavy_check_mark:|
|強力なIAMパスワードポリシーを設定したか？ |:heavy_check_mark:|
|未使用のアクセスキーは削除されているか？ |:heavy_check_mark:|
具体的な手順は[@tmknomさん](https://qiita.com/tmknom)の記事、[AWSアカウントを取得したら速攻でやっておくべき初期設定まとめ](https://qiita.com/tmknom/items/303db2d1d928db720888)に書かれているので参照して欲しい。

# AWSマネジメントコンソールにログイン
ルートアカウントはもう使わないのでログアウトし、先ほど作成した**管理者用IAMユーザ**でコンソールにログインしなおす。

## 経理部門用IAMユーザの作成
請求情報の確認のみができるIAMユーザを作成する。
経理担当者にこのIAMユーザを貸与することで、技術部門への照会を減らすことができるし、経理部門が誤ってサービスを停止してしまうこともない。

### ポリシーの作成
IAMのメニュー **[ポリシー]** :arrow_right: **[ポリシーの作成]** をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/9febec45-def9-52f4-2712-bc2203e783ec.png)
AWSユーザーガイド[【例8：アカウント設定へのアクセスは拒否し、その他の請求および使用状況の情報へのフルアクセスは許可する】](https://docs.aws.amazon.com/ja_jp/awsaccountbilling/latest/aboutv2/billing-permissions-ref.html#example-billing-deny-modifyaccount)のJSONテキストをコピペする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/63ff8536-59e8-27cb-17c5-f517ac91084c.png)

```json:JSON
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "aws-portal:*Billing",
                "aws-portal:*Usage",
                "aws-portal:*PaymentMethods"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Deny",
            "Action": "aws-portal:*Account",
            "Resource": "*"
        }
    ]
}
```

### グループの作成
IAMのメニュー **[グループ]** :arrow_right: **[新しいグループの作成]** から任意の名前でグループを作成し、前項のポリシーをアタッチする。

### ユーザーの作成
IAMのメニュー **[ユーザー]** :arrow_right: **[ユーザーを追加]** から任意の名前でユーザーを作成し、前項のグループに追加する。 

### 請求ダッシュボード
経理部門が見る請求ダッシュボード（オンデマンドインスタンス＝従量課金）の例を示す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/152f2a6c-f924-1460-6313-dfc21009462e.png)
請求書の画面では、EC2リソースごとに詳細な内訳を見ることができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/01d9f381-98c6-320a-76de-0b998c1036df.png)
PDF版請求書をメールで受け取ることもできる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/aba81702-9bde-6d6a-37e1-6825b92e1c7b.png)
リザーブドインスタンス（固定料金）への切り替えは、リソースの分析後スペックが固まってからでも良いだろう。

## インスタンスの作成
メニュー **[EC2]** を選択する。作成前に今の**リージョン**を確認しておこう。（今回は東京を選択する）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/416b78b5-1973-996e-5edb-59b1d33d6d4f.png)

EC2のメニュー **[インスタンス]** :arrow_right: **[インスタンスの作成]** をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/dec47853-348f-9e6f-da90-3c5c91a3756c.png)

### Amazonマシンイメージ(AMI)の選択
**AMI**には、AWSが提供するもの、ユーザーコミュニティが提供するもの、ソフトウェアベンダーが提供するもの（Marketplace）がある。
今回は、Marketplaceから`Ubuntu 18.04`を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/0d9827d6-dd7e-e4aa-6344-b5dc5285d420.png)

### インスタンスタイプの選択
ここでは`m5.large`を選択（１時間当たり約13円）。今あえて前世代の`m4.large`を選択する理由も無いだろう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/f4077be3-a2cc-66b4-5811-d29fd22f22f8.png)
:book: [Amazon EC2 インスタンスタイプ](https://aws.amazon.com/jp/ec2/instance-types/)

### インスタンスの詳細の設定
今回は何も考えずに、デフォルトで追加された**VPC**（Virtual Private Cloud）をそのまま使う。
インスタンスを誤って削除しないように、**[削除保護の有効化]**をチェックしておくと安全だ。

なお、インスタンスを複数作成するときは、インスタンスの用途（例えば専用のDBサーバなど）に応じてプライベートサブネットを作ることがあるが、今回はインスタンス（Web/DBサーバ）がひとつしか無いので、そのままデフォルトのパブリックサブネットに置く。

### ストレージの追加
IoT機器からセンサーのデータを受け取るため、パーティションを下表のように分割した。

|デバイス&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|容量|マウント先|備考|
|:--------|----:|:-------|:--|
|/dev/sda1| 30GB|/       |   |
|/dev/sdb |100GB|/data   |MongoDB（スキーマレスのNoSQL型データベース）で使うため、IOPS重視とする。|
|/dev/sdc |500GB|/archive|ログやビッグデータなど大量データを保存するのに使うため、スループット重視とする。|
IOPSとスループットの関係はバケツリレーに例えると分かり易い。往復回数がIOPS、水の総量がスループット、ゆえにバケツのサイズに影響する、と考えれば良い。

**[新しいボリュームの追加]** をクリックし、次のように入力。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/88aa0596-25b8-5cf0-841f-f19c5b238158.png)
:book: [Amazon EBS ボリュームの種類](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/EBSVolumeTypes.html)
:book: [Amazon EBS の料金](https://aws.amazon.com/jp/ebs/pricing/)

### セキュリティグループの設定
VPCにデフォルトのセキュリティグループがあるので、設定を変更する。
要はファイアウォールのことだ。特に解説は不要だろう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/ea511380-211b-bf87-bbf6-b1f90eb55f9e.png)
デフォルトでは、インバウンドはすべて拒否、アウトバウンドはすべて許可となっている。
:book: [VPC のセキュリティグループ](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/VPC_SecurityGroups.html)

### 新しいキーペアの作成
インスタンス作成の最終工程である。
**[キーペアのダウンロード]**、**[インスタンスの作成]** の順にクリックすれば完了する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/df8719fa-edfa-463a-0a1a-8455a0a6840e.png)
もし、下のようなメッセージが出ても、暫くして再試行すれば問題ないので慌てずに。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/6dbc3815-94cd-a72b-7c90-b40ab2f86f42.png)

## IPアドレスを割り当てる
インスタンス作成時に自動付与されたパブリックIPアドレス（グローバルIPアドレス）は変化する場合があるので、固定化する。
EC2のメニュー **[Elastic IP]** :arrow_right: **[新しいアドレスの割り当て]** をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/d4b7c7f9-881b-101d-9b61-3eaf71db4b76.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/da9e8f47-3513-50ca-9851-cab4cd62f651.png)

### IPアドレスをインスタンスに関連付ける
割り当てされたIPアドレスを選択し、アクションメニューからインスタンスに関連付けよう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/ebcb56c3-f0d7-1771-d6bb-96a942f5d102.png)
リソースタイプに**インスタンス**、インスタンスには**インスタンスID**を指定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/d57c4951-1458-3fc4-b394-adda1ae65f7f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/67e7a223-cbe5-7869-6d15-38782c4c57ef.png)

以上でコンソール側の操作は終わりだ。
なお、インターネットゲートウェイはデフォルトVPCに最初からアタッチされている。

# Linuxの初期設定
インスタンス作成時にダウンロードしたキーペア（秘密鍵）を使い、サーバにログインする。
Ubuntuの場合、初期ユーザー名は`ec2-user`ではなく`ubuntu`になる。

### パッケージ更新

```
sudo -i
apt -y update
apt -y upgrade
```

### パーティション作成
`lsblk`コマンドで、SSDやHDDなどのブロックデバイス一覧を表示する。

```
$ lsblk
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
loop0         7:0    0 88.4M  1 loop /snap/core/7169
loop1         7:1    0   18M  1 loop /snap/amazon-ssm-agent/1335
nvme0n1     259:0    0  100G  0 disk 
nvme2n1     259:1    0  500G  0 disk 
nvme1n1     259:2    0   30G  0 disk 
└─nvme1n1p1 259:3    0   30G  0 part /
```

Nitro世代（ニトロではなくナイトロと読むらしい）のインスタンスでは、NVMeデバイス名に名前が変わるので注意。
例えば `/dev/sda1` が `/dev/nvme1n1p1` という具合だ。

デバイス名が分かったらフォーマットし、マウントを試みる。

```
mkfs -t ext4 /dev/nvme0n1
mkdir /data
mount /dev/nvme0n1 /data
```

マウントに成功したら`fstab`に登録しよう。
デバイス名は変わる可能性があるので、起動時のマウントはUUIDにすべきだ。
UUIDは`mkfs`したときに表示される他、`blkid`コマンドでも確認できる。

```:/etc/fstab
UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx  /data  ext4  defaults,nofail  0 2
```

### 日本語化
これはお好みで。

```
apt -y install language-pack-ja-base language-pack-ja ibus-mozc
localectl set-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja"
source /etc/default/locale
apt -y install manpages-ja manpages-ja-dev
timedatectl set-timezone Asia/Tokyo
```

### 開発者用アカウント作成
sudo権限付のアカウントとキーペアを作成する。

```
adduser user
gpasswd -a user sudo

su - user

ssh-keygen -t rsa
mv ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
```

キーペアのうち、秘密鍵となる `~/.ssh/id_rsa` を安全なルートで開発者に渡そう。
なお、パスワード無しで sudo させたい場合は、`--disabled-password`を付けて`adduser`し、

```:/etc/sudoers.d/90-cloud-init-users
user   ALL = NOPASSWD:ALL
```

のように追加すれば良い。

### ホスト名の変更
EC2では、ホスト名の初期値がプライベートIPアドレス（例：`ip-12-34-56-78`）になっている。
これがシェルプロンプトの一部に表示されるのだが、いくつも端末を立ち上げていると、ここはどこ？になるので変更する。

```
hostnamectl set-hostname ホスト名
```

# バックアップの取得
サーバを開発部門へ引き渡す前に、バックアップ（スナップショット）を取得しておこう。
再びコンソールにログインする。

### インスタンスの停止
停止は必須ではないが推奨されている。
アクションメニューの **[インスタンスの状態]** から **[停止]** をクリックする。
EC2では **[停止（stopped）]** と **[終了（terminated）]** は意味がまったく違うので気を付けよう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/66320ae4-7ee6-2522-5fef-2a7b460897fc.png)

### スナップショットの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/61c7b15c-94b3-9ac7-f134-eee36654bfb6.png)
リソースタイプにインスタンスを選択し、対象インスタンスを選ぶだけでOKだ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/9ee1e79b-31d6-4b16-7fbb-156535b19c5e.png)

これでスナップショットからいつでも復元できるようになる。
復元のやり方は何パターンかあり、Qiitaにも関連記事は沢山あるので色々試してみて欲しい。

# DNS登録
ネームサーバは自前で管理しているので、**Route53** は使わない。
ゾーンファイルにAレコードを追加する。

```config:/usr/local/etc/namedb/master/example.com.zone
$TTL 3600
$ORIGIN example.com.
@       IN      SOA     foo.example.com. (
        2019071401      ; Serial
        43200           ; Refresh after 12 hours
        3600            ; Retry after one hour
        2419200         ; Expire after 4 weeks
        1200    )       ; Negative cache TTL of 20 minutes
;
; Authoritative name servers
;
        IN      NS      ns01.example.com.
;
; Host
;
bar     1800    IN      A      12.34.56.78
```

# サーバの引き渡し
例えば下のような設定ワークシートをたくさん書かなければならないときでも、**AWS SDK**を使えば労力を抑えられる。
仕様書をExcelで自動生成している例を見つけたので、最後にリンクを載せておく。
https://dev.classmethod.jp/cloud/excel_aws_spec_autogeneration/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/436d53ed-dde8-d7cc-d76d-3e961779bf53.png)