ゼロから始める！AWSアカウント作成からTerraformでEC2インスタンスを立てるまでハンズオン

# 前提

- AWSとTerraformについて、ぐぐって **概要** が **だいたい** わかる程度の人が対象です
- brewを使うのでmac前提です...。読み替えて頂ければ、windowsでも実現可能かと思われます
- Terraformを今日初めて触ったので勢いでやってる部分があります。誤りやアドバイスあればぜひコメントください！

免責事項としてまして、この記事に書いてあることを実施したことで「大量の課金請求が来た！」など、あらゆる問題については責任を負いかねますので、全て自己責任で実施をお願いいたします！

# ここでやること

1. **AWSのアカウントを作成して、AWS上で開発用ユーザを作成**
1. **開発用ユーザを用いて、TerraformでEC2インスタンスを作成**

さぁ、やってみよう！

# 1. AWSのアカウントを作成して、AWS上で開発用ユーザを作成

## AWSアカウント作成

すでにAWSアカウントを持っている人は、飛ばしてもらって構いません。

[AWS アカウント作成の流れ](https://aws.amazon.com/jp/register-flow/) の「コンソールにサインイン」からアカウントを登録します。
<img width="272" alt="スクリーンショット 2019-07-26 2.32.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224357/db543677-8a97-9d52-b93a-e91ff405e01e.png">

- クレジットカードの登録が必要になります
- プランの選択はFreeで問題ありません
- 英語で住所登録をするので、住所の英語変換サービスが便利です → [JuDress](http://judress.tsukuenoue.com/)

## 開発用ユーザの作成

前項で作ったAWSアカウントはroot権限を持っており、普段使いするものではありません
そこで開発用ユーザーを作成し、そちらで開発をします

今回は開発用ユーザーグループを作成し、そのグループを開発用ユーザーに

### IAMでユーザーグループの作成

マネジメントコンソールで、「IAM」と検索し、IAMを選択します
<img width="867" alt="スクリーンショット 2019-07-26 2.50.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224357/88f92bcc-2a3c-3974-cb98-a4dfb34a758c.png">

左ナビから、「グループ」を選択し、「新しいグループの作成」を選択します
<img width="1440" alt="スクリーンショット_2019-07-26_2_53_18-2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224357/116bc45f-2dcf-b4fa-5e6d-7caf8c61c96e.png">

グループ名は「developer」を入力して「次のステップ」へ
<img width="438" alt="スクリーンショット 2019-07-26 2.59.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224357/38aa065d-8480-2ae9-ef43-29e73078b26c.png">

ポリシーは「PowerUserAccess」を入力、選択して「次のステップ」へ
<img width="1125" alt="スクリーンショット 2019-07-26 3.08.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224357/8d84ea76-34d9-1f9f-1034-8e1e9c533772.png">

最後は確認なので、そのまま「次のステップ」へ

developerユーザーができました！
<img width="1440" alt="スクリーンショット_2019-07-26_3_09_49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224357/657ef830-6a07-79d8-23d8-f90359fd8ace.png">

### IAMでユーザーの作成

左ナビから、「ユーザー」を選択し、「ユーザーを追加」を選択します
<img width="1440" alt="スクリーンショット_2019-07-26_3_47_01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224357/a97ac9df-041b-9f42-b638-4923c0312618.png">

ユーザー名を「terraform-test」と入力し、アクセスについては以下のように設定します
カスタムパスワードは忘れないように！
そして「次のステップ」へ
<img width="974" alt="スクリーンショット 2019-07-26 3.21.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224357/f46f6201-180e-aa9c-2192-6953d1abf81a.png">

作成したユーザーグループの「developer」を選択して「次のステップへ」
<img width="976" alt="スクリーンショット 2019-07-26 3.23.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224357/953bbea2-0fd9-59bb-4475-de27607192aa.png">

タグの追加は今回しませんので、何もせず「次のステップ」へ
そして最後は確認なので、そのまま「ユーザーを作成」

「terraform-test」ユーザーが作成されました！
<img width="996" alt="スクリーンショット_2019-07-26_3_27_51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224357/a1733201-0760-c9d2-1c84-1a315b6fcd24.png">

以下の3つ（赤で囲ったところ）はあとで使うのでメモっておいてください
cvsダウンロードしておくと楽です

- コンソールアクセスのurl
- アクセスキーID
- シークレットアクセスキー

これらを用いて外部からAWSの操作を行います
**githubにpushなどは大変危険です 絶対に他人が知れない状態を保ってください**

最後にコンソールへのurlへアクセスしてみましょう！
ログインができたらフェーズ1は完了です！

# 2. 開発用ユーザを用いて、TerraformでEC2インスタンスを作成

## AWS CLIを使えるようにする

AWSを使う上で、今回はAWS CLIというコマンドラインでAWSとやりとりするツールを使います
そのためpython pipなど、インストールに必要なものを整備していきます
すでにインストールが完了しているものは飛ばしてもらって構いません

### pythonインストール

pyenvを使います

```console
$ brew install pyenv
$ pyenv install --list  | egrep '^[ ]+[23]\.[0-9\.]+$' | grep ' 3' | tail -n 1
$ pyenv install 3.7.4 # 最新をインストール
$ pyenv global 3.7.4
$ pyenv global 3.7.4
$ pyenv versions
  system
* 3.7.4 (set by /usr/local/var/pyenv/version)
$ python --version
Python 3.7.4
```

### pipインストール

pythonでpipをインストールします

```console
$ python -m pip install pip --upgrade
$ pip -V
pip 19.2.1 from /usr/local/var/pyenv/versions/3.7.4/lib/python3.7/site-packages/pip (python 3.7)
```

### AWS CLIインストール

pipでAWS CLIをインストール

```console
$ sudo pip install awscli
$ aws --version
aws-cli/1.16.205 Python/3.7.4 Darwin/18.7.0 botocore/1.12.195
...
```

### AWS CLIに開発用ユーザーの登録

先ほどの「アクセスキーID」「シークレットアクセスキー」をそれぞれ設定します

```console
$ aws configure --profile terraform-test
AWS Access Key ID [None]: XXXXXXXXXXXXXXXXX        # アクセスキー
AWS Secret Access Key [None]: YYYYYYYYYYYYYYYYYYYY # シークレットアクセスキー
Default region name [None]: ap-northeast-1         # デフォルトのリージョン：アジアパシフィック (東京)
Default output format [None]: json                 # とりあえずjson
```

### 設定を確認

```console
$ aws configure list --profile terraform-test
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile           terraform-test           manual    --profile
access_key     ****************XXXX shared-credentials-file
secret_key     ****************YYYY shared-credentials-file
    region           ap-northeast-1      config-file    ~/.aws/config
```

AWS CLIを使う準備が完了しました！

## Terraformでインスタンスを立てる

### Terraformインストール

```console
$ brew update
$ brew install terraform
$ terraform -v
Terraform v0.12.5
...
```

### リポジトリの作成

```console
$ mkdir terraform-test
$ cd terraform-test
$ terraform init
```

### .tfファイルの作成

Ubuntuのインスタンスを2つ立ててみるという内容です
terreform-testディレクトリ直下に以下の2ファイルを作成します
[GitHub - first-terraform](https://github.com/aromanokarisu/first-terraform)

```plaintext:variables.tf
provider "aws" {
  profile = "terraform-test" # aws cliで設定したprofile
  version = "~> 2.0"
  region  = "ap-northeast-1" # リージョン：アジアパシフィック (東京)
}
```

```plaintext:ec2.tf
resource "aws_instance" "sandbox" {
  count         = 2              # インスタンス数
  ami           = "ami-785c491f" # Ubuntu 16.04 LTS official ami
  instance_type = "t2.micro"     # インスタンスタイプ

  tags = {
    Name = "${format("sandbox-%02d", count.index + 1)}"
  }
}
```

## ドライラン

.tfで記載した内容であるかを確認します

```console
$ terraform plan
...
Terraform will perform the following actions:

  # aws_instance.sandbox[0] will be created
  + resource "aws_instance" "sandbox" {
      + ami                          = "ami-785c491f"
  ...

  # aws_instance.sandbox[1] will be created
  + resource "aws_instance" "sandbox" {
      + ami                          = "ami-785c491f"
  ...

Plan: 2 to add, 0 to change, 0 to destroy.
...
```

## 実行

ドライランで確認した内容で、インスタンスの生成を行います

```console
$ terraform apply
...
Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes # yesを入力

aws_instance.sandbox[0]: Creating...
aws_instance.sandbox[1]: Creating...
aws_instance.sandbox[1]: Still creating... [10s elapsed]
aws_instance.sandbox[0]: Still creating... [10s elapsed]
aws_instance.sandbox[0]: Still creating... [20s elapsed]
aws_instance.sandbox[1]: Still creating... [20s elapsed]
aws_instance.sandbox[0]: Creation complete after 23s [id=i-xxxxxxxxxxxxxxxxx]
aws_instance.sandbox[1]: Still creating... [30s elapsed]
aws_instance.sandbox[1]: Creation complete after 33s [id=i-xxxxxxxxxxxxxxxxx]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
```

## 生成されたインスタンスの確認

### コマンドライン

```console
$ terraform show
# aws_instance.sandbox[0]:
resource "aws_instance" "sandbox" {
    ami                          = "ami-785c491f"
    ...

# aws_instance.sandbox[1]:
resource "aws_instance" "sandbox" {
    ami                          = "ami-785c491f"
    ...
```

### AWS マネジメントコンソール

terraform-testユーザのAWSマネジメントコンソールで「EC2」を検索し、選択します
<img width="837" alt="スクリーンショット 2019-07-26 4.21.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224357/a1a40e88-f11d-cebf-e620-61168409555c.png">

右上のプルダウンから「東京リージョン」を選択すると、EC2インスタンスが2つ立ち上がっています！
僕は「東京リージョン」を選択するのを失念して、関係ない設定をいじくりまわしてかなり無駄な時間を過ごしました
<img width="1440" alt="スクリーンショット_2019-07-26_4_17_58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224357/25a0d271-c34e-7af2-153d-b316a5a9b377.png">

このようにTerraformでEC2インスタンスを立ち上げることができました！
あとは公式ドキュメントなどに従い .tfをいじって見ましょう！

## インスタンスの削除

クラウドサービスでインスタンスの放置は、ある日突然多大な料金の請求がくる原因になり大変危険です
常日頃から、勉強用、使わないインスタンスは停止なり削除を心がけましょう

```console
$ terraform destroy
Terraform will perform the following actions:

  # aws_instance.sandbox[0] will be destroyed
  - resource "aws_instance" "sandbox" {
      - ami                          = "ami-785c491f" -> null
      ...

  # aws_instance.sandbox[1] will be destroyed
  - resource "aws_instance" "sandbox" {
      - ami                          = "ami-785c491f" -> null
      ...

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes # yesを入力

aws_instance.sandbox[0]: Destroying... [id=i-0f64c8ea558dcfb68]
aws_instance.sandbox[1]: Destroying... [id=i-063fb9265f57a867d]
aws_instance.sandbox[0]: Still destroying... [id=i-0f64c8ea558dcfb68, 10s elapsed]
aws_instance.sandbox[1]: Still destroying... [id=i-063fb9265f57a867d, 10s elapsed]
aws_instance.sandbox[0]: Still destroying... [id=i-0f64c8ea558dcfb68, 20s elapsed]
aws_instance.sandbox[1]: Still destroying... [id=i-063fb9265f57a867d, 20s elapsed]
aws_instance.sandbox[0]: Destruction complete after 30s
aws_instance.sandbox[1]: Still destroying... [id=i-063fb9265f57a867d, 31s elapsed]
aws_instance.sandbox[1]: Destruction complete after 31s

Destroy complete! Resources: 2 destroyed.
```

## 削除されたインスタンスの確認

### コマンドライン

```console
$ terraform show
# 何も表示されない
```

### AWS マネジメントコンソール

terminatedになっていれば時期に消えます
<img width="1440" alt="スクリーンショット_2019-07-26_4_28_01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224357/6ba2bb25-a2a0-d227-a394-67107b8e1838.png">

# 最後に

ここまで読んでいただきありがとうございます！
僕自身、Terraform触ったことない、AWSの課金体型よくわからん怖い、IAMもようわからん、という状況でしたが、なんとか動かすところまで持っていくことができました
この記事がTerraformを知ろうとしている人の助けになれば幸いです！

# 参考記事

- [10分で理解するTerraform](https://qiita.com/Chanmoro/items/55bf0da3aaf37dc26f73)
- [AWSでチーム開発する際のIAMによるアカウント設定方法](https://qiita.com/s-kiriki/items/db6fc88ce2ce6626fb4f)
- [AWS-CLIの初期設定のメモ](https://qiita.com/reflet/items/e4225435fe692663b705)
- [AWS CLIで複数アカウントを利用する](https://koji.noshita.net/post/2017/0307-awscli/)