patternMinor
Structuring Ansible playbooks for low volume, purpose-built images
Viewed 0 times
builtimageslowstructuringplaybooksforpurposeansiblevolume
Problem
I hope this question is not too vague / opinion-based:
I need to create and maintain a handful of virtual machines that get packaged up and deployed out to thousands of users, depending on specific requirements. Everyone is doing roughly the same job, but different people need different tools. This is important because I don't think I can structure things around roles (though I'm happy to be told I'm wrong).
They way I have things structured now is:
With this approach, it basically means that when I get a requirement for a new machine, I have to create a new Playbook42.yml, use
Is there a more "Ansible official" or industry standard approach to doing this?
I need to create and maintain a handful of virtual machines that get packaged up and deployed out to thousands of users, depending on specific requirements. Everyone is doing roughly the same job, but different people need different tools. This is important because I don't think I can structure things around roles (though I'm happy to be told I'm wrong).
They way I have things structured now is:
vagrant-directory
|-Vagrantfile # Multi-host setup, with one machine per "use-case"
|-scripts/ # Shell scripts run by Vagrant (mostly used to install Ansible prereqs)
|-ansible/ # All Ansible-related files
|----Playbook1.yml # One playbook per use case
|----tasks/ # Contains task files for everything I want to do
|------install/ # All task files related to installing software
|------apt-update.yml # For example, a script to run apt update
|------iptables-flush.yml # Disable iptablesWith this approach, it basically means that when I get a requirement for a new machine, I have to create a new Playbook42.yml, use
import_tasks for the tasks that I need, create any machine-specific tasks, and then provision and export.Is there a more "Ansible official" or industry standard approach to doing this?
Solution
Unless I totally missed your question, roles are exactly what you need in this case. I'll use examples from my real world. My code below is just to illustrate my point (so it is not fully runnable, might contain errors and is not bullet proof rocket science: you will probably have to adapt/overcome tools limitations). But at least you'll be able to tell me if I got you wrong.
Let's say your servicing a large community of developers on different techs: java, php, nodejs, scala, python, ruby... needing some tools as well like apache, nginx, postgres, mysql, redis...
You have a role for each of these techs/tools, and possibly use existing ones from galaxy that you don't even have to write and that you can download at provisioning time. These roles can possibly be controlled with vars to choose e.g. versions. (see vagrant provisionner config below)
Now, one way you can activate/deactivate roles in a play is with the use of tags
Your unique playbook could look something like this
With such a structure, you can now configure your ansible provisioinner in vagrant defining the tags and specifying the vars needed to provision with your single playbook.
Does this fit your needs ?
Note: if a single playbook is too much of a hassle, you can still use the roles and assemble in each playbook the techs/tools you need and reuse things that you will need in several places.
Let's say your servicing a large community of developers on different techs: java, php, nodejs, scala, python, ruby... needing some tools as well like apache, nginx, postgres, mysql, redis...
You have a role for each of these techs/tools, and possibly use existing ones from galaxy that you don't even have to write and that you can download at provisioning time. These roles can possibly be controlled with vars to choose e.g. versions. (see vagrant provisionner config below)
Now, one way you can activate/deactivate roles in a play is with the use of tags
Your unique playbook could look something like this
- name: Vagrant provisionning playbook
hosts: all
pre_tasks:
# whatever you need to do before roles
roles:
- role: php
tags: [php]
- role: java
tags: [java]
- role: nginx
tags: [nginx,php] # if you always deploy php with nginx
- role: redis
tags: [redis]
# more roles here
tasks:
# Whatever tasks are needed to be played after rolesWith such a structure, you can now configure your ansible provisioinner in vagrant defining the tags and specifying the vars needed to provision with your single playbook.
Vagrant.configure(2) do |config|
config.vm define "php_application" do |php_application|
# Some config for vm
php_application.vm.provision "ansible" do |ansible|
ansible.playbook = "playbook.yml"
ansible.tags = "php,nginx,untagged"
end
end
# Host vars declared globally. You might be able to do
# it on host by host basis but the doc does not specify it
config.vm.provision "ansible" do |ansible|
ansible.host_vars = {
"php_application" => {"php_version" => "7.2"}
}
end
endDoes this fit your needs ?
Note: if a single playbook is too much of a hassle, you can still use the roles and assemble in each playbook the techs/tools you need and reuse things that you will need in several places.
Code Snippets
- name: Vagrant provisionning playbook
hosts: all
pre_tasks:
# whatever you need to do before roles
roles:
- role: php
tags: [php]
- role: java
tags: [java]
- role: nginx
tags: [nginx,php] # if you always deploy php with nginx
- role: redis
tags: [redis]
# more roles here
tasks:
# Whatever tasks are needed to be played after rolesVagrant.configure(2) do |config|
config.vm define "php_application" do |php_application|
# Some config for vm
php_application.vm.provision "ansible" do |ansible|
ansible.playbook = "playbook.yml"
ansible.tags = "php,nginx,untagged"
end
end
# Host vars declared globally. You might be able to do
# it on host by host basis but the doc does not specify it
config.vm.provision "ansible" do |ansible|
ansible.host_vars = {
"php_application" => {"php_version" => "7.2"}
}
end
endContext
StackExchange DevOps Q#6764, answer score: 2
Revisions (0)
No revisions yet.