2016年7月31日日曜日

[AWS] AMIへのリリースを Packer で自動化する


AMIに埋め込んだ、HTMLページを更新したいと思います。

直接AMIの更新はできないので、以下のような手順で新しいAMIを作り直すことになります。
  1. AMIからEC2インスタンスを起動する
  2. EC2インスタンスにHTMLページを配置する
  3. EC2インスタンスを停止する
  4. 新しいAMIを作成する
この手順を Packer で自動化してみます。

テンプレートは以下のとおり。
このテンプレートでは、環境変数でパラメータを設定し、パブリックIPでSSH(SCP)接続します。
ec2-user には、/var/ww/html 以下を触れる権限がないので、一旦、/tmp にアップロードした後にコピーします。

{
 "variables": {
    "server_name": "{{env `BUILD_SERVER_NAME`}}",
    "ami": "{{env `BUILD_AMI`}}",
    "volume_size": "{{env `BUILD_EBS_SIZE`}}",
    "src_path": "{{env `BUILD_SPATH`}}",
    "dst_path": "{{env `BUILD_DPATH`}}"
  },
  "builders" : [{
    "type" : "amazon-ebs",
    "access_key": "AKIAIC2J7TWPXY2L2HGQ",
    "secret_key": "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",
    "region" : "us-east-1",
    "availability_zone" : "us-east-1b",
    "instance_type" : "t2.nano",
    "source_ami" : "{{user `ami`}}",
    "launch_block_device_mappings": [
      {
        "device_name": "/dev/xvda",
        "volume_size": "{{user `volume_size`}}",
        "volume_type": "gp2",
        "delete_on_termination": "true"
      }
    ],
    "subnet_id" : "subnet-f528a2ad",
    "associate_public_ip_address" : "true",
    "security_group_id": "sg-bbf176df",
    "ssh_keypair_name" : "virginia_key",
    "ssh_username" : "ec2-user",
    "ssh_private_key_file" : "/root/workspace/packer/virginia_key.pem",
    "ami_name" : "TEST-AMI-{{user `server_name`}}",
    "ami_description" : "{{user `server_name`}} created by packer",
    "tags" : {
      "Name" : "{{user `server_name`}}",
      "Environment" : "develop"
    }
  }],
  "provisioners" : [
    {
     "type" : "file",
     "source" : "{{user `src_path`}}",
     "destination" : "{{user `dst_path`}}"
    },
    {
     "type" : "shell",
     "inline" : [ "sudo /bin/cp /tmp/index.html /var/www/html/index.html", "/bin/rm -f /tmp/index.html"  ]
    }
   ]
}

実行は以下のとおり。

[root@localhost packer]# env BUILD_SERVER_NAME=web01-002 BUILD_AMI=ami-5d901b4a BUILD_EBS_SIZE=8 BUILD_SPATH=/root/workspace/packer/index.html BUILD_DPATH=/tmp/index.html packer build packer.json
amazon-ebs output will be in this color.

==> amazon-ebs: Prevalidating AMI Name...
==> amazon-ebs: Inspecting the source AMI...
==> amazon-ebs: Launching a source AWS instance...
    amazon-ebs: Instance ID: i-75cb94e5
==> amazon-ebs: Waiting for instance (i-75cb94e5) to become ready...
==> amazon-ebs: Waiting for SSH to become available...
==> amazon-ebs: Connected to SSH!
==> amazon-ebs: Uploading /root/workspace/packer/index.html => /tmp/index.html
==> amazon-ebs: Provisioning with shell script: /tmp/packer-shell671690326
==> amazon-ebs: Stopping the source instance...
==> amazon-ebs: Waiting for the instance to stop...
==> amazon-ebs: Creating the AMI: TEST-AMI-web01-002
    amazon-ebs: AMI: ami-c177e1d6
==> amazon-ebs: Waiting for AMI to become ready...
==> amazon-ebs: Modifying attributes on AMI (ami-c177e1d6)...
    amazon-ebs: Modifying: description
==> amazon-ebs: Adding tags to AMI (ami-c177e1d6)...
    amazon-ebs: Adding tag: "Name": "web01-002"
    amazon-ebs: Adding tag: "Environment": "develop"
==> amazon-ebs: Tagging snapshot: snap-661c2288
==> amazon-ebs: Terminating the source AWS instance...
==> amazon-ebs: Cleaning up any extra volumes...
==> amazon-ebs: No volumes to clean up, skipping
Build 'amazon-ebs' finished.

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

us-east-1: ami-c177e1d6