TerraformでAWS AMIの最新を常に使うようにする

[TerraformとAWSに同時入門する
](https://qiita.com/litencatt/items/8da20374def6320a014b)の続きで、
> 最新のAMIが常に指定されるようなami設定にする

を行えるようにします。

## 確認環境
```
$ terraform version
Terraform v0.11.1
+ provider.aws v1.5.0
```

## 取得するAMIのスペック
今回は2017/12/10時点でのAmazon Linuxの下記スペックにおける最新AMI ID(`ami-da9e2cbc`)を取得します。
最新AMI IDはこちらで確認できます: [Amazon Linux AMI ID](https://aws.amazon.com/jp/amazon-linux-ami/#Amazon_Linux_AMI_ID)

- リージョン: `アジアパシフィック東京`
- 仮想化タイプ: `HVM`
- ルートデバイスタイプ: `EBS-Backed`
- アーキテクチャ: `x86_64`
- ボリュームタイプ: `gp2`

:warning: 注意点
AMI IDはリージョン毎に異なるようなので複数リージョンにまたがった環境の場合は注意が必要かもしれません

## 結論

### 簡易版
フィルタ条件はAMI Image名の条件のみ

```HCL:aws_ami.tf
data "aws_ami" "amazon_linux" {
  most_recent = true
  owners = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn-ami-hvm-*-x86_64-gp2"]
  }
}
```

### 詳細版
フィルタ条件として今回の指定スペックをすべて指定

参考: [Terraformでもいつでも最新AMIからEC2を起動したい](https://dev.classmethod.jp/cloud/aws/launch-ec2-from-latest-ami-by-terraform/)

```HCL:aws_ami.tf
data "aws_ami" "amazon_linux" {
  most_recent = true
  owners = ["amazon"]

  filter {
    name   = "architecture"
    values = ["x86_64"]
  }

  filter {
    name   = "root-device-type"
    values = ["ebs"]
  }

  filter {
    name   = "name"
    values = ["amzn-ami-hvm-*"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  filter {
    name   = "block-device-mapping.volume-type"
    values = ["gp2"]
  }
}
```

### EC2側の設定

```HCL:ec2.tf
resource "aws_instance" "web-server" {
  ami                    = "${data.aws_ami.amazon_linux.id}"
  instance_type          = "t2.micro"
}
```

### 確認
```
$ terraform plan

  + aws_instance.web-server
      id:                           <computed>
      ami:                          "ami-da9e2cbc"
      ...
```

## AWS CLIでAmazon Linux AMI image名を取得してみる
### 準備
[AWS Command Line Interface のインストール](http://docs.aws.amazon.com/ja_jp/cli/latest/userguide/installing.html)

### 簡易版のフィルタ条件の説明

[AWS CLIで最新のAmazon LinuxのAMI IDを取得する](http://sechiro.hatenablog.com/entry/2014/10/11/AWS_CLI%E3%81%A7%E6%9C%80%E6%96%B0%E3%81%AEAmazon_Linux%E3%81%AEAMI_ID%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B)
上記でのシェルを参考に今回取得したい条件に変更します

```diff:get-aws-ec2-image.sh.sh
...

describe_images(){
    echo $timestamp > $timestamp_file
    aws ec2 describe-images \
-       --owners self amazon \
+       --owners amazon \
        --filters \
+         Name=name,Values="amzn-ami-hvm-*" \
          Name=virtualization-type,Values=hvm \
          Name=root-device-type,Values=ebs \
          Name=architecture,Values=x86_64 \
-         Name=block-device-mapping.volume-type,Values=standard
+         Name=block-device-mapping.volume-type,Values=gp2
}

...
```

実行結果

```
$ zsh ./get-aws-ec2-image.sh

amzn-ami-hvm-2014.03.2.x86_64-gp2: ami-df470ede
amzn-ami-hvm-2014.09.0.x86_64-gp2: ami-45072844
amzn-ami-hvm-2014.09.1.x86_64-gp2: ami-4585b044
amzn-ami-hvm-2014.09.2.x86_64-gp2: ami-1e86981f
amzn-ami-hvm-2015.03.0.x86_64-gp2: ami-cbf90ecb
amzn-ami-hvm-2015.03.1.x86_64-gp2: ami-1c1b9f1c
amzn-ami-hvm-2015.09.0.x86_64-gp2: ami-9a2fb89a
amzn-ami-hvm-2015.09.1.x86_64-gp2: ami-383c1956
amzn-ami-hvm-2015.09.2.x86_64-gp2: ami-59bdb937
amzn-ami-hvm-2016.03.0.x86_64-gp2: ami-f80e0596
amzn-ami-hvm-2016.03.1.x86_64-gp2: ami-29160d47
amzn-ami-hvm-2016.03.2.x86_64-gp2: ami-6154bb00
amzn-ami-hvm-2016.03.3.x86_64-gp2: ami-374db956
amzn-ami-hvm-2016.09.0.20160923-x86_64-gp2: ami-1a15c77b
amzn-ami-hvm-2016.09.0.20161028-x86_64-gp2: ami-0c11b26d
amzn-ami-hvm-2016.09.1.20161221-x86_64-gp2: ami-9f0c67f8
amzn-ami-hvm-2016.09.1.20170119-x86_64-gp2: ami-56d4ad31
amzn-ami-hvm-2017.03.0.20170401-x86_64-gp2: ami-859bbfe2
amzn-ami-hvm-2017.03.0.20170417-x86_64-gp2: ami-923d12f5
amzn-ami-hvm-2017.03.1.20170617-x86_64-gp2: ami-bbf2f9dc
amzn-ami-hvm-2017.03.1.20170623-x86_64-gp2: ami-3bd3c45c
amzn-ami-hvm-2017.03.1.20170812-x86_64-gp2: ami-4af5022c
amzn-ami-hvm-2017.03.rc-0.20170320-x86_64-gp2: ami-be154bd9
amzn-ami-hvm-2017.03.rc-1.20170327-x86_64-gp2: ami-10207a77
amzn-ami-hvm-2017.09.0.20170930-x86_64-gp2: ami-2a69be4c
amzn-ami-hvm-2017.09.1.20171103-x86_64-gp2: ami-2803ac4e
amzn-ami-hvm-2017.09.1.20171120-x86_64-gp2: ami-da9e2cbc
amzn-ami-hvm-2017.09.rc-0.20170913-x86_64-gp2: ami-d424e7b2
```

最新AMI ID(`ami-da9e2cbc`)が取得できているのがわかります。
> `amzn-ami-hvm-2017.09.1.20171120-x86_64-gp2: ami-da9e2cbc`

取得結果からわかるようにImage名にはスペック名も含まれていることがわかります。

よって今回のスペックのAMI IDはImage名でのフィルタ条件のみで取ることができるため、簡易版ではImage名の値が`"amzn-ami-hvm-*-x86_64-gp2"`とするフィルタ条件1つで最新のAMI IDを取得していました。

また、`aws_ami.tf`では`most_recent = true`という設定により取得した中で最新のAMI IDが取得されます。

:warning: Image名の命名規則が変更された場合に指定スペックの最新が取得できなくなるので注意ください

### フィルタ条件を`name`のみにしてAWS CLIでも確認
AWS CLI側でも一応確認

```diff:get-aws-ec2-image.sh
describe_images(){
    echo $timestamp > $timestamp_file
    aws ec2 describe-images \
        --owners amazon \
        --filters \
          Name=name,Values="amzn-ami-hvm-*-x86_64-gp2" \
-          Name=virtualization-type,Values=hvm \
-          Name=root-device-type,Values=ebs \
-          Name=architecture,Values=x86_64 \
-          Name=block-device-mapping.volume-type,Values=gp2
}
```

```
$ zsh ./get-aws-ec2-image.sh | grep ami-da9e2cbc

amzn-ami-hvm-2017.09.1.20171120-x86_64-gp2: ami-da9e2cbc
```

最新AMI ID(`ami-da9e2cbc`)が取得できているのがわかります。

</details>

## その他の参考
- [Terraform Docs > Data Sources > aws_ami](https://www.terraform.io/docs/providers/aws/d/ami.html)
- [AWS Documentation - AWS Command Line Interface とは](http://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-welcome.html)
- [Linux AMI 仮想化タイプ](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/virtualization_types.html)
- [Amazon EC2 ルートデバイスボリューム](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/RootDeviceStorage.html)
- [Amazon EBS ボリュームの種類](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/EBSVolumeTypes.html)