6 ms·
Interesting Uses of Ansible's ternary filter
- raziel2p 3y agoWhy would you use this instead of e.g. {{ "--quiet" if ansible_verbosity == 0 }} https://jinja.palletsprojects.com/en/3.1.x/templates/#if-expression https://jinja.palletsprojects.com/en/3.1.x/templates/#if-exp...
- switch007 3y agoI was wondering the same thing. I tested it and it works fine. It defaults to an empty string if there is no "else".
- zufallsheld 3y agoProbably because the author of this piece of code was not aware of it. :) Thanks, I updated the blog-post.
- cpburns2009 3y agoI'm genuinely surprised you can use if-else expressions in Jinja. Jinja uses such neutered expressions I would have looked for an equivalent ternary/iff filter.
- mdaniel 3y agoThey support for-if from python, too: https://jinja.palletsprojects.com/en/3.1.x/templates/#loop-filtering https://jinja.palletsprojects.com/en/3.1.x/templates/#loop-f... but I haven't tried the "recursive" keyword to know if ansible supports that. I say "ansible supports that" because they don't just drop jinja2 into ansible and call it a draw, they have a bunch of custom execution integrations: https://github.com/ansible/ansible/blob/v2.16.3/lib/ansible/template/__init__.py#L561 https://github.com/ansible/ansible/blob/v2.16.3/lib/ansible/...
- kunley 3y agoCool. Ansible is still going to be around for some time. Also reminds me again that yaml should have never been born. Look how unnatural this "language" is in this article's examples
- xienze 3y agoMost of that is the embedded templating/scripting system (the stuff between {{}}), not YAML itself.
- zufallsheld 3y agoWell, that's Jinja. And arguably not a bad tool, but not the best for the use-case of config-management.
- kunley 3y agoYeah, I just have this sentiment wishing that Ansible's author used own-crafted format. HashiCorp used their own and suddenly in this case no one says "yaml should be everywhere because it's everywhere already". In a similar mood, I wished Kubernetes was staying every from yaml. Even mentioned HCL would be better (although it's not perfect)
- kunley 3y agoYes but the task names and parameters try to mimic natural language, like assert: that:, so you're supposed to read it as a whole, and it quickly turns into an abomination, with one syntax (yaml) for the structure and another (jinja) for values and conditions
- avgcorrection 3y agoYeah. I don’t understand why we keep submitting ourselves to this way of working.
- linsomniac 3y agoIMHO, the issue is that Ansible uses YAML to do "programming language" sorts of things, which is why it feels so unnatural. I tried an experiment last year: What if Ansible had Python rather than YAML syntax. https://github.com/linsomniac/uplaybook?tab=readme-ov-file#simple-examples https://github.com/linsomniac/uplaybook?tab=readme-ov-file#s... The downside is that having full Python available makes it really easy to make your playbooks non-idempotent, which Ansible gate-keeps behind Ansible modules. Also someone raised a concern that full Python (rather than a more limited safe dialect like Starlark) would make it harder to trust third-party playbooks. But considering uPlaybook's use case (ansible-like system configuration) it feels like even with a restricted dialect it is going to have plenty of opportunity for nefarious purposes. I've put out uPlaybook for some limited review among my friends, and I've gotten some excitement about it. It doesn't have fleet management and remote running though, which is the big negative feedback I've gotten. I'm interested in thoughts on it though.
- kimbernator 3y agoI really wish Ansible would have chosen to use python instead of YAML (since that's what it ends up being anyways). Shoehorning actual programming logic into YAML files is just awful; Working with Ansible as a software engineer is without a doubt the worst work I've done in my professional career. Every otherwise simple logic structure in any programming language like loops, variable declaration, or conditional statements take 5x as much space and are very difficult to understand immediately. My first love in this space was Chef, and honestly it remains my favorite in config management because you can write things in it that look very non-programmy, but you're still just writing in pure ruby. Obviously Ansible has the advantage being agentless, but I just cannot stand how popular it is.
- SteveNuts 3y agoAnsible is a nice tradeoff to allow sysadmins with no programming experience to work with it, and someday hopefully graduate to something else. For that, I think it's a net-positive. But yes, trying to work with even mildly complex data structures in Ansible is a nightmare compared to raw Python.
- zufallsheld 3y agoAs a counter anecdote I can tell you that all of the ops-people I worked with, they gladly switched from Puppet and Chef to Ansible, specifically because it was less programming and more shell-like. Not that this is good or bad, but I think that's why Ansible took off with the traditional operations-teams.
- jauntywundrkind 3y agoMore shell like, and more normative. There's a given form & shape in Ansible; playbooks resemble each other. You don't get that with programming languages. People do all kinds of shit with programming languages. There's tons of good ways to tackle a problem. And exponentially many more bad ways to tackle a problem. Having a given repeated form makes interpreting & understanding Ansible far easier than the alternatives.
- syslog 3y ago
- pton_xd 3y agoAnsible is great as long as you keep Jinja use to a minimum. Basic variable substitution handles 90% of what you need. Ternary filter... doesn't qualify. Everything else should just be handled by a python script to orchestrate the playbooks.
- IncreasePosts 3y agoNever thought I'd see a blog post describing an if statement.
- zufallsheld 3y agoYou're welcome. :)
- Szpadel 3y agoI use it to conditionally add elements to array or dict in group_vars, real life example: aws_tags_pio: RoleImage: "pio" aws_tags_role_app_tpl: [ { Role: "app" }, "{{ (mageops_pio_worker_enable and not mageops_pio_worker_dedicated_asg) | ternary(aws_tags_pio, {}) }}" ] aws_tags_role_app: "{{ aws_tags_role_app_tpl | combine }}" https://github.com/mageops/ansible-infrastructure/blob/5dcc321c8d2a918afd43e2a50665ccbd1159a674/group_vars/all.yml#L83-L96 https://github.com/mageops/ansible-infrastructure/blob/5dcc3... for array you use flatten eg aws_security_group_persistant_rules_tpl: [ "{{ mageops_ssh_proxy_persistant | ternary(aws_security_group_persistant_rules_ssh_proxy, []) }}", "{{ mageops_tinyproxy_persistant_enabled | ternary(aws_security_group_persistent_rules_tinyproxy, []) }}" ] aws_security_group_persistant_rules: "{{ aws_security_group_persistant_rules_tpl | flatten }}" this pattern really helped to clean up conditionals that normally had to be done in tasks