Skip to content

Instantly share code, notes, and snippets.

@a-r-g-v
Last active October 5, 2018 06:18
Show Gist options
  • Select an option

  • Save a-r-g-v/cb745842b69118c48d770b7cd69b4cb9 to your computer and use it in GitHub Desktop.

Select an option

Save a-r-g-v/cb745842b69118c48d770b7cd69b4cb9 to your computer and use it in GitHub Desktop.
Packer+Circle CIでGoogle Compute Engineのイメージを生成する

Packer+Circle CIでGoogle Compute Engineのイメージを生成する

Google Compute Engineには,Imageという概念があって,AWSではAMIに相当する. Imageには,Image Familyというものがあって,Imageのバージョン管理を行うことができる. 具体的には,Familyはその中に存在する一番最新のImageへのポインタを持っている.DockerfileのFROM name:latestみたいなノリ.

これを使うと,インスタンスを実行する時に,デフォルトは最新のイメージであってほしいんだけれど,過去のバージョンを指定して環境を構築するシーンも想定したい,みたいなニーズを簡単に満たすことができる.

circle.yml は下記の通り.

# circle.yml
machine:
  environment:
    GCLOUD_PROJECT: "argvc-jp"
    CLOUDSDK_COMPUTE_ZONE: "asia-northeast1-a"
    CLOUDSDK_COMPUTE_REGION: "asia-northeast1"
    GOOGLE_APPLICATION_CREDENTIALS: "$HOME/client-secret.json"
  post:
    - echo $CLIENT_KEYS | base64 --decode > $GOOGLE_APPLICATION_CREDENTIALS

dependencies:
  cache_directories:
    - "~/bin"
  pre:
    - mkdir -p ~/packer
    - wget https://releases.hashicorp.com/packer/0.12.0/packer_0.12.0_linux_amd64.zip
    - unzip packer_0.12.0_linux_amd64.zip
    - mv packer ~/bin/packer

test:
  override:
    - ~/bin/packer validate ./packer.json

deployment:
  packer:
    branch: master 
    commands:
      - gcloud auth activate-service-account --key-file $GOOGLE_APPLICATION_CREDENTIALS
      - gcloud config set project $GCLOUD_PROJECT
      - ~/bin/packer build ./packer.json

CircleCI用にGoogle Cloud Platformのサービスアカウントを取得する必要がある.

JSONのサービスアカウントファイルがkeyだとした時,下記コマンドで生成される文字列をCLIENT_KEYSという名前の環境変数に登録した.

cat key | base64 | tr -d "\n" 

packer.json は下記の通り.

{
  "variables" : {
    "project_id": "{{env `GCLOUD_PROJECT`}}",
    "accout_file_path": "{{env `GOOGLE_APPLICATION_CREDENTIALS`}}"
  },
  "builders": [{
    "type": "googlecompute",
    "account_file": "{{user `account_file_path`}}",
    "project_id": "{{user `project_id`}}",
    "source_image": "debian-8-jessie-v20161129",
    "zone": "asia-northeast1-a",
    "ssh_username": "packer",
    "image_family": "openresty",
    "image_name": "openresty-{{uuid}}"
  }], 
  "provisioners": [
  {
    "type": "shell",
    "execute_command": "sudo {{.Path}}",
    "scripts": [
      "openresty.sh"
    ]
  }
  ]
}

サンプルリポジトリがあるので,詳しくはこっちを見てほしい.

https://github.com/a-r-g-v/packer-circleci-gce https://circleci.com/gh/a-r-g-v/packer-circleci-gce

ところで,Packerのマニュアルを見ていると,BuilderのGCEにはsourceのimage_familyを指定できないっぽいことがわかる. (ref: https://www.packer.io/docs/builders/googlecompute.html) これでは,ソースイメージが更新された度に,packer.jsonを変更する必要があって,面倒. 特に,ベースイメージをCIで定期的に自動生成し,ベースイメージの派生イメージとして具体的なアプリケーション用のイメージを生成するようなパターンを適用したい場合,最新版のベースイメージ名を解決する必要があるので,非常にしんどい.

どうにかならないかなーと思ってPull requestsを漁っていると,こういうのがあった. hashicorp/packer#4162

2016/12/10時点ではリリースはされていないが,source_image_familyがサポートされるので,packer.jsonは下記のように書き直せる.

packer.json は下記の通り.

{
  "variables" : {
    "project_id": "{{env `GCLOUD_PROJECT`}}",
    "accout_file_path": "{{env `GOOGLE_APPLICATION_CREDENTIALS`}}"
  },
  "builders": [{
    "type": "googlecompute",
    "account_file": "{{user `account_file_path`}}",
    "project_id": "{{user `project_id`}}",
    "source_image_family": "debian-8",
    "zone": "asia-northeast1-a",
    "ssh_username": "packer",
    "image_family": "openresty",
    "image_name": "openresty-{{uuid}}"
  }], 
  "provisioners": [
  {
    "type": "shell",
    "execute_command": "sudo {{.Path}}",
    "scripts": [
      "openresty.sh"
    ]
  }
  ]
}

べんり.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment