Skip to content

Commit a1ee965

Browse files
committed
Aws-ami-packer-ansible.md
1 parent 9f40b5e commit a1ee965

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
---
2+
layout: post
3+
title: "Building AWS AMIs with Packer-Ansible: tips and tricks"
4+
image:
5+
feature: cresta.jpg
6+
credit: Richelmo Giupponi
7+
excerpt: "Some tips and tricks on how to use Packer and Ansible with the base AWS Linux AMI."
8+
tags: [ec2, aws, ansible, packer]
9+
comments: true
10+
---
11+
12+
Continuous deploy with immutable infrastructure requires an automatic and robust workflow for building virtual machines. This article lists some tips and tricks on how to use [Packer](https://www.packer.io/) and [Ansible](https://www.ansible.com) with the base AWS Linux AMI.
13+
Using [Packer](https://www.packer.io/) and [Ansible](https://www.ansible.io), a simple bash script “wrapper” can be responsible to build, provision and deploy AMIs into your AWS infrastructure.
14+
<BR>
15+
<BR>
16+
17+
Immutable infrastructure practices require to treat virtual machines as disposable tools, meant to be thrown away and recreated from scratch when we want/must change something (new application code, software upgrades, OS tweaking, …).
18+
<BR>
19+
<BR>
20+
21+
Packer is a tool to portably create machine images. It can build VM artifacts for different platforms such as AWS EC2, Azure, DigitalOcean, Docker, GCE, …
22+
Code attached here refers to the cooking of AWS EC2 instances.
23+
<BR>
24+
<BR>
25+
26+
Creating virtual machines portably and à-la-carte sounds cool, but what is even cooler is that Packer can also be instructed to wrap your infrastructure provisioner of choice ( Ansible, Chef, Puppet, Salt and some others) while baking a machine.
27+
Packer building logic and parameters are defined in a JSON template file: please refer to [intro](https://www.packer.io/intro/) and [docs](https://www.packer.io/docs/) pages for details.
28+
<BR>
29+
<BR>
30+
31+
In the following, we list tips and tricks adopted to automatically build and provision Sequra AWS machines based on [encrypted AMIs](https://engineering.sequra.es/2016/09/building-an-aws-ami-with-encrypted-root-device/).
32+
<BR>
33+
<BR>
34+
35+
## Wrap packer templates into bash scripts
36+
37+
The first trick that we suggest is to create a script that wraps both the JSON Packer template and the commands/variables necessary to execute the command, i.e.
38+
39+
40+
{% highlight bash %}
41+
###
42+
# ... params management
43+
###
44+
45+
AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-'your_aws_access_key_id_here'}
46+
AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-'your_aws_access_secret_key_here'}
47+
48+
cat > $PACKER_TEMPLATE << PACKER
49+
...
50+
... Your Packer template, with bash and ENV variables to make it more flexible
51+
...
52+
PACKER
53+
54+
time packer build -var "aws_access_key=$AWS_ACCESS_KEY_ID" \
55+
-var "aws_secret_key=$AWS_SECRET_ACCESS_KEY" \
56+
$PACKER_TEMPLATE
57+
58+
rm $PACKER_TEMPLATE
59+
{% endhighlight %}
60+
61+
Putting AWS credentials in environment variables might not be the best solution, but it is not the focus here. Feel free to implement different ways to pass them to packer.
62+
63+
## Non-standard location of sftp-server command on AWS Linux AMIs
64+
65+
This tip can save you from setting debug options in Ansible and Packer to skim through logs in order to understand why you cannot provision an AWS Linux machine with the Packer test template found in the documentation.
66+
67+
68+
{% highlight bash %}
69+
...
70+
"provisioners": [
71+
{
72+
...
73+
"sftp_command": "/usr/libexec/openssh/sftp-server -e"
74+
...
75+
}
76+
]
77+
...
78+
{% endhighlight %}
79+
80+
## Packer does not support Ansible remote_user in playbooks
81+
82+
Packer connects to instances to push and run Ansible code only with the user you specify in the builder of the packer template.
83+
Full stop. No can do. Just try some other solution.
84+
85+
86+
{% highlight bash %}
87+
...
88+
"builders": [{
89+
...
90+
"ssh_username": "ec2-user",
91+
...
92+
}],
93+
...
94+
{% endhighlight %}
95+
96+
The same happens for ansible_user in configuration files, i.e. it is useless.
97+
<BR>
98+
<BR>
99+
100+
This is a [poorly documented](https://github.com/hashicorp/packer/issues/3828) packer “feature” that can cause headaches. It is actually [under discussion](https://github.com/hashicorp/packer/issues/3889) and the issue we opened seems to be taken as case study.
101+
102+
## ec2-user to non-root users
103+
104+
Another trick we implemented is due to the fact that Ansible 2.1 and above versions by default do not allow to become an unprivileged user from non-root users. There are [sound security reasons](http://docs.ansible.com/ansible/become.html#becoming-an-unprivileged-user) for this, but this is a pity as on AWS AMIs sudo-ed root users are called ec2-user (or ubuntu), and this security measure then impedes become_user tasks, a very common pattern when provisioning with Ansible.
105+
In our case, we can use the workaround that Ansible people suggest to modify this default behaviour, i.e. we can put
106+
107+
108+
{% highlight bash %}
109+
allow_world_readable_tmpfiles = True
110+
{% endhighlight %}
111+
112+
in your ansible configuration file.
113+
114+
## Conclusions
115+
116+
We have shown here that, with a bit of effort, it is possible to couple the great power of Ansible and Packer to build AWS Linux machines: all testing was done with version 2016.09.0, but the tips will probably apply to more versions. This can be used in a continuous delivery/deploy solution in order to allow immutable infrastructure pipelines, where phrases as ‘cap stage deploy’, ‘apt-get update’, … are not very welcome.
117+
118+
119+

0 commit comments

Comments
 (0)