I am currently taking my first steps with ansible, so this might be a basic question.

I am trying to configure a server with ansible that hosts a couple of webpages and exposes a number of other services as well. For each of these, I optionally want to be able to

  • Register a subdomain with the nameserver that is one of the services
  • Use Let's Encrypt to issue a certificate for the service
  • Open sme ports in my firewall

I currently also have roles to setup nameserver, let's encrypt, and firewall. What are the best practises to communicate between the roles? Should e.g. the webserver role know the exact command how to create a certificate for itself, or is there a way to abstract this to a notify call maybe? Should each service role be able to write to my firewall configuration file, or should this be a privilege of the firewall role somehow?

Maybe I am too much in a programmer's mindset, but I like things like "separation on concern" and I'd like to be able to change e.g. my firewall software without having to change every other role as well.


It is not possible to provide an exact answer to your question for obvious reasons, but let me at least point out some bits, some of them will be very easily understandable from a programmer's point of view:

  1. Keep data and logic separated. ansible provides the means to make this an easy task, but you need to create your roles in a functional fashion, that is, make your roles configurable through data.

  2. Write your roles so they do one thing only, but do it well. This improves re-usability of your roles, and eases maintenance down the road.

  3. When defining the data that will drive the behaviour of your roles, don't make over complicated data structures. ansible has quite a few iterators you can use and even provides the ability to write your own, but if you find yourself in need of something more complicated than with_subelements, it's time to re-think your data structures.

  4. Use tags. You can scope actions using a combination of groups and tags.

  5. Use registers to capture the result of your actions, and use them in subsequent actions to control flow using when statements. Don't over complicate conditions, though.

  6. set_facts and assert can help gathering data about the status of the target system.

  7. Idempotence. Keep your actions idempotent so you eliminate the need to build too much logic on top of your actions. Think in terms of target staus (desired state) rather than in terms of procedural language.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.