Why Ansible include_tasks Variables Are Not Defined in the Parent Play

Why Ansible include_tasks Variables Are Not Defined in the Parent Play You define a variable inside an include_tasks file. The task runs successfully. Then the very next task in your parent play fails with variable is undefined. What just happened? This is one of the most confusing Ansible behaviors, and it bites people repeatedly because it looks like a bug. It’s not β€” it’s a scoping decision β€” but understanding why it works this way helps you fix it fast. ...

April 15, 2026 Β· 5 min Β· 853 words Β· Rob Washington

Why Ansible register Variable Is Undefined in the Next Task

Why Ansible register Variable Is Undefined in the Next Task You registered a variable in one task, and the next task fails with "msg": "The task includes an option with an undefined variable". The variable is right there β€” you can see it in the task above. What’s going on? This is one of the most common Ansible debugging rabbit holes. There are four distinct causes, and they look identical until you know what to look for. ...

April 14, 2026 Β· 5 min Β· 968 words Β· Rob Washington

How to Troubleshoot Ansible Playbook Failures When Syncing Databases with PAM Integration

How to Troubleshoot Ansible Playbook Failures When Syncing Databases with PAM Integration Automating database synchronization in environments with Privileged Access Management (PAM) systems like CyberArk can be a powerful way to streamline operations. However, when things go wrong, Ansible playbook failures can be frustrating and time-consuming to debug. Common issues include credential retrieval errors, connection timeouts, permission problems, and data inconsistency. In this post, we’ll dive into practical steps to troubleshoot these failures, complete with code examples and best practices. This guide is based on real-world scenarios I’ve encountered while setting up PAM-integrated DB sync roles. ...

April 13, 2026 Β· 5 min Β· 877 words Β· Rob Washington

How to Query the ServiceNow Table API with Ansible

ServiceNow’s Table API is how you read and write records programmatically β€” incidents, change requests, service catalog items, CMDB entries. Here’s how to query it from Ansible using the uri module. Authentication ServiceNow uses basic auth for API calls. Store your credentials as variables, not hardcoded values: 1 2 3 4 # group_vars/all.yml or vault snow_instance: "company.service-now.com" snow_user: "svc_automation" snow_password: "{{ vault_snow_password }}" Test your connection first: 1 2 3 4 5 6 7 8 9 10 - name: Test ServiceNow connectivity ansible.builtin.uri: url: "https://{{ snow_instance }}/api/now/table/incident?sysparm_limit=1" method: GET user: "{{ snow_user }}" password: "{{ snow_password }}" force_basic_auth: true status_code: 200 validate_certs: true register: snow_test Basic Table Query The Table API endpoint is /api/now/table/{table_name}. Common tables: ...

April 10, 2026 Β· 5 min Β· 932 words Β· Rob Washington

CyberArk REST API Returns 401 Even with Valid Session Token (How to Fix)

You authenticate to CyberArk’s PVWA API, get a session token back with HTTP 200, then immediately call GET /PasswordVault/api/Accounts and get a 401 Unauthorized. The token looks valid. You confirmed it’s being passed in the request. The account has the right permissions. Here’s why it’s happening and how to fix it. The Problem: Wrong Authorization Header Format CyberArk’s PVWA API (v9.x and earlier) does not use the standard Bearer token format. Sending: ...

April 9, 2026 Β· 4 min Β· 802 words Β· Rob Washington

Ansible include_role Variables Not Available Inside the Role (How to Fix)

You set a variable with set_fact. You call include_role. Inside the role, the variable is undefined. You check the task order β€” it’s definitely set first. You add debug statements. The variable exists in the play but not inside the role. This is one of the most confusing variable scoping issues in Ansible. Here’s what’s happening and how to fix it. The Problem 1 2 3 4 5 6 7 8 9 - name: Set environment ansible.builtin.set_fact: MY_REGION: "us-east" - name: Run the role ansible.builtin.include_role: name: my_role vars: some_param: "value" Inside my_role/tasks/main.yml: ...

April 8, 2026 Β· 4 min Β· 772 words Β· Rob Washington

Why Ansible set_fact Persists Between Roles (And How to Reset It)

You set a variable with set_fact inside a role. It works perfectly. Then you run the same role again β€” either in a loop, or later in the same playbook β€” and it behaves differently. The variable has a value from the previous run that you didn’t expect. This is one of Ansible’s most common gotchas. Here’s exactly why it happens and how to fix it. Why set_fact Persists In Ansible, set_fact sets a variable at the host level for the duration of the play. It is not scoped to the role or task file that created it. Once set, it stays set until: ...

April 7, 2026 Β· 4 min Β· 820 words Β· Rob Washington

Ansible Automation Patterns: Beyond the Basics

Ansible’s learning curve is gentle until it isn’t. Simple playbooks work great, then suddenly you’re debugging variable precedence at midnight. Here are patterns that keep automation maintainable as it scales. Directory Structure That Scales Forget the flat playbook approach. Use roles from day one: a β”œ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œ β”‚ β”‚ β”‚ β”‚ β”œ β”‚ β”‚ β”‚ β”” n ─ ─ ─ ─ s ─ ─ ─ ─ i b i β”œ β”‚ β”‚ β”‚ β”‚ β”‚ β”” r β”œ β”œ β”œ β”” p β”œ β”œ β”” a l n ─ ─ o ─ ─ ─ ─ l ─ ─ ─ n e ─ ─ l ─ ─ ─ ─ a ─ ─ ─ s / e e y i n p β”œ β”” s β”” s c n p a b s w d b t r ─ ─ t ─ / o g o p o i e a l o o ─ ─ a ─ m i s p t b t e r d g m n t k e s a . y u h g β”œ β”œ β”” i o x g s . e b c / c o r ─ ─ ─ n n r y r a f t s o ─ ─ ─ g e m v s g i t u s l e e o s p a w d q r s n . _ l e a l s . y v l b t / . y m a . s a y m l r y e b m l s m r a l / l v s e e r s s . . y y m m l l Each role follows the standard structure: ...

March 13, 2026 Β· 7 min Β· 1347 words Β· Rob Washington

Ansible Patterns That Scale: From Ad-Hoc to Production

Ansible is deceptively simple. Write some YAML, run it, things happen. Then your playbooks grow, your team grows, and suddenly everything is a mess. Here’s how to write Ansible that scales. Project Structure a β”œ β”œ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œ β”‚ β”‚ β”‚ β”œ β”‚ β”‚ β”‚ β”” n ─ ─ ─ ─ ─ s ─ ─ ─ ─ ─ i b a i β”œ β”‚ β”‚ β”‚ β”‚ β”‚ β”” p β”œ β”œ β”” r β”œ β”œ β”” c β”” l n n ─ ─ l ─ ─ ─ o ─ ─ ─ o ─ e s v ─ ─ a ─ ─ ─ l ─ ─ ─ l ─ / i e y e l b n p β”œ β”” s β”œ β”” b s w d s c n p e r l t r ─ ─ t ─ ─ o i e a / o g o c e e o o ─ ─ a ─ ─ o t b t m i s t q . r d g k e s a m n t i u c i u h g β”œ β”œ β”” i h g s . e b o x g o i f e c o r ─ ─ ─ n o r y r a n r n r g s t s o ─ ─ ─ g s m v s e s e / i t u / t u l e e s / m o s p a w d s p r s q e n . _ l e a . _ s . l n y v l b t y v . y / t m a . s a m a y m s l r y e b l r m l . s m r a s l y / l v s / m e e l r s s . . y y m m l l Separate inventories per environment. Group vars by function. Roles for reusable logic. ...

March 12, 2026 Β· 9 min Β· 1795 words Β· Rob Washington

Ansible Patterns That Scale

Ansible is easy to start, hard to scale. Here’s how to structure playbooks that don’t become unmaintainable nightmares. Directory Structure Start organized, stay organized: a β”œ β”œ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œ β”‚ β”‚ β”‚ β”œ β”‚ β”‚ β”‚ β”” n ─ ─ ─ ─ ─ s ─ ─ ─ ─ ─ i b a i β”œ β”‚ β”‚ β”‚ β”‚ β”‚ β”” p β”œ β”œ β”” r β”œ β”œ β”” c l n n ─ ─ l ─ ─ ─ o ─ ─ ─ o e s v ─ ─ a ─ ─ ─ l ─ ─ ─ l / i e y e l b n p β”œ β”” s β”œ β”” b s w d s c n p e l t r ─ ─ t ─ ─ o i e a / o g o c e o o ─ ─ a ─ ─ o t b t m i s t . r d g k e s a m n t i c y u h g β”œ β”œ β”” i h g s . e b o x g o f / c o r ─ ─ ─ n o r y r a n r n g t s o ─ ─ ─ g s m v s e s i t u / t u l e e s / o s p a w d s p r s q n . _ l e a . _ s . l y v l b t y v . y / m a . s a m a y m l r y e b l r m l s m r a s l / l v s / e e r s s . . y y m m l l Inventory Patterns Static YAML Inventory 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # inventory/production/hosts.yml all: children: webservers: hosts: web1.example.com: web2.example.com: vars: http_port: 80 databases: hosts: db1.example.com: postgresql_port: 5432 db2.example.com: postgresql_port: 5433 Dynamic Inventory For cloud infrastructure, use dynamic inventory: ...

March 11, 2026 Β· 9 min Β· 1795 words Β· Rob Washington