TerraformでAWSのEC2まわり（SG、IAM、KMS）をデプロイする

Terraformシリーズ第5弾は**EC2**です。EC2を中心に**KMS**や**SecurityGroup（以下SG）** をかいていきます:bulb:

※過去のTerraform記事はこちら
第一弾：[TerraformでAWSリソースをデプロイしてみる](https://qiita.com/hiyanger/items/ca337f70ad4801072850)
第二弾：[TerraformでAWS環境をデプロイする前に認識しておくべきこと](https://qiita.com/hiyanger/items/9efdc570e6cfed5aab13)
第三弾：[TerraformでAWSのIAMまわりをデプロイする](https://qiita.com/hiyanger/items/8f925e21166461a5ddb1)
第四弾：[TerraformでAWSのネットワークまわりをデプロイする](https://qiita.com/hiyanger/items/cabb1697c29d2ba93b5a)

※以下実際にコードを記述していきますが、**"${local.XXX}"** と記述されているものは個人的に外出しした箇所なので、より参考になるかと思いそのまま残しておきました。

## SecurityGroup
```terraform
#セキュリティグループの作成
resource "aws_security_group" "SG名" {
  name        = "SG名"
  description = "SG名"
  vpc_id      = aws_vpc.vpc01.id #紐づけるVPC
  tags = {
    Name = "SG名"
  }
}

#インバウンドルール
resource "aws_security_group_rule" "SG名-in01" {
  type              = "ingress"
  description       = "インバウンド元のSG名"
  from_port         = 0 #ポート範囲
  to_port           = 0 #ポート範囲
  protocol          = "-1" #プロトコル（-1はall）
  source_security_group_id = aws_security_group.example_in.id #インバンド元のSG
  security_group_id = aws_security_group.example.id
}

#アウトバウンドルール 
resource "aws_security_group_rule" "SG名-out01" {
  type              = "egress"
  description       = "アウトバウンド先のSG名"
  from_port         = 0 #ポート範囲
  to_port           = 0 #ポート範囲
  protocol          = "-1" #プロトコル（-1はall）
  prefix_list_ids = ["pl-XXXXXXXX"] #基本は不要 VPCエンドポイントへのアクセスがある場合に記載
  source_security_group_id = aws_security_group.example_out.id #アウトバウンド先のSG
  security_group_id = aws_security_group.example.id
```
上記が基本の記述になります。インアウトのルールが増える場合は01の数字をふやして追記すればOKです。

## IAMロール
インスタンスに紐づけるIAMロール（インスタンスプロファイル）を事前に作成しておく必要があります。
```terraform
#信頼ポリシーの作成
data "aws_iam_policy_document" "assume_role" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["ec2.amazonaws.com"]
    }
  }
}

#IAMロール作成
resource "aws_iam_role" "ロール名" {
  name = "ロール名"
  assume_role_policy = data.aws_iam_policy_document.assume_role.json #紐づける信頼ポリシー
}

#事前に作成したポリシーのアタッチ（複数の前提）
resource "aws_iam_role_policy_attachment" "ロール名" {
  count = "${length(local.example_policylist)}"
  role = aws_iam_role.example_role.name
  policy_arn = "${element(local.example_policylist, count.index)}"
}

#インラインポリシーのアタッチ（もしあれば）
resource "aws_iam_role_policy" "ロール名-in01" {
  name = "ポリシー名"
  role = aws_iam_role.example.name
  policy = file("ディレクトリ/ファイル名.json")
}

#インスタンスプロファイルの作成
resource "aws_iam_instance_profile" "インスタンスプロファイル名" {
  name = "インスタンスプロファイル名"
  role = aws_iam_role.example.name
}
```

## KMS（EC2で利用する場合）
```terraform
#KMS作成
resource "aws_kms_key" "KMS名" {
  policy = templatefile("ディレクトリ/ファイル名.json") #ポリシーはjsonから取得を前提
  enable_key_rotation = true #キーローデーション（必要なら）
}

#エイリアス作成
resource "aws_kms_alias" "KMS名" {
  name          = "alias/KMS名"
  target_key_id = aws_kms_key.example.key_id
}
```

## EC2
```terraform
resource "aws_instance" "インスタンス名" {
    ami = "ami-XXXXX" #AMIのID
    instance_type = "t3.medium" #インスタンスタイプ
    disable_api_termination = true #終了保護（ここでは有効）
    monitoring = "false" #詳細モニタリング（ここでは無効）
    key_name = "キーペア名" #キーペア名
    vpc_security_group_ids = aws_security_group.example.id #紐付けるセキュリティグループ
    iam_instance_profile = aws_iam_instance_profile.example.name #紐づけるIAMロール
    subnet_id = aws_subnet.private-1a.id #デプロイ先サブネットID
    private_ip = "XXX.XXXX.XXX.XXX" #プライベートIP(指定がなければ不要)

    #cpu_credits
    credit_specification {
      cpu_credits = "standard" #CPUクレジット 不要ならスタンダード
    }
    
    #rootデバイス
    root_block_device {
      volume_type = "gp3"
      volume_size = 10
      delete_on_termination = "true" #終了のEBS削除（ここでは有効）
      encrypted = "true" #暗号化
      kms_key_id  = aws_kms_key.example.arn #必要なら先に作成したKMSを指定する
    }

    #追加ディスク（必要なら）
    ebs_block_device {
      volume_type = "gp3"
      volume_size = 10
      device_name = "/dev/xvdb" #マウントポイント
      delete_on_termination = "true"
      encrypted = "true"
      kms_key_id  = aws_kms_key.example.arn
    }
    tags = {
      Name = "インスタンス名"
    }
}
```
t3など一部インスタンスタイプではCPUクレジットが有効化されてしまうようなので、明示的に不要にしてあげる必要があります。

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/burstable-performance-instances-unlimited-mode.html