Ansible Provisioner

Packer has a lot of provisioner available! Your favorite server provisioner is probably supported.

This video will show an example of using Ansible ("local") to provision a server as well.

Here's what we're doing in a nutshell:

  1. The base shell script installs Ansible
  2. The ansible builder uploads the Ansible files to the server and runs them on the server

Ansible-local runs them locally within the server. Ansible-remote would run them on the host server via SSH. You can do either!

1{
2 "min_packer_version":"1.0.0",
3 "variables":{
4 "infra_name": "cloudcasts",
5 "infra_env": "",
6 "aws_region": "us-east-2",
7 "aws_instance": "t3.small",
+ "vault_pass": ""
9 },
10 "builders":[
11 { Click to show }
12 "type":"amazon-ebs",
13 "ami_name":"{{user `infra_name`}}-{{user `infra_env`}}-{{timestamp}}-app",
14 "instance_type":"{{user `aws_instance`}}",
15 "region":"{{user `aws_region`}}",
16 "profile": "cloudcasts",
17 
18 "source_ami_filter": {
19 "filters": {
20 "architecture": "x86_64",
21 "name": "ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*",
22 "root-device-type": "ebs",
23 "virtualization-type": "hvm"
24 },
25 "most_recent": true,
26 "owners": [
27 "099720109477"
28 ]
29 },
30 "ssh_username":"ubuntu",
31 "launch_block_device_mappings":[
32 {
33 "device_name":"/dev/sda1",
34 "volume_size":8,
35 "delete_on_termination":true,
36 "encrypted":false,
37 "volume_type":"gp3",
38 "throughput": 125,
39 "iops": 3000
40 }
41 ],
42 "tags":{
43 "Name":"{{user `infra_name`}}-{{user `infra_env`}}-{{timestamp}}-app",
44 "Project":"{{user `infra_name`}}",
45 "Environment":"{{user `infra_env`}}",
46 "Role":"baked-ami",
47 "Unique":"baked-ami-{{timestamp}}",
48 "ManagedBy":"packer",
49 "Component":"app"
50 }
51 }
52 ],
53 "provisioners":[
54 {
55 "script": "{{template_dir}}/scripts/base.sh",
56 "type": "shell"
- }
+ },
+ {
+ "type": "ansible-local",
+ "playbook_file": "ansible/app.yml",
+ "command": "echo '{{user `vault_pass`}}' | ansible-playbook",
+ "role_paths": [
+ "ansible/roles/base",
+ "ansible/roles/php",
+ "ansible/roles/nginx",
+ "ansible/roles/app"
+ ],
+ "extra_arguments": ["--vault-password-file=/bin/cat", "--extra-vars \"infra_env={{user `infra_env`}}\""],
+ "group_vars": "ansible/group_vars"
+ }
72 ]
73}

And we need the file ansible/app.yml:

1---
2- hosts: all
3 user: ubuntu
4 become: yes
5 become_user: root
6 become_method: sudo
7 roles:
8 - base # Install basic utilities like jq
9 - php # Install & Configure PHP
10 - nginx # Install & Configure Nginx
11 - app # Get the server ready to serve an app

We can run the above Ansible provisioner in Packer with a little helper script (or just this command directly):

1ANSIBLEPW=`cat .vault`
2 
3packer build \
4 -var "infra_env=staging" \
5 -var "vault_pass=$ANSIBLEPW" \
6 cloudcasts-app.json

Don't miss out

Sign up to learn when new content is released! Courses are in production now.