Packer With HCL Configs - datocms-assets.com

Preview:

Citation preview

Packer With HCL Configs

Software Engineer at HashiCorp

Adrien Delorme

UBUNTU IMAGE

GENERIC PROVISIONING

SECURITY

TELEMETRY

BASE SERVER IMAGE

CONSUL IMAGE VAULT IMAGENOMAD IMAGE

Kubernetes

APP IMAGE

App

BASE SERVER IMAGE

KUBERNETES IMAGE

Packer in numbers

34 Builders

Packer in numbers

34 Builders

18 Provisioners

Packer in numbers

34 Builders

22 Post Processors

18 Provisioners

Packer in numbers

34 Builders

22 Post Processors

18 Provisioners 4

Maintainers

Packer in numbers

34 Builders

22 Post Processors

1088 Contributors

18 Provisioners 4

Maintainers

Packer in numbers

Why HCL2

CODE EDITOR

{ "variables": { "aws_access_key": null, "aws_secret_key": "", }, "builders": [{ "type": "amazon-ebs", "region": "{{ user `aws_region` }}", "access_key": "{{ user `aws_access_key` }}", "secret_key": "{{ user `aws_secret_key` }}", "ami_name": "ubuntu-16-04-test-{{ timestamp }}", "source_ami_filter": { "filters": { "virtualization-type": "hvm", "name": "ubuntu-xenial-16.04-amd64-server-*", "root-device-type": "ebs" }, "owners": [ "014720109477" ], "most_recent": true },

...

JSON works but…

CODE EDITOR

{ "variables": { "aws_access_key": null, "aws_secret_key": "", }, "builders": [{ "type": "amazon-ebs", "region": "{{ user `aws_region` }}", "access_key": "{{ user `aws_access_key` }}", "secret_key": "{{ user `aws_secret_key` }}", "ami_name": "ubuntu-16-04-test-{{ timestamp }}", "source_ami_filter": { "filters": { "virtualization-type": "hvm", "name": "ubuntu-xenial-16.04-amd64-server-*", "root-device-type": "ebs" }, "owners": [ "014720109477" ], "most_recent": true },

...

JSON works but… Quotes everywhere

CODE EDITOR

{ "variables": { "aws_access_key": null, "aws_secret_key": "", }, "builders": [{ "type": "amazon-ebs", "region": "{{ user `aws_region` }}", "access_key": "{{ user `aws_access_key` }}", "secret_key": "{{ user `aws_secret_key` }}", "ami_name": "ubuntu-16-04-test-{{ timestamp }}", "source_ami_filter": { "filters": { "virtualization-type": "hvm", "name": "ubuntu-xenial-16.04-amd64-server-*", "root-device-type": "ebs" }, "owners": [ "014720109477" ], "most_recent": true },

...

JSON works but… Variables are quirky

CODE EDITOR

{ "variables": { "aws_access_key": null, "aws_secret_key": "", }, "builders": [{ "type": "amazon-ebs", "region": "{{ user `aws_region` }}", "access_key": "{{ user `aws_access_key` }}", "secret_key": "{{ user `aws_secret_key` }}", "ami_name": "ubuntu-16-04-test-{{ timestamp }}", "source_ami_filter": { "filters": { "virtualization-type": "hvm", "name": "ubuntu-xenial-16.04-amd64-server-*", "root-device-type": "ebs" }, "owners": [ "014720109477" ], "most_recent": true },

...

JSON works but… Everything is parsed at

once

CODE EDITOR

{ "variables": { "aws_access_key": null, "aws_secret_key": "", }, "builders": [{ "type": "amazon-ebs", "region": "{{ user `aws_region` }}", "access_key": "{{ user `aws_access_key` }}", "secret_key": "{{ user `aws_secret_key` }}", "ami_name": "ubuntu-16-04-test-{{ timestamp }}", "source_ami_filter": { "filters": { "virtualization-type": "hvm", "name": "ubuntu-xenial-16.04-amd64-server-*", "root-device-type": "ebs" }, "owners": [ "014720109477" ], "most_recent": true },

...

JSON works but… The User Experience

could be better

BASE SERVER IMAGE

CONSUL IMAGE VAULT IMAGENOMAD IMAGE

Kubernetes

APP IMAGE

App

BASE SERVER IMAGE

KUBERNETES IMAGE

CODE EDITOR

{

"builders": [ { "type": "amazon-ebs" , ... }, { "type": "docker", ... }, { "type": "qemu", ... }, ... ],

"provisioners": [{ "type" : "shell", "scripts": [ "security.sh", "telemetry.sh" ] }],

"post-processors": [{ "type": "manifest", "output": "base-server-image-manifest.json", }]

Build chaining

CODE EDITOR

{ "builds": [ { "builder_type": "docker", "artifact_id": "container-id", "packer_run_uuid": "6d5d3185-fa95-44e1-8775-9e64fe2e2d8f" }, { "builder_type": "amazon-ebs", "artifact_id": "container-id", "packer_run_uuid": "6d5d3185-fa95-44e1-8775-9e64fe2e2d8f" }, { "builder_type": "qemu", "artifact_id": "container-id", "packer_run_uuid": "6d5d3185-fa95-44e1-8775-9e64fe2e2d8f" } ], "last_run_uuid": "6d5d3185-fa95-44e1-8775-9e64fe2e2d8f" }

Build chaining

CODE EDITOR

$ cat base-server-image-manifest.json | jq '.last_run_uuid as $last | .builds | map(select(.packer_run_uuid == $last) | {"base-image-artifact-\(.builder_type)": .artifact_id}) | add'

{ "base-image-artifact-docker": "container-id", "base-image-artifact-amazon-ebs": "ami-123456" }

Build chaining Could be easier

YAML

YAML was not an option

YAML was not an option,

and neither was HCL1.

CODE EDITOR

HCL2 source "amazon-ebs" "my_ubuntu" {

# such comments ! Much wow !

access_key = "${var.aws_access_key}" ami_name = "ubuntu-16-04-test-${local.timestamp}" region = "${var.aws_region}"

source_ami_filter { filters = { name = "ubuntu-xenial-16.04-amd64-server-*" root-device-type = "ebs" virtualization-type = "hvm" }

most_recent = true owners = ["014720109477"] }

...

What Changes

IMAGE.JSON

{ "variables": { "foo": "bar" }, "builders": [{ "type": "vmware-iso", "name": "my_builder" }], "provisioners": [{ "type": "shell" }], "post-processors": [{ "type": "googlecompute-import" }] }

IMAGE.PKR.HCL

variable "foo" { default = "bar" }

IMAGE.JSON

{ "variables": { "foo": "bar" }, "builders": [{ "type": "vmware-iso", "name": "my_builder" }], "provisioners": [{ "type": "shell" }], "post-processors": [{ "type": "googlecompute-import" }] }

IMAGE.PKR.HCL

variable "foo" { default = "bar" } source "vmware-iso" "my_build" { }

IMAGE.JSON

{ "variables": { "foo": "bar" }, "builders": [{ "type": "vmware-iso", "name": "my_builder" }], "provisioners": [{ "type": "shell" }], "post-processors": [{ "type": "googlecompute-import" }] }

IMAGE.PKR.HCL

variable "foo" { default = "bar" } source "vmware-iso" "my_builder" { }

build { sources = ["source.vmware-iso.my_builder"] source "vmware-iso.my_builder" { output = "other_output" } }

CODE EDITOR

{ "variables": { "foo": "bar" }, "builders": [{ "type": "vmware-iso", "name": "my_builder" }], "provisioners": [{ "type": "shell" }], "post-processors": [{ "type": "googlecompute-import" }] }

CODE EDITOR

variable "foo" { default = "bar" } source "vmware-iso" "my_builder" { }

build { sources = ["source.vmware-iso.my_builder"] source "vmware-iso.my_builder" { output = "other_output" }

provisioner "shell" { }

post-processor "googlecompute-import" { }

}

CODE EDITOR

{ "variables": { "foo": "bar" }, "builders": [{ "type": "vmware-iso", "name": "my_builder" }], "provisioners": [{ "type": "shell" }], "post-processors": [{ "type": "googlecompute-import" }] }

CODE EDITOR

variable "foo" { default = "bar" } source "vmware-iso" "my_builder" { }

build { sources = ["source.vmware-iso.my_builder"] source "vmware-iso.my_builder" { output = "other_output" }

provisioner "shell" { }

post-processor "googlecompute-import" { }

}

. ├── build.ubuntu.pkr.hcl ├── source.vmware-iso.pkr.hcl ├── variables.ubuntu.20.04.pkr.hcl ├── settings.auto.pkrvars.hcl └── etc └── scripts

Split HCL2 config files

.pkr.hclSplit HCL2 config files

.pkr.hcl

.pkrvars.hclSplit HCL2 config files

.pkr.hcl

.pkrvars.hcl

.pkr.json

Split HCL2 config files

HCL2 JSON != Classical JSONCODE EDITOR

{ "foo": "bar", "baz": 42 }

IMAGE.JSON

variable "foo" { default = "bar" }

source "vmware-iso" "my_builder" { }

build { sources = [ "source.vmware-iso.my_builder" ]

provisioner "shell" { }

post-processor "googlecompute-import" { } }

IMAGE.PKR.HCL

{ "variable": { "foo": { "default": "bar" } }, "source": { "vmware-iso": { "my_builder": {} } }, "build": { "sources": ["source.vmware-iso.my_builder"], "provisioner": [ { "shell": {} } ], "post-processor": [ { "googlecompute-import": {} } ] } }

Caveats

HCL2 support is in beta

Some parts depend on Go interpolation

CODE EDITOR

locals { ubuntu_1804_boot_command = [ "<esc><wait>", "<enter><wait>", "/install/vmlinuz<wait>",

# ...

"preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/${var.preseed}", ] }

Go interpolation HCL Interpolation

CODE EDITOR

${upper("{{user `my_var`}}")}

> "{{USER `MY_VAR`}}" Avoid

CODE EDITOR

${upper("{{user `my_var`}}")}

> "{{USER `MY_VAR`}}"

# this works: ${upper("${var.my_var}")}

Avoid

Upcoming

Chaining builds

Terraform interoperability

Remove Go templating

Packer Plugin Repository

Thanks!Don't hesitate to reach out on adrien@hashicorp.com or team-packer@hashicorp.com

github.com/hashicorp/packer is the best place for issues

discuss.hashicorp.com is the best place for questions

Recommended