Packer チュートリアルからダミープラグインを書くまで

Packerのチュートリアルを通しました。そのあとに何もしないビルダープラグインを作ってみました。

簡単な説明

PackerはGo製のマシンイメージのビルダーです。 AWS AMI とか Vagrant Box とか作れます。 テンプレートと呼ばれる設定ファイルはJSONHCLv2を使えます。 詳細はドキュメントを読んでください。変数についてのドキュメントは大事です。

テンプレートで指定する builder, provisioner, post-processor などがプラグイン機構を備えています。Hashi CorpメンテナンスとHashi Corpが見つけたコミュニティのプラグインは下からたどれます。

チュートリアル

Packer Tutorialsをやりました。 したみたいなテンプレートを作ってAMIをビルドして削除しました。とくになし。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{
  "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-northeast-1",
      "vpc_id": "vpc-xxxxxxxx",
      "subnet_id": "subnet-yyyyyyyyyy",
      "associate_public_ip_address": true,
      "source_ami_filter": {
        "filters": {
          "virtualization-type": "hvm",
          "name": "ubuntu/images/*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}}"
    }
  ]
}

プラグイン作り

プラグインのドキュメントにしたがって作りました。ドキュメントはいまの最新である1.6系での話です。どうやら1.7以降ではプラグインのインタフェースの定義はhashicorp/packer-plugin-sdkというリポジトリに切り出される予定のようでhashicorp/packerのmasterからは既にインタフェース定義が消されています。 そのため go.mod でバージョン固定しないと master を取ってしまいビルドできないという状態になってしまい時間を使いました。

開発したダミービルダーは 1.6.1 に向けて開発しました。 完全なソースコードはここです。

1
2
3
4
5
6
7
8
module github.com/masu-mi/playground/packer/sample-plugin

go 1.13

require (
        github.com/hashicorp/hcl/v2 v2.6.0
        github.com/hashicorp/packer v1.6.1
)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package main

import (
	"context"

	"github.com/hashicorp/hcl/v2/hcldec"
	"github.com/hashicorp/packer/packer"
	"github.com/hashicorp/packer/packer/plugin"
)

type Builder struct{}

func (b *Builder) Prepare(_ ...interface{}) ([]string, []string, error) {
	return []string{}, []string{}, nil
}

// Run is where the actual build should take place. It takes a Build and a Ui.
func (b *Builder) Run(ctx context.Context, _ packer.Ui, _ packer.Hook) (packer.Artifact, error) {
	return &packer.MockArtifact{}, nil
}

func (b *Builder) ConfigSpec() hcldec.ObjectSpec {
	return map[string]hcldec.Spec{}
}

func main() {
	server, err := plugin.Server()
	if err != nil {
		panic(err)
	}
	server.RegisterBuilder(new(Builder))
	server.Serve()
}
1
2
3
4
5
6
7
8
9
.PHONNY: install build all

build: packer-builder-dummy-builder

packer-builder-dummy-builder: main.go
	go build .

install: packer-builder-dummy-builder
	cp $< $(HOME)/.packer.d/plugins/$<

まずインストールしてみます。 $HOME/.packer.d/plugins/ 配下に packer-${plugin_category}-${plugin_name} としてインストールします。 他の場所も読み込まれるようで詳しくはここを参考にしてください。

1
$ make install

つくった dummy-builder プラグインを呼び出してみると下のようになります。 PACKER_LOGを設定するとログが表示されます

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
$ cat ./test.json
{
  "builders": [ {"type": "dummy-builder", "name": "hoge", "attr": "dummy" } ]
}

$ PACKER_LOG=1  packer build ./test.json
2021/01/06 22:19:34 [INFO] Packer version: 1.6.1 [go1.14.5 darwin amd64]
2021/01/06 22:19:34 [DEBUG] Discovered plugin: dummy-builder = /Users/masumi/.packer.d/plugins/packer-builder-dummy-builder
2021/01/06 22:19:34 [DEBUG] Discovered plugin: sample-plugin = /Users/masumi/.packer.d/plugins/packer-builder-sample-plugin
2021/01/06 22:19:34 using external builders [dummy-builder sample-plugin]
2021/01/06 22:19:34 [DEBUG] Discovered plugin: dummy-builder = /Users/masumi/works/playground/packer/packer-builder-dummy-builder/packer-builder-dummy-builder
2021/01/06 22:19:34 using external builders [dummy-builder]
2021/01/06 22:19:34 Checking 'PACKER_CONFIG' for a config file path
2021/01/06 22:19:34 'PACKER_CONFIG' not set; checking the default config file path
2021/01/06 22:19:34 Attempting to open config file: /Users/masumi/.packerconfig
2021/01/06 22:19:34 [WARN] Config file doesn't exist: /Users/masumi/.packerconfig
2021/01/06 22:19:34 Setting cache directory: /Users/masumi/works/playground/packer/packer-builder-dummy-builder/packer_cache
2021/01/06 22:19:34 Creating plugin client for path: /Users/masumi/works/playground/packer/packer-builder-dummy-builder/packer-builder-dummy-builder
2021/01/06 22:19:34 Starting plugin: /Users/masumi/works/playground/packer/packer-builder-dummy-builder/packer-builder-dummy-builder []string{"/Users/masumi/works/playground/packer/packer-builder-dummy-builder/packer-builder-dummy-builder"}
2021/01/06 22:19:34 Waiting for RPC address for: /Users/masumi/works/playground/packer/packer-builder-dummy-builder/packer-builder-dummy-builder
2021/01/06 22:19:34 Received unix RPC address for /Users/masumi/works/playground/packer/packer-builder-dummy-builder/packer-builder-dummy-builder: addr is /var/folders/v9/6fsv_s4s1bd9p7z1t3dz06qr0000gn/T/packer-plugin161852889
2021/01/06 22:19:34 packer-builder-dummy-builder plugin: 2021/01/06 22:19:34 Plugin address: unix /var/folders/v9/6fsv_s4s1bd9p7z1t3dz06qr0000gn/T/packer-plugin161852889
2021/01/06 22:19:34 packer-builder-dummy-builder plugin: 2021/01/06 22:19:34 Waiting for connection...
2021/01/06 22:19:34 packer-builder-dummy-builder plugin: 2021/01/06 22:19:34 Serving a plugin connection...
2021/01/06 22:19:34 Preparing build: hoge
2021/01/06 22:19:34 Build debug mode: false
2021/01/06 22:19:34 Force build: false
2021/01/06 22:19:34 On error:
2021/01/06 22:19:34 Waiting on builds to complete...
hoge: output will be in this color.
2021/01/06 22:19:34 Starting build run: hoge
2021/01/06 22:19:34 Running builder: dummy-builder

2021/01/06 22:19:34 [INFO] (telemetry) Starting builder dummy-builder
2021/01/06 22:19:34 [INFO] (telemetry) ending dummy-builder
==> Builds finished. The artifacts of successful builds are:
2021/01/06 22:19:34 machine readable: hoge,artifact-count []string{"1"}
Build 'hoge' finished.

==> Builds finished. The artifacts of successful builds are:
2021/01/06 22:19:34 machine readable: hoge,artifact []string{"0", "builder-id", "bid"}
2021/01/06 22:19:34 machine readable: hoge,artifact []string{"0", "id", "id"}
2021/01/06 22:19:34 machine readable: hoge,artifact []string{"0", "string", "string"}
2021/01/06 22:19:34 machine readable: hoge,artifact []string{"0", "files-count", "2"}
2021/01/06 22:19:34 machine readable: hoge,artifact []string{"0", "file", "0", "a"}
2021/01/06 22:19:34 machine readable: hoge,artifact []string{"0", "file", "1", "b"}
--> hoge: string
2021/01/06 22:19:34 machine readable: hoge,artifact []string{"0", "end"}
2021/01/06 22:19:34 [INFO] (telemetry) Finalizing.
2021/01/06 22:19:35 waiting for all plugin processes to complete...
2021/01/06 22:19:35 /Users/masumi/works/playground/packer/packer-builder-dummy-builder/packer-builder-dummy-builder: plugin process exited
comments powered by Disqus