AWSサインアップからEC2上げるまでの自分用おさらい

## はじめに

どちらかというと管理者さんからAWSの作業用アカウントをいただいてお仕事をすることが多かったので、自分でやったサインアップからの作業を淡々と書いてみます。
ほんとうにメモ書きですので、ご容赦ください。

また、AWS公式、特にクラスメソッド様のブログ、Qiita上のたくさんの記事を参考にさせていただいています。ありがとうございます！

### いったんやりたいこと

- [x] サインアップから課金でひどい目にあわないように最低限設定する
- [x] ルートアカウントでなく作業用にユーザアカウントを作成する
- [x] アカウントを切り替えて、コンソールでの操作ができる
- [x] 開発用アカウントでaws cliを使える

### 今後やりたいこと

この辺りを、お手伝いでちょっと見ただけなので、自分でちゃんとできるようにしておきたい。

- Terraformを使ってDBやEC2,ELBの簡単な操作をする
- コンソールからECRに登録する
- コンソールからECS (Fargate) を操作する
- CI連携でECR -> ECSにデプロイできるようにする
- ECS上のコンテナで定期タスクを実行できるようにする
- ログをよしなに見れるようにする
 - CloudWatch以外でのメトリクスをうまく見れるようにする
 
まだまだですが、まずは「いったんやりたいこと」をつらつらとメモします。

## アカウント作成

- ルートアカウント作成をします
  - [アカウント作成の流れ](https://aws.amazon.com/jp/register-flow/) by AWS
  - AWS公式サイトの手順に従って作成します
  - クレカの番号と、本人確認用の電話番号が必要
  
## 作成後 / 2段階認証設定

一旦ルートアカウントでサインインします。ルートアカウントは本当に特権ユーザアカウントなので、できるだけこのアカウントは使わないように。
また、パスワード認証に加え、2段階認証も設定。

- こちらの記事に大変お世話になりました！
  - [AWSアカウントを取得したら速攻でやっておくべき初期設定まとめ](https://qiita.com/tmknom/items/303db2d1d928db720888)
- https://console.aws.amazon.com/iam/home?#/home に移動
- [x] ルートアカウントのMFAを有効化
  - MFA用のアプリには、わたしは [IIJ SmartKey](https://www.iij.ad.jp/smartkey/) を利用しています！

## 管理用のIAMユーザ作成

ルートアカウントでサインアウト、そして再びサインインし、2FA (MFA)が有効なことを確認。
次にオペレーション用のアカウントを作成します。
Billingや、以降のIAMユーザ作成などは、こちらを利用する方針で。 

- https://console.aws.amazon.com/iam/home に移動
- 「個々の IAM ユーザーの作成」を選ぶ
- オペレーション用アカウントを作成
 - Group追加（Admin用)
 - キー作成は無し（プログラムからのアクセスは想定していないので、キーは作らない）
  - [x] MFA設定も設定済み
 
## セキュリティステータスの確認
  
- https://console.aws.amazon.com/iam/home
 - OKになりました

## CloudWatchで請求情報のアラームを作成

このあたりも、[AWSアカウントを取得したら速攻でやっておくべき初期設定まとめ](https://qiita.com/tmknom/items/303db2d1d928db720888) を参考に。

- CloudWatch設定 -> SNSでも確認
- 登録したメールアドレスに確認メールがくるので、そちらもクリックして確認
- 課金アラームは、閾値を100USDで設定

## 課金関連設定変更

- USD -> JPYでの請求に変更
- コストエクスプローラーを有効にする
- Subscriptionの設定変更（AWSからのメールを必要なものに絞る）

## オペレーション用のIAMユーザでのサインイン

だいたいオペレーション用のアカウントでできるようになっているので、切り替え。

- アカウントを切り替えてサインインの確認
- リージョンをTokyoに変更

## CloudTrail設定

- https://qiita.com/tmknom/items/303db2d1d928db720888#cloudtrail
- AWSのAPI呼び出しの履歴を残してくれる

※CloudTrailの設定の際、**記録の保持にS3を利用**します。
こちらは、APIを利用していたりすると無料枠がすぐに超えてしまう可能性があるので、しばらくはコストエクスプローラーを確認しておくのが良いでしょう。(s3に対するリクエストの回数）
（さほど高額ではないにしても）

### 20190810追記

- CloudTrailを有効にした場合、Putの枠が2000件なので、すぐに枠を超えてしまいます....
- Terraformの操作をテストしていたら、API呼び出しが結構発生するので、個人利用だとこちらも注意

参照: [AWS初心者が無料利用枠で個人運用していたら$0.64請求がきた話し](https://qiita.com/fkooo/items/df3b1b47a61f7826ffd4)

エンタープライズ（お仕事で使う）相当の内容を試したい場合には、個人無料枠だけだと、うっかり試すと厳しいものがあると感じた次第。

## git-secrets

手元のPC（Mac) 側に設定。envファイルなどにキーを登録したりしないように、gitのプラグイン的なもので防止策を取っておく。

- https://qiita.com/pottava/items/4c602c97aacf10c058f1
- brew installしておく

## さらに開発用の別ユーザを作成＆サインイン

- 開発用のグループ（ポリシー）を割り当てたユーザを作成
- そちらのアカウントでもMFAを有効にしてサインイン

いったんの準備はここまで。
あとは開発用のユーザに切り替えて、基本のEC2の立ち上げなどを確認

## 追加設定

開発用のアカウントが属するグループに割り当てた、ビルトインのPowerUserAccessポリシーには、アクセスキー生成の権限がなかったので、以下のポリシーを作成し、グループに追加。

- Ref. 
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_permissions-required.html

```JSON
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ManageOwnAccessKeys",
            "Effect": "Allow",
            "Action": [
                "iam:CreateAccessKey",
                "iam:DeleteAccessKey",
                "iam:GetAccessKeyLastUsed",
                "iam:GetUser",
                "iam:ListAccessKeys",
                "iam:UpdateAccessKey",
                "iam:ListMFADevices"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        }
    ]
}
```

## EC2作成

[10 分間チュートリアル](https://aws.amazon.com/jp/getting-started/tutorials/) のコンテンツに従って駆け足で確認。
基本のき、で [Linux 仮想マシンの起動](https://aws.amazon.com/jp/getting-started/tutorials/launch-a-virtual-machine/) を進めます。

まずは開発用に作成したIAMユーザにアカウントを切り替えて、コンソールにログイン。

- SSH port: 22のみインバウンドでオープン
- あとからSSHのポートは変更したりするけど、ここではすぐ消すのでそのまま
  - EC2側のsshdのポート番号を変えてrestartすると、そのポートを開けておかないとsshログインできなくなっちゃうので注意 
  - ※先にセキュリティグループでlistenできるようにしておく

起動が確認できました。

## キーペア作成とsshログイン

- 作成後にキーペアを作成
- 作業用PCの~/.ssh/ 以下に配置 (xxxx.pem)
- chmod 600 xxxx.pem する
- .ssh/confg に設定を追加しておく
- あとは ssh first_ec2 でログインを確認  

```config

% cat ~/.ssh/config

Host first_ec2
  HostName パブリックIP
  User ec2-user
  Port 22
  IdentityFile ~/.ssh/xxxx.pem
  TCPKeepAlive yes
  IdentitiesOnly yes

% ssh first_ec2 
```

## AWS CLIを入れておく

コマンドラインで操作したいので、aws cliを入れておく。

- https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-install.html


```bash
% aws --version
aws-cli/1.15.81 Python/2.7.10 Darwin/18.6.0 botocore/1.10.80
% python -V
Python 3.7.0
```

### aws cliの初期設定作成

- aws configure で表示に従って操作
- うまくいくと、~/.aws/ 以下に設定ファイルができる
   -  ~/.aws/credentials にアクセスキー情報
   -  ~/.aws/config にデフォルトのリージョン情報など

```bash
% aws configure
AWS Access Key ID [None]: xxxxx
AWS Secret Access Key [None]: xxxxxx
Default region name [None]: ap-northeast-1
Default output format [None]: json
```

## AWS CLIからEC2の操作

- aws cliの設定済み
- aws ec2 

一覧を抽出

```bash
# describe-instances: Describes one or more of your instances.
% aws ec2 describe-instances --filters "Name=instance-type,Values=t2.micro" \ 
    --query "Reservations[].Instances[].InstanceId"
[
    "i-xxxxxxxxxxx"
]
```

AWSコンソールから作成したEC2インスタンスが見えるので、単体で起動（停止中にしておいた）

```bash
% export INSTANCE_ID=i-xxxxxxxxxxx
% aws ec2 start-instances --instance-ids $INSTANCE_ID
{
    "StartingInstances": [
        {
            "InstanceId": "i-xxxxxxxxxxx",
            "CurrentState": {
                "Code": 0,
                "Name": "pending"
            },
            "PreviousState": {
                "Code": 80,
                "Name": "stopped"
            }
        }
    ]
}
```

- AWSコンソールの画面を見るとrunningになっている
- コマンドラインからも確認

```bash
% aws ec2 describe-instance-status --instance-ids $INSTANCE_ID | jq '.InstanceStatuses[] | {InstanceId, InstanceState: .InstanceState.Name, SystemStatus: .SystemStatus.Status, InstanceStatus: .InstanceStatus.Status}'
{
  "InstanceId": "i-xxxxxxxxxxx",
  "InstanceState": "running",
  "SystemStatus": "initializing",
  "InstanceStatus": "initializing"
}

# しばらくするとOKになる

% aws ec2 describe-instance-status --instance-ids $INSTANCE_ID | jq '.InstanceStatuses[] | {InstanceId, InstanceState: .InstanceState.Name, SystemStatus: .SystemStatus.Status, InstanceStatus: .InstanceStatus.Status}'
{
  "InstanceId": "i-xxxxxxxxxxx",
  "InstanceState": "running",
  "SystemStatus": "ok",
  "InstanceStatus": "ok"
}
```

- また停止する

```bash
% aws ec2 stop-instances --instance-ids $INSTANCE_ID
{
    "StoppingInstances": [
        {
            "InstanceId": "i-xxxxxxxxxxx",
            "CurrentState": {
                "Code": 64,
                "Name": "stopping"
            },
            "PreviousState": {
                "Code": 16,
                "Name": "running"
            }
        }
    ]
}

# 停止確認

% aws ec2 describe-instances --instance-ids $INSTANCE_ID | \
   jq '.Reservations[].Instances[] | {InstanceId, InstanceState: .State.Name}'
{
  "InstanceId": "i-xxxxxxxxxxx",
  "InstanceState": "stopped"
}
```

- 削除まで実行
- terminate-instances を使う
- https://docs.aws.amazon.com/cli/latest/reference/ec2/terminate-instances.html

```bash

% aws ec2 terminate-instances --instance-ids $INSTANCE_ID
{
    "TerminatingInstances": [
        {
            "InstanceId": "i-xxxxxxxxxxx",
            "CurrentState": {
                "Code": 48,
                "Name": "terminated"
            },
            "PreviousState": {
                "Code": 80,
                "Name": "stopped"
            }
        }
    ]
}

% aws ec2 describe-instances --instance-ids $INSTANCE_ID | \
    jq '.Reservations[].Instances[] | {InstanceId, InstanceState: .State.Name}'
{
  "InstanceId": "i-xxxxxxxxxxx",
  "InstanceState": "terminated"
}

```

削除コマンドが発行され、"terminated" の状態になっても、しばらくは一覧から消えないので注意。

- Ref. https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/terminating-instances.html#termination-overview

ここまでで完了。

## ここまでのふりかえり

少し前（3年くらい前）と比べても、本当に資料やチュートリアル、情報が充実しており、IDE（高機能エディタ）との連携なども格段に良くなっていて、本当に有難い限りです！

怖がらずにおさらいしていきたいです...。

```
A 明日の
W わたしは
S 最強だ！
```