2017年8月16日水曜日

packer で AWS に AMI イメージを作成してみた

概要

packer を使って AWS 上に AMI のイメージを自動で作成してみました
AWS 側の VPC 設定などではまりポイントがあったので合わせて紹介します

環境

  • CentOS 7.3.1611
  • packer 1.0.3

packer インストール

https://www.packer.io/downloads.html から Linux 64-bit 版をダウンロードします

  • unzip packer_1.0.3_linux_amd64.zip
  • mv packer /usr/local/bin/

PATH が通っているところに適当に移動してください

  • packer -v
1.0.3

でインストール完了です

テンプレートファイルの作成

作成するイメーを定義するテンプレートファイルを作成します

  • example.json
{
  "variables": {
    "aws_access_key": "",
    "aws_secret_key": ""
  },
  "builders": [{
    "type": "amazon-ebs",
    "access_key": "{{user `aws_access_key`}}",
    "secret_key": "{{user `aws_secret_key`}}",
    "region": "ap-southeast-2",
    "source_ami_filter": {
      "filters": {
        "virtualization-type": "hvm",
        "name": "*ubuntu-xenial-16.04-amd64-server-*",
        "root-device-type": "ebs"
      },
      "owners": ["099720109477"],
      "most_recent": true
    },
    "instance_type": "t2.micro",
    "ssh_username": "ubuntu",
    "ami_name": "packer-example {{timestamp}}",
    "subnet_id": "subnet-4b31382f",
    "security_group_id": "sg-c33edba5"
  }]
}

aws_access_key と aws_secret_key の部分は各自のものを入力してください
あとは subnet_id と security_group_id の部分も各自で作成したものに変更してください

  • packer validate example.json

でエラーがでなければビルドを実行できます

ビルドする

ビルドが成功すると最終的には AMI のイメージが作成されて完了になります
AWS 側の設定ミスで結構エラーが出たので以下にまとめています
packer 側というよりか AWS 側の設定のほうが自分は大変でした

  • packer build example.json
amazon-ebs output will be in this color.

==> amazon-ebs: Prevalidating AMI Name...
    amazon-ebs: Found Image ID: ami-546d7437
==> amazon-ebs: Creating temporary keypair: packer_598a4b64-8997-7032-bcee-a3113fdde266
==> amazon-ebs: Launching a source AWS instance...
    amazon-ebs: Instance ID: i-0eeb422db2057ff58
==> amazon-ebs: Waiting for instance (i-0eeb422db2057ff58) to become ready...
==> amazon-ebs: Adding tags to source instance
    amazon-ebs: Adding tag: "Name": "Packer Builder"
==> amazon-ebs: Waiting for SSH to become available...
==> amazon-ebs: Connected to SSH!
==> amazon-ebs: Stopping the source instance...
    amazon-ebs: Stopping instance, attempt 1
==> amazon-ebs: Waiting for the instance to stop...
==> amazon-ebs: Creating the AMI: packer-example 1502235491
    amazon-ebs: AMI: ami-79e7fe1a
==> amazon-ebs: Waiting for AMI to become ready...
==> amazon-ebs: Terminating the source AWS instance...
==> amazon-ebs: Cleaning up any extra volumes...
==> amazon-ebs: No volumes to clean up, skipping
==> amazon-ebs: Deleting temporary keypair...
Build 'amazon-ebs' finished.

==> Builds finished. The artifacts of successful builds are:
--> amazon-ebs: AMIs were created:

ap-southeast-2: ami-79e7fe1a

エラー集

  • Error launching source instance: VPCResourceNotSpecified: The specified instance type can only be used in a VPC. A subnet ID or ne
    twork interface ID is required to carry out the request.

テンプレート内で subnet_id パラメータを使って vpc を指定する必要があります

  • InvalidSubnetID.NotFound: The subnet ID 'vpc-a08048c4' does not exist

指定したリージョン内に vpc -> subnet が存在しません

  • Error launching source instance: InvalidParameter: Security group sg-0d6ccd6a and subnet subnet-d3fe41a5 belong to different networks.

指定したセキュリティグループに指定した vpc が所属していません

  • Timeout waiting for SSH.

指定したサブネットで「自動割り当てパブリック IP」を有効にする必要があります
指定したサブネットの VPC で「DNS 解決」と「DNS ホスト名」を有効にする必要があります
指定したサブネットの VPC にインターネットゲートウェイをアタッチする必要があります
指定したサブネットの VPC にルートテーブルを新規で作成する必要があります
指定したサブネットの VPC に作成したルートテーブルのルートにインターネットゲートウェイを指定する必要があります (送信先: 0.0.0.0/0, ターゲット: 作成したインターネットゲートウェイ)
指定したサブネットの VPC にサブネット関連付けで新規に作成したサブネットを割り当てる必要があります

タイムアウトのエラーに関しては VPC 内に作成されたインスタンスがインターネットに接続できないためにエラーとなるケースがほとんどです
なので、対象の VPC がインターネットに接続できるようになれば OK です

プロビジョニングしてみる

事前に OS 上に必要なパッケージや設定を行うことができます
先程の example.json にプロビジョニング用の設定を追加してみましょう

vim example_provisioning.json

{
  "variables": {
    "aws_access_key": "",
    "aws_secret_key": ""
  },
  "builders": [{
    "type": "amazon-ebs",
    "access_key": "{{user `aws_access_key`}}",
    "secret_key": "{{user `aws_secret_key`}}",
    "region": "ap-southeast-2",
    "source_ami_filter": {
      "filters": {
      "virtualization-type": "hvm",
      "name": "*ubuntu-xenial-16.04-amd64-server-*",
      "root-device-type": "ebs"
      },
      "owners": ["099720109477"],
      "most_recent": true
    },
    "instance_type": "t2.micro",
    "ssh_username": "ubuntu",
    "ami_name": "packer-example {{timestamp}}",
    "subnet_id": "subnet-4b31382f",
    "security_group_id": "sg-c33edba5"
  }],
  "provisioners": [{
    "type": "shell",
    "inline": [
      "sleep 30",
      "sudo apt-get update",
      "sudo apt-get install -y redis-server"
    ]
  }]
}

variables, builders の部分はそのままで、新たに provisioners の項目を追加しています
今回は shell を使って apt コマンドで redis-server をインストールしているだけです

これもビルドしてみましょう
ビルド中に表示されるデバッグ情報に apt install のログも表示されると思います
AMI ができたあとにその AMI から EC2 インスタンスを作成して SSH ログインしてみます
すると redis がすでにインストールされている状態でインスタンスが作成されるのがわかると思います
一点注意が必要なのが SSH ユーザはテンプレートの ssh_username で定義した ubuntu になります

  • ssh -i "your_key.pem" ubuntu@ec2-xx-xxx-xxx-xxx.ap-southeast-2.compute.amazonaws.com

その他

あとは Getting Started に Parallel Build のやり方や Vagrant Box の作成方法や Atlas と連携する方法が紹介されています
興味があれば触ってみると良いかなと思います

最後に

packer と AWS を連携して AMI を自動生成する方法を紹介しました
今回の場合はどちらかというと AWS 側の設定でハマった部分が多かったです
packer 自体は非常に簡単に使えるので便利かなと思います

次回は VMware 上で動作するベースイメージを作成してみたいと思います

参考サイト

0 件のコメント:

コメントを投稿