Ansible Interview Questions

Aditya PatilAditya Patil
8 min read

Q What tasks did you recently did with the ansible ?

Here’s how I’d answer this in an interview setting, reflecting 4 years of experience:


Recently with Ansible, I worked on:

  1. Provisioning EC2 Instances (Ad-hoc + Playbooks)

    • Wrote playbooks to launch EC2 instances with required tags, security groups, and AMIs for QA testing.
  2. Installing and Configuring NGINX & Java App

    • Automated installation of NGINX and deployed a WAR file for a Spring Boot app with systemd setup.
  3. Patch Management

    • Used Ansible to apply critical security updates to dev and staging servers.
  4. Dynamic Inventory with AWS EC2 Plugin

    • Integrated dynamic inventory to manage EC2 instances by tags/regions.
  5. Vault Usage

    • Used ansible-vault to secure credentials like DB passwords and API tokens in playbooks.
  6. CI/CD Integration

    • Integrated Ansible playbooks in Jenkins pipeline to automate post-deployment steps like restarting services and config updates.

Q. What sort of automations you do with ansible recently that still you think was innovative ?

One automation I recently did with Ansible that I found innovative:

I automated blue/green deployment of a Java-based microservice using Ansible on EC2 instances.


🔧 What I Did:

  1. Used Tags in EC2:
    Tagged instances as blue and green to identify environments.

  2. Playbook Logic:
    Wrote a playbook that:

    • Detected the idle environment (green if blue is live).

    • Deployed the latest artifact there.

    • Ran health checks.

    • Swapped the ALB target group to point to the new environment.

  3. Rollback Strategy:
    If health check failed, it auto-rolled back to previous (live) environment.

  4. Slack Notification:
    Sent deployment status to Slack with job ID, commit hash, and deployment environment.


💡 Why It’s Innovative:

  • No downtime deployments using just Ansible and EC2 — without external deployment tools.

  • Made deployments safer, automated, and auditable with Slack logs.


Q. So you wrote playbooks or roles ?

Yes, I wrote both — playbooks and modular roles.


👇 In Real-Time Projects:

  • I wrote roles for reusable components like:

    • install_java

    • deploy_artifact

    • update_alb_target_group

    • health_check

    • rollback

    • notify_slack

  • Then used those roles inside a main playbook for the full deployment workflow.


🎯 Why Roles?

  • Reusability across environments (Dev, QA, Prod).

  • Easier to test and maintain.

  • Cleaner structure when team members contribute.


🧠 Example Playbook Structure:

- hosts: target_hosts
  roles:
    - install_java
    - deploy_artifact
    - health_check
    - update_alb_target_group
    - notify_slack

Q .Write a playbooks for all of the above ?

Sure! Here's a complete Ansible playbook that uses modular roles like:

  • install_java

  • deploy_artifact

  • health_check

  • update_alb_target_group

  • rollback

  • notify_slack


📁 Folder Structure (Best Practice)

site.yml
inventory/
  hosts.ini
roles/
  install_java/
  deploy_artifact/
  health_check/
  update_alb_target_group/
  rollback/
  notify_slack/

site.yml — Main Playbook


- name: Complete CI/CD Deployment Workflow
  hosts: app_servers
  become: true

  roles:
    - install_java
    - deploy_artifact
    - health_check
    - update_alb_target_group
    - notify_slack

🧩 Role: install_java/tasks/main.yml


- name: Install OpenJDK 17
  apt:
    name: openjdk-17-jdk
    state: present
    update_cache: yes

🧩 Role: deploy_artifact/tasks/main.yml


- name: Copy JAR to server
  copy:
    src: /path/to/your-app.jar
    dest: /opt/your-app.jar
    mode: '0755'

- name: Start application service
  systemd:
    name: your-app
    state: restarted
    enabled: yes

🧩 Role: health_check/tasks/main.yml


- name: Wait for App to respond on port 8080
  uri:
    url: http://localhost:8080/health
    status_code: 200
    timeout: 30
    validate_certs: no
  register: result
  retries: 5
  delay: 10
  until: result.status == 200

🧩 Role: update_alb_target_group/tasks/main.yml


- name: Register Instance to Target Group (AWS)
  community.aws.elb_target:
    state: present
    target_group_arn: "{{ target_group_arn }}"
    targets:
      - Id: "{{ ansible_default_ipv4.address }}"
        Port: 8080
  when: ansible_default_ipv4.address is defined

🧩 Role: notify_slack/tasks/main.yml


- name: Send Deployment Notification to Slack
  community.general.slack:
    token: "{{ slack_token }}"
    msg: "✅ Deployment of `your-app` to {{ inventory_hostname }} completed."
    channel: "#deployments"
    username: "ansible-bot"

🧩 Optional: rollback/tasks/main.yml


- name: Rollback to previous JAR version
  shell: |
    cp /opt/your-app-backup.jar /opt/your-app.jar
    systemctl restart your-app

Q. How would your inventory looks like ?

Here’s how your Ansible inventory file (hosts.ini) would typically look for this setup:


inventory/hosts.ini

[app_servers]
dev-app01 ansible_host=10.0.1.10 ansible_user=ubuntu
dev-app02 ansible_host=10.0.1.11 ansible_user=ubuntu

[app_servers:vars]
ansible_ssh_private_key_file=~/.ssh/devops-key.pem
ansible_python_interpreter=/usr/bin/python3
target_group_arn=arn:aws:elasticloadbalancing:ap-south-1:123456789012:targetgroup/dev-apps-tg/abcd1234efgh5678
slack_token=xoxb-1234567890-0987654321-abcdefghijklmnopqrst

🔍 Explanation

SectionDescription
[app_servers]Group of servers you're targeting (e.g. dev environment nodes).
ansible_hostPrivate or public IP/hostname of EC2 or VM.
ansible_userOS-level user (like ubuntu for Ubuntu EC2).
ansible_ssh_private_key_fileSSH key to connect to target servers.
ansible_python_interpreterEnsures Ansible uses correct Python version.
target_group_arnUsed in the ALB update step to register instances.
slack_tokenToken used by the Slack notification role.

Q. Why INI format and not yaml ?

ChatGPT said:

Great question 👇 (Answer in interview-style as per your request):


Why use .ini over .yaml for Ansible inventory?

By default, Ansible uses INI-style static inventory (hosts.ini) because it’s simple, easy to maintain, and supported out of the box. It's good for small to medium environments where hosts don’t change frequently.


When would I use YAML?

I’d prefer YAML inventory for:

  • Better readability in complex group hierarchies

  • Dynamic inventory scripts (combined with plugins like AWS EC2)

  • Consistency when everything else (like playbooks and vars) is in YAML


Follow-up (if asked):
Yes, starting from Ansible 2.4+, YAML-style inventory is supported using .yaml or .yml files, but it needs to be explicitly structured and not all features are as straightforward as in ini.

Q. So, don't you manage configuration for dev, QA, stage, and prod servers using Ansible? Because I haven't seen them in your INI file. Or do you prefer a different strategy?

Interview-style answer:

Yes, I do manage configurations across Dev, QA, Staging, and Prod environments using Ansible.

🔹 In our case, we follow a directory-based inventory strategy, not just a flat .ini file.


✅ Example Folder Structure:

inventories/
├── dev/
│   ├── hosts.ini
│   └── group_vars/
├── qa/
│   ├── hosts.ini
│   └── group_vars/
├── staging/
│   ├── hosts.ini
│   └── group_vars/
├── prod/
│   ├── hosts.ini
│   └── group_vars/

Each environment has its own hosts.ini and group_vars for environment-specific configurations.


🔄 Why not put all environments in one .ini?

To avoid risk of accidental cross-environment deployment, we separate inventories.
Also, our CI/CD pipeline triggers the right inventory based on environment passed as input.


🧠 Bonus Tip (if asked):

We also use ansible.cfg to dynamically point to the right inventory during runtime, like:

[defaults]
inventory = inventories/dev/hosts.ini

Q. So how would it look like the above structure and content in it and how you run any specific playbook on any env servers ?

Interview-style answer:
Here’s how our Ansible inventory directory structure and content looks like, and how we execute playbooks per environment.


📁 Directory Structure:

ansible/
├── playbooks/
│   ├── deploy_app.yml
│   ├── install_docker.yml
│   └── harden_os.yml
├── inventories/
│   ├── dev/
│   │   ├── hosts.ini
│   │   └── group_vars/
│   │       └── all.yml
│   ├── qa/
│   │   ├── hosts.ini
│   │   └── group_vars/
│   │       └── all.yml
│   ├── staging/
│   │   ├── hosts.ini
│   │   └── group_vars/
│   │       └── all.yml
│   └── prod/
│       ├── hosts.ini
│       └── group_vars/
│           └── all.yml
└── ansible.cfg

📄 Sample hosts.ini (for QA):

[web]
web-qa-01 ansible_host=10.0.1.11

[db]
db-qa-01 ansible_host=10.0.1.22

📄 Sample group_vars/all.yml:

app_port: 8080
env: qa
docker_version: "20.10"

🔧 ansible.cfg (partial):

[defaults]
inventory = inventories/dev/hosts.ini
remote_user = ec2-user
private_key_file = ~/.ssh/id_rsa

▶️ Run a playbook for QA environment:

ansible-playbook -i inventories/qa/hosts.ini playbooks/deploy_app.yml

💡 How this helps:

  • Clear separation of envs avoids cross-deployments

  • Each env has its own config via group_vars

  • Easy integration into CI/CD (pass -i dynamically)

Q. How you use roles here and why ?

Interview-style answer:

We use Ansible roles to modularize and reuse code across environments. Roles help keep the playbooks clean, maintainable, and scalable — especially when the same logic is used in Dev, QA, Stage, and Prod.


📁 Our Updated Directory Structure (with roles):

ansible/
├── playbooks/
│   ├── deploy_app.yml
│   └── install_docker.yml
├── roles/
│   ├── docker/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   ├── handlers/
│   │   │   └── main.yml
│   │   └── defaults/
│   │       └── main.yml
│   ├── app_deploy/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── templates/
│   │       └── nginx.conf.j2
├── inventories/
│   ├── dev/
│   ├── qa/
│   └── prod/
└── ansible.cfg

📄 Sample deploy_app.yml:

- name: Deploy Application
  hosts: web
  become: yes
  roles:
    - docker
    - app_deploy

🔁 Why we use roles:

PurposeRole Benefit
Code reusabilityAvoid repeating logic like Docker install
Environment overrideOverride role defaults with group_vars
Easy testingTest roles individually with Molecule
CI/CD friendlyIntegrates cleanly into Jenkins/GitHub Actions

▶️ How we run it for QA:

ansible-playbook -i inventories/qa/hosts.ini playbooks/deploy_app.yml

0
Subscribe to my newsletter

Read articles from Aditya Patil directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Aditya Patil
Aditya Patil

Hi, I'm Aditya — a Cloud & DevOps Engineer passionate about automating everything from CI/CD pipelines to multi-cloud infrastructure. I specialize in AWS, Kubernetes, Terraform, and GitOps tools like Argo CD. I’ve helped teams scale applications, cut cloud costs by 90%, and build disaster-ready infra. I love sharing real-world DevOps lessons, cloud cost optimization tips, and infrastructure design patterns. Let’s connect and simplify the cloud — one YAML file at a time ☁️⚙️