訳しながら理解していくPacker_Amazon AMI Builder編

## はじめに
Packerのドキュメントって英語だし、英検3級レベルで英語力のない私にはつらい・・・
そして、一回(google翻訳を使って)訳しながら読んでまた忘れてまた(google翻訳を使って)訳すを繰り返すのをやめたい。
調べるときは全文を見ずに、必要な部分だけを見てたりするので、公式ドキュメントを訳しながら全体を理解していこうと思う。

英語読むのめんどくせーーーとなっている人の助けになればと思い公開した

今回は [Amazon AMI Builder](https://www.packer.io/docs/builders/amazon.html)


## 注意事項
* 基本的にGoogle翻訳のまんまです。
* 一応、意味が分かるようには訳してるつもりですが、ちょいちょい意味分からない部分もあります。  
誤訳がある可能性があるので、最後はちゃんと公式ドキュメントを読みましょう
* 私の知りたい部分からやるので、訳す部分はバラバラになります。
* 公式ドキュメントに記載されていない部分(自分で調べた部分とか)は_italic_で記載しています。

# Amazon AMI Builder
PackerはAmazon AMIを作成することができます。これを実現するために、Packerには、AMIを構築するために使用する戦略に応じて複数のビルダーが付属しています。 Packerは現時点で次のビルダーをサポートしています。

* amazon-ebs - プロビジョニング後、ソースAMIを起動し、新しいAMIに再パッケージングすることにより、EBS-backedのAMIを作成します。不明な点がある場合は、このビルダーを使用してください。このビルダーを使い始めるのが最も簡単です。
* amazon-instance - ソースインスタンスを起動してプロビジョニングし、インスタンスを再構築してS3にアップロードすることによって、インスタンスストアAMIを作成します。
* amazon-chroot - ルートデバイスをマウントし、そのデバイスをプロビジョニングするためにChroot環境を使用して、既存のEC2インスタンスからEBS-backed AMIを作成します。これは**高度なビルダーであり、初心者には使用しないでください。**ただし、新しいEC2インスタンスを起動する必要がないため、EBSでバックアップされたAMIを構築するための最速の方法です。
* amazon-ebssurrogate - EBS-backedされたAMIをゼロから作成します。 chrootビルダーと同様に動作しますが、AWSで実行する必要はありません。これは**高度なビルダーであり、初心者には使用しないでください。**

>**どのビルダーを使用するのか分かりませんか？**疑わしい場合は、amazon-ebsビルダーを使用してください。使用するのがはるかに簡単で、Amazonは一般的にEBSでバックアップされたイメージを現在推奨しています。

# Amazon EBS Volume Builder
Packerは、ファイルシステムとデータで初期化されているAmazon EBSボリュームを作成することができます。

* amazon-ebsvolume - ブロックデバイスがマップされたソースAMIを起動して、EBSボリュームを作成します。インスタンスをプロビジョニングし、EBSボリュームを保持してインスタンスを破棄します。

## Authentication
AWSプロバイダは、認証用の資格情報を提供する柔軟な手段を提供します。以下の方法が、この順序でサポートされ、以下で説明されています。

* Static credentials
* Environment variables
* Shared credentials file
* EC2 Role

### Static Credentials
静的認証情報は、アクセスキーIDおよび秘密の形式で提供することができます。これらは次のようになります。


```json
{
    "access_key": "AKIAIOSFODNN7EXAMPLE",
    "secret_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
    "region": "us-east-1",
    "type": "amazon-ebs"
}
```

### Environment variables
AWSアクセスキーとAWS秘密キーを表す環境変数AWS_ACCESS_KEY_IDとAWS_SECRET_ACCESS_KEYを使用して、資格情報を提供できます。 これらの環境変数を使用してAWS認証情報を設定すると、AWS_SHARED_CREDENTIALS_FILEとAWS_PROFILEの使用が上書きされます。環境変数AWS_DEFAULT_REGIONおよびAWS_SESSION_TOKENも使用されます（該当する場合）。

Usage:

```shell
$ export AWS_ACCESS_KEY_ID="anaccesskey"
$ export AWS_SECRET_ACCESS_KEY="asecretkey"
$ export AWS_DEFAULT_REGION="us-west-2"
$ packer build packer.json
```

### Shared Credentials file
AWS資格情報ファイルを使用して資格情報を指定することができます。デフォルトの場所は、LinuxおよびOS Xの場合は$HOME/.aws/credentials、Windowsの場合は "％USERPROFILE％.aws\credentials"です。インラインで、または環境内で資格情報を検出できない場合、Packerはこの場所を確認します。 AWS_SHARED_CREDENTIALS_FILE変数を使用して環境を設定することによって、構成内の別の場所を指定することもできます（オプション）。

資格情報ファイルの形式は次のとおりです

```ini
[default]
aws_access_key_id=<your access key id>
aws_secret_access_key=<your secret access key>
```

プロファイル設定オプションを設定するか、またはAWS_PROFILE環境変数を設定することによって、使用するプロファイルを設定することもできます：

```json
{
    "profile": "customprofile",
    "region": "us-east-1",
    "type": "amazon-ebs"
}
```

### IAM Task or Instance Role
最後に、Packerは、タスクまたはインスタンスのIAMロール（存在する場合）によって提供された資格情報を使用します。

これは、EC2で実行しているときに、他のシステムより優先されるアプローチで、ハードウェアコーディング資格を避けることができます。代わりに、これらはPackerによってオンザフライでリースされ、リークの可能性を低減します。

次のポリシー文書は、Packerが動作するために必要な最低限のアクセス許可を提供します。

```json
{
  "Version": "2012-10-17",
  "Statement": [{
      "Effect": "Allow",
      "Action" : [
        "ec2:AttachVolume",
        "ec2:AuthorizeSecurityGroupIngress",
        "ec2:CopyImage",
        "ec2:CreateImage",
        "ec2:CreateKeypair",
        "ec2:CreateSecurityGroup",
        "ec2:CreateSnapshot",
        "ec2:CreateTags",
        "ec2:CreateVolume",
        "ec2:DeleteKeyPair",
        "ec2:DeleteSecurityGroup",
        "ec2:DeleteSnapshot",
        "ec2:DeleteVolume",
        "ec2:DeregisterImage",
        "ec2:DescribeImageAttribute",
        "ec2:DescribeImages",
        "ec2:DescribeInstances",
        "ec2:DescribeRegions",
        "ec2:DescribeSecurityGroups",
        "ec2:DescribeSnapshots",
        "ec2:DescribeSubnets",
        "ec2:DescribeTags",
        "ec2:DescribeVolumes",
        "ec2:DetachVolume",
        "ec2:GetPasswordData",
        "ec2:ModifyImageAttribute",
        "ec2:ModifyInstanceAttribute",
        "ec2:ModifySnapshotAttribute",
        "ec2:RegisterImage",
        "ec2:RunInstances",
        "ec2:StopInstances",
        "ec2:TerminateInstances"
      ],
      "Resource" : "*"
  }]
}
```

スポットインスタンスを作成する場合は、次のものも追加する必要があります。

```
ec2:RequestSpotInstances,
ec2:CancelSpotInstanceRequests,
ec2:DescribeSpotInstanceRequests
```

spot_priceパラメータをautoに設定した場合は、次のものも追加する必要があります。

```
ec2:DescribeSpotPriceHistory
```

## Troubleshooting

### Attaching IAM Policies to Roles
IAMポリシーは、ユーザーまたは役割に関連付けることができます。 IAMロールでpackerを使用すると、次のようなエラーが発生することがあります。

`==> amazon-ebs: Error launching source instance: You are not authorized to perform this operation.`

[Amazon Security Blog](https://aws.amazon.com/jp/blogs/security/granting-permission-to-launch-ec2-instances-with-iam-roles-passrole-permission/)でこれがなぜ発生するのか、さらに詳しく知ることができます。以下のポリシー例は、packerがIAMのroleを使用するのに役立ちます。この例は、packerが動作するのに必要な最小限のパーミッション以上のものを提供していますが、具体的な内容はユースケースによって異なります。

```json
{
    "Sid": "PackerIAMPassRole",
    "Effect": "Allow",
    "Action": "iam:PassRole",
    "Resource": [
        "*"
    ]
}
```

### Checking that system time is current
Amazonは現在の時刻を[リクエスト署名プロセス](https://docs.aws.amazon.com/ja_jp/general/latest/gr/sigv4_signing.html)の一部として使用します。現在の時刻からシステムクロックがずれていると、要求が失敗する可能性があります。そのような場合は、次のようなエラーが表示されることがあります。

`==> amazon-ebs: Error querying AMI: AuthFailure: AWS was not able to validate the provided access credentials`

あなたのシステムの日付が間違っていると思われる場合は、それをhttp://www.time.gov/と比較することができます。Linux / OS Xでは、現在の時刻を取得するためにdateコマンドを実行できます。 Linuxの場合は、sudo ntpd -qを実行してntpで時間を設定してみてください。

### exceeded wait attempts while waiting for tasks to complete
AWS SDKに組み込まれたウェイターを使用して、長時間実行されるタスクが完了するまで待ちます。これらのウェイターには、クエリーの間にデフォルトの遅延があり、ユーザーにとって常に機能しないクエリーの最大数があります。

レート制限されているか、最大待ち時間を超えている場合は、次のpacker環境変数を設定してデフォルトを上書きすることができます（これは待機しなければならないすべてのawsタスクに適用されます）。

AWS_MAX_ATTEMPTS - これは、ステータス更新要求を再送信する回数です。非常に長い時間がかかることがわかっているタスクを除いて、デフォルトは40triesです。

AWS_POLL_DELAY_SECONDS - ステータス更新要求の間に待機する秒数。タスクに応じて、通常はデフォルトで2秒または5秒です。