Posted on 2018-03-19
This is the second part of a post series What’s new in Ansible 2.5. In the previous post we learned the basic steps to deploy a server on Vultr.
In this follow up post, you will see how we can secure our server.
Vultr has the concept of “Firewall Groups” also known as “Security Groups”. One group can have one or more Firewall rules and one server can be assigned to exactly one group.
That said, I think we need to create a firewall group. Let’s create one.
But first we look back what we got in our existing playbook:
|
|
The module to create a firewall group is called vr_firewall_group
, unsurprisingly.
We try to add the task to the existing play:
|
|
That doesn’t look to wrong, but the challenge here is, we don’t want to create a group for each cloud hosts, just one group in total.
Yes, you are right! This could be achieved by adding a run_once: yes
to this task.
|
|
Yes, that would work. However, there is a drawback when a play uses serial
. The run_once: yes
would be executed for every batch of host.
That is why I prefer to create a separate play with target localhost
for the things that only needs to be applied once in total. And it makes things much more clear, let’s change that.
|
|
For the new play with target localhost
, we skip local_action
because the scope is already local. Great, let’s add some HTTP rules.
For adding firewall rules, we use the vr_firewall_rule
module. It only creates one rule at a time, but with existing Ansible functionality, we are able to apply a list of rules.
We place the task right to the first play right after the firewall group task, because it also only needs to be run once.
|
|
We added 2 rules with a list of dicts and let ansible loop over it to create each rule.
Once this has been set up, our cloud servers only needs to have the firewall group web
assigned.
|
|
I think we are ready to run our evolved playbook! I take the chance to show you another super useful feature of the vultr ansible modules, the --diff
support!
We see exactly what changed:
ansible-playbook playbooks/cloud.yml -i hosts/production --diff
PLAY [localhost] ***************************************************************
TASK [Create a firewall group] *************************************************
--- before
+++ after
@@ -1 +1,3 @@
-{}
+{
+ "description": "web"
+}
changed: [localhost]
TASK [Create firewall rules] ***************************************************
--- before
+++ after
@@ -1 +1,9 @@
-{}
+{
+ "FIREWALLGROUPID": "fda48556",
+ "direction": "in",
+ "ip_type": "v4",
+ "port": 80,
+ "protocol": "tcp",
+ "subnet": "0.0.0.0",
+ "subnet_size": "0"
+}
changed: [localhost] => (item={u'cidr': u'0.0.0.0/0', u'start_port': 80})
--- before
+++ after
@@ -1 +1,9 @@
-{}
+{
+ "FIREWALLGROUPID": "fda48556",
+ "direction": "in",
+ "ip_type": "v4",
+ "port": 443,
+ "protocol": "tcp",
+ "subnet": "0.0.0.0",
+ "subnet_size": "0"
+}
changed: [localhost] => (item={u'cidr': u'0.0.0.0/0', u'start_port': 443})
PLAY [cloud] *******************************************************************
TASK [Ensure a cloud server exists] ********************************************
--- before
+++ after
@@ -1,3 +1,3 @@
{
- "firewall_group": null
+ "firewall_group": "web"
}
changed: [web-01 -> localhost]
PLAY RECAP *********************************************************************
localhost : ok=2 changed=2 unreachable=0 failed=0
web-01 : ok=1 changed=1 unreachable=0 failed=0
That’s it for today. Hope you enjoyed the reading and looking forward to the follow up posts!