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:
- The base shell script installs Ansible
- 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 {
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": 300040 }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 PHP10 - nginx # Install & Configure Nginx11 - 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