Terraformを使ってAWS環境を構築するやり方

なにかサービスを始めるに当たってのIAMまわりを構築するときの役にたてばと思ってまとめています。

## Terraformとは？
インフラ構築や設定をコード(テンプレートファイル)を使って自動化するためのツール
https://dev.classmethod.jp/cloud/terraform-getting-started-with-aws/

## 環境について
* Mac(High Sierra 10.13.5)
* [Docker for Mac](https://www.docker.com/docker-mac) をインストール済み
* Gitをインストール済み
* Docker Terraform(v0.11.7)

## 環境を構築する前のAWSコンソール上でやること

以下のアカウント作成は、ルートアカウントで作業をしないために、次に強力な権限をもつアカウントを作成しています。
そのためセキュリティーは **ルートアカウント同様に強力** なものにしてください。

1. Admin権限をもったユーザーを作成しましょう
  1. IAM -> メニューから「ユーザー」を選択します
  1. 「ユーザーを追加」を選択します
  1. AWSマネジメントコンソールへのアクセスにチェックします
![p1_result.png](https://qiita-image-store.s3.amazonaws.com/0/266407/fc5d8b82-a117-9a77-223b-f94c636058b8.png)
 1. 既存のポリシーから「AdministratorAccess」にチェックします
![p2_result.png](https://qiita-image-store.s3.amazonaws.com/0/266407/57522bc3-db69-c26d-5ad8-8699daf6c14b.png)
 1. パスワードを覚えましょう
![p3_result.png](https://qiita-image-store.s3.amazonaws.com/0/266407/2ddcd429-de82-b1b7-f2a3-a26057916b29.png)
1. 「MFAデバイスの割り当て」を必ず行います
1. 「アクセスキーの作成」を選択します
![p4_result.png](https://qiita-image-store.s3.amazonaws.com/0/266407/e3497b7a-292c-621a-815c-c26bb1722d0b.png)
  1. 「CSVファイルのダウンロード」は忘れずにしましょう
![p5_result.png](https://qiita-image-store.s3.amazonaws.com/0/266407/1f63b778-442a-6f58-a903-f7ac27a24e75.png)

## DockerでTerraform環境を構築

DockerHubから[terraform](https://hub.docker.com/r/hashicorp/terraform/)のイメージをダウンロードします。

`$ docker pull hashicorp/terraform:light`

## Mac上にワークスペースフォルダを作成

実行するためのシェルも設置したいので以下のようなフォルダ構成にします。
※自分はドキュメントフォルダの下に以下のようなフォルダ構成を構築しています。

````
terraform
├ aws
│ └ main.tf
│
└ bin
  └ terraform_aws.sh
````
### 実行するためのシェルスクリプトを作成

以下のサイトを参考にして「terraform_aws.sh」を作成しました。
https://qiita.com/ojiry/items/89bd8b3a68c69c84a60e

````sh:bin/terraform_aws.sh
#!/usr/bin/env bash

set -eu

SCRIPT_DIR=$(cd $(dirname $0); pwd)

cd $SCRIPT_DIR/../

docker run -i --rm -t -v $(pwd)/aws:/aws -w /aws hashicorp/terraform:light $@
````

## terraform の構築

ファイルはGit管理します。
※アクセスキーなどの機密情報はGit管理外にします。

* 作成したワークスペースフォルダに移動します。
  `$ cd terraform/aws`
  `$ git init`

* .gitignoreファイルを作成してGit管理外のファイルを指定します。

````sh:aws/.gitignore
# Local .terraform directories
**/.terraform/*

# .tfstate files
*.tfstate
*.tfstate.*

# Crash log files
crash.log

# Ignore any .tfvars files that are generated automatically for each Terraform run. Most
# .tfvars files are managed as part of configuration and so should be included in
# version control.
#
terraform.tfvars
````

* terraform.tfvars ファイルを作成してAdmin権限をもったユーザーのアクセスキーを記述します。

````sh:aws/terraform.tfvars
aws_access_key = "*******************"
aws_secret_key = "**********************"
````

* main.tf ファイルを作成します。
  * リージョンは東京にしています。

````sh:aws/main.tf
variable "aws_access_key" {}
variable "aws_secret_key" {}
variable "region" {
    default = "ap-northeast-1"
}

provider "aws" {
    access_key = "${var.aws_access_key}"
    secret_key = "${var.aws_secret_key}"
    region = "${var.region}"
}
````
* 設定ファイルはまだないですが、これでAWSに環境を構築する準備ができました。

## terraform の初期化

* 最初にまず以下のコマンドを実行します。

`$ sh bin/terraform_aws.sh init`

## terraform の計画・実行

* 設定を追加/修正するたびに以下のコマンドを実行して反映させます。
  * コマンドについては冒頭の「Terraformとは？」のリンク先を参照してください。

`$ sh bin/terraform_aws.sh plan`
`$ sh bin/terraform_aws.sh apply`


駆け足でしたが、これでterraformを利用してAWSに環境を構築する準備が整いました。

---

# おまけ

## AWS CodeCommitでバージョン管理

※Git使い方を知っている前提で記載します。

1. ローカルPCでSSH鍵を作成します。
`ssh-keygen -t rsa -b 4096 -C "メールアドレス"`

1. terraformを利用してCodeCommitのリポジトリとコミットできるユーザーを作成します。
  * 「<< >>」で囲んでいるところは書き換えてください。

````json:aws/aws_codecommit_terraform.tf
resource "aws_codecommit_repository" "terraform" {
  repository_name = "terraform"
  description     = "AWS インフラ構築や設定をコード(テンプレートファイル)を使って自動化するためのツール"
}

resource "aws_iam_user" "terraform_committer" {
  name = "terraform_committer"
}

resource "aws_iam_user_ssh_key" "terraform_committer" {
  username   = "${aws_iam_user.terraform_committer.name}"
  encoding   = "SSH"
  public_key = "<<公開鍵>>"
}

resource "aws_iam_policy" "terraform_committer_policy" {
    name        = "terraform_committer_policy"
    description = "GIT管理のみ"
    policy = <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "StmtTerraformCommitter01",
            "Effect": "Allow",
            "Action": [
                "codecommit:ListRepositories"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Sid": "StmtTerraformCommitter02",
            "Effect": "Allow",
            "Action": [
                "codecommit:BatchGetRepositories",
                "codecommit:GetBlob",
                "codecommit:GetBranch",
                "codecommit:GetCommit",
                "codecommit:GetDifferences",
                "codecommit:GetObjectIdentifier",
                "codecommit:GetReferences",
                "codecommit:GetRepository",
                "codecommit:GetRepositoryTriggers",
                "codecommit:GetTree",
                "codecommit:GitPull",
                "codecommit:GitPush",
                "codecommit:ListBranches",
                "codecommit:ListRepositories"
            ],
            "Resource": [
                "arn:aws:codecommit:ap-northeast-1:<<AWS アカウントID>>:terraform"
            ]
        }
    ]
}
EOF
}

resource "aws_iam_user_policy_attachment" "terraform_committer_policy-attach" {
    user       = "${aws_iam_user.terraform_committer.name}"
    policy_arn = "${aws_iam_policy.terraform_committer_policy.arn}"
}
````

* ファイル作成後、反映させます。

`$ sh bin/terraform_aws.sh plan`
`$ sh bin/terraform_aws.sh apply`

* GitにOriginリポジトリを追加します。

`$ git remote add origin ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/terraform`

* ローカルPCにSSHの設定をします。

````sh:~/.ssh/config
Host codecommit-terraform
  Hostname git-codecommit.ap-northeast-1.amazonaws.com
  User <<terraform_committerユーザーのSSHアクセスキー>>
  IdentityFile <<SSH秘密鍵ファイルパス>>
````