Saturday, 8 August 2026

How to manage WSL and Ansible automation &Azure Devops part1


Question: How module work ansible.builtin.copy
Using ansible.builtin.copy with check_mode: true, diff: true, and register: copy_ensure performs a safe dry-run preview of a file transfer, captures the projected changes, and saves the detailed outcome into a registered variable without modifying the remote machine. 
How the Parameters Work Together
  • check_mode: true: Forces the specific task to run as a dry run. Ansible evaluates whether a file change is needed (comparing checksums or existence) but never writes or alters anything on the remote host. 
  • diff: true: Instructs Ansible to generate line-by-line before-and-after text comparisons if a difference is detected.
  • register: copy_ensure: Captures the module's return data (including changed, diff results, checksums, and metadata) into a variable named copy_ensure for use in subsequent tasks. 
Example Playbook Usage
yaml
- hosts: all
  gather_facts: false
  tasks:
    - name: Preview file copy changes safely
      ansible.builtin.copy:
        src: files/app.conf
        dest: /etc/app.conf
        owner: root
        group: root
        mode: '0644'
      check_mode: true
      diff: true
      register: copy_ensure

    - name: Show whether changes would happen
      ansible.builtin.debug:
        msg: "Would this file change? {{ copy_ensure.changed }}"

Question : How module ansible.builtin.assert work
The ansible.builtin.assert module verifies that given expressions are true before letting a playbook continue. 
Key Features
  • Guardrails: Stops playbook execution on target hosts if an expression evaluates to false.
  • Custom Messages: Supports fail_msg for custom error text and success_msg when all conditions pass.
  • Jinja2 Integration: Evaluates standard Jinja2 tests and conditional expressions. 
Basic Usage Example
yaml
- name: Validate required variables
  ansible.builtin.assert:
    that:
      - app_version is defined
      - replicas >= 1
    fail_msg: "Configuration requirements are not met."
    success_msg: "All checks passed successfully."
```

<FollowUp>
If you want, let me know:
* What **conditions or variables** you need to test
* Whether you want the playbook to **halt or continue** on failure

I can write a custom assertion snippet for your playbook.
</FollowUp>
Q1: How does Azure Repos support Git, and what is the alternative version control system it provides?
Answer: Azure Repos supports Git (Distributed Version Control) and TFVC (Team Foundation Version Control, which is Centralized). 
  • Git is preferred for modern DevOps because every developer has a full copy of the repository locally, allowing for offline work, fast branching, and seamless integration with Azure Pipelines for CI/CD. 
Q2: What are the differences between Git Merge and Git Rebase? When should you use which in Azure DevOps?
Answer: Both commands integrate changes from one branch into another, but they handle history differently: 
  • git merge: Combines the branches and creates a special "merge commit". It preserves the exact chronological history of how and when features were made. 
  • git rebase: Moves the entire feature branch so it begins at the tip of the target branch. This rewrites the project history to create a clean, linear sequence of commits. 
Featuregit mergegit rebase
HistoryNon-linear; preserves true history.Linear; rewrites commit history.
TraceabilityEasy to trace where a feature was merged.Harder to trace exactly when a merge occurred.
UsageBest for shared/public target branches (e.g., main).Best for local/personal feature branches before a PR.

2. Security & Strategy (Scenario-Based)
Q3: As a Technical Architect, how do you prevent developers from committing code directly to the main branch?
Answer: You must implement Branch Policies in Azure Repos. To secure the main branch, you navigate to Project Settings -> Repositories -> Policies and enforce the following rules: [1]
  1. Require a Pull Request (PR): Blocks direct pushes and forces code review.
  2. Minimum number of reviewers: Requires at least 1 or 2 approvals before merging.
  3. Check for linked work items: Ensures every code change is tied to a user story or task in Azure Boards.
  4. Build Validation: Automatically triggers an Azure Pipeline to compile the code and run tests before the PR can be merged. 
Q4: How do you handle a scenario where two developers push conflicting changes to the same file in Azure Repos?
Answer: This causes a Merge Conflict. 
  1. The developer attempting to merge will see a conflict notification in the Azure DevOps PR interface.
  2. Resolution: The developer must fetch the latest changes locally (git fetch or git pull), execute a local merge or rebase (git merge origin/main), identify the conflicting lines flagged by Git, and manually edit the file to keep the correct logic.
  3. Once resolved, they stage (git add), commit, and push the clean code back to update the PR. 

3. CI/CD Pipeline Automation
Q5: How do you automate an Azure Pipeline to trigger every time code is pushed to a Git branch?
Answer: You use CI Triggers within your pipeline's configuration. In a YAML-based pipeline, you explicitly define the target branches under the trigger block: 
yaml
trigger:
  branches:
    include:
      - main
      - release/*
Every time code is pushed to main or any branch starting with release/, Azure DevOps automatically queues a build pipeline. 
Q6: What is the difference between git fetch and git pull in the context of an Azure DevOps self-hosted agent?
Answer:
  • git fetch: Downloads the latest metadata, commits, and files from Azure Repos but does not alter your local working directory code.
  • git pull: Runs a git fetch first and then immediately executes a git merge to update your current local branch with the remote changes.
  • Agent Context: Azure DevOps build agents typically perform a clean checkout or a targeted fetch to capture the exact commit hash tied to the pipeline trigger, minimizing merge conflicts during automated jobs. 

4. Advanced Troubleshooting
Q7: How do you roll back a bad production deployment that was triggered via Git in Azure DevOps?
Answer: There are two main approaches depending on the strategy: 
  1. The Git Way (Safe history): Run git revert <commit_hash> locally. This creates a new commit that completely mirrors the inversion of the faulty changes. Push this to Azure Repos, which triggers the pipeline to deploy the stable configuration. 
  2. The Pipeline Way (Fast recovery): Go to Azure Pipelines Releases, locate the last known stable deployment run, and trigger a Redeploy of that specific build artifacts directly to production to buy time while debugging.


Q: How do you configure Git in WSL to use the Windows Git Credential Manager (GCM) for authenticating with Azure DevOps?
Answer:
By default, WSL runs a separate Linux environment and cannot automatically use Windows GUI prompts for authentication. To enable Git Credential Manager from Windows inside your WSL distribution: 
  1. Point your WSL global Git configuration to the Windows GCM executable:
    bash
    git config --global credential.helper "/mnt/c/Program\ Files/Git/mingw64/bin/git-credential-manager.exe"
    

  2. Enable the HTTP path setting required explicitly by Azure DevOps to correctly resolve organization and repository names:
    bash
    git config --global credential.https://dev.azure.com.useHttpPath true
    
Q: What essential Git commands do you run to clone and push code to an Azure Repos repository from a WSL terminal?
Answer:
After setting up authentication, use standard remote URL operations: 
  • Clone an Azure DevOps repository:
    bash
    git clone https://azure.com
    

  • Stage, commit, and push your changes:
    bash
    git add .
    git commit -m "feat: integrate wsl git workflow"
    git push origin main


Q1: How do you configure Git in WSL to use the Windows Git Credential Manager (GCM) for Azure DevOps?
Answer:
By default, Git installed inside WSL is isolated from Windows. To authenticate seamlessly with Azure DevOps over HTTPS using your Windows credentials, configure the global HTTP path property in WSL. 
  • Run this command inside your WSL terminal:
    bash
    git config --global credential.https://dev.azure.com.useHttpPath true
    

  • Ensure Git Credential Manager is set up on the Windows side so WSL can delegate authentication requests. 

Q2: What is the best practice for cloning an Azure DevOps Git repository inside a WSL file system, and why?
Answer:
You should clone repositories inside the native WSL Linux file system (e.g., ~/projects/) rather than the mounted Windows file system (/mnt/c/).
  • Reasoning: File I/O performance in WSL is significantly faster when working inside the native Linux VHD root. Cross-OS file system calls via /mnt/c/ slow down Git status checks, builds, and file locking operations.
  • Command Example:
    bash
    cd ~
    git clone https://azure.com
    
Q3: How do you troubleshoot line ending (CRLF vs LF) issues when collaborating on Azure DevOps across Windows hosts and WSL environments?
Answer:
Mismatched line endings cause unnecessary Git diff modifications. Configure Git's core.autocrlf setting differently depending on whether you operate strictly in WSL or share the repo.
  • Set native Linux behavior inside WSL:
    bash
    git config --global core.autocrilf input
    

  • This ensures that Windows-style CRLF are converted to LF upon commit, keeping your Azure Repos clean and standard for Linux-based CI/CD build agents. [1]

Q4: How do you connect WSL to Azure Repos using SSH instead of HTTPS?
Answer:
Using SSH avoids credential manager overhead inside Linux environments.
  • Generate an SSH key pair inside WSL:
    bash
    ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
    

  • Copy the public key content (~/.ssh/id_rsa.pub) and add it under your User Settings -> SSH public keys in Azure DevOps.
  • Test the connection from WSL:
    bash
    ssh -T git@://azure.com


Question : What is best practice ,do we need to create separate repos for each project

Best practice dictates creating separate repositories for each independent project or Ansible role rather than bundling everything into one massive repository.
This approach ensures clean automation pipelines, precise access controls, and reliable deployment workflows in Azure DevOps and Ansible AWX.
Why Separate Repositories are Best Practice
  • Granular AWX Syncing: AWX syncs at the repository level. Separate repos prevent AWX from pulling unrelated code every time a job runs.
  • Isolated CI/CD Pipelines: Azure DevOps pipelines trigger automatically on code changes. Separate repos ensure changes to Project A do not trigger testing for Project B.
  • Tight Security: You can restrict access to sensitive infrastructure code by managing permissions per repository.
  • Version Control: Separate repos allow you to tag and version individual roles or projects independently.

Recommended Architecture Overview
To balance separation with reusability, structure your environment like this:
  1. Ansible Role Repositories: One repository per reusable role (e.g., ansible-role-nginx, ansible-role-db).
  2. Playbook/Project Repositories: Separate repositories for specific business applications or environments that call those roles via a requirements.yml file.

Step-by-Step Example
Here is how to set up a separate project repository for a web application using Azure DevOps and Ansible AWX.
1. The Project Repository Structure (app-web-infra)
Create a dedicated Azure DevOps Git repository named app-web-infra.
text
app-web-infra/
├── collections/
│   └── requirements.yml   # Defines external dependencies
├── site.yml               # Main playbook
├── inventory/             # Production/Staging inventories
│   └── production.ini
└── azure-pipelines.yml    # CI/CD test cases
2. Define Dependencies (collections/requirements.yml)
Instead of copying role code into this repo, reference your separate, reusable role repositories.
yaml
---
roles:
  - name: geerlingguy.nginx
    version: 3.2.0
3. The Main Playbook (site.yml)
This maps your hosts to the imported roles.
yaml
---
- name: Configure Web Servers
  hosts: webservers
  become: true
  roles:
    - geerlingguy.nginx
Testing and CI/CD Cases
Use Azure DevOps Pipelines inside this repository to test your Ansible code before AWX runs it.
Automated Test Case (azure-pipelines.yml)
This pipeline runs automatically on every Pull Request to validate your syntax and code quality.
yaml
trigger:
  - main

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: UsePythonVersion@0
  inputs:
    versionSpec: '3.x'

- script: |
    pip install ansible ansible-lint
  displayName: 'Install Testing Tools'

- script: |
    ansible-lint site.yml
  displayName: 'Run Test Case: Linting Check'

- script: |
    ansible-playbook --syntax-check site.yml
  displayName: 'Run Test Case: Syntax Check'
Linking to Ansible AWX
Once your separate repository passes the Azure DevOps test cases and merges into the main branch, you pull it into AWX:
  1. Create Credentials: Add your Azure DevOps personal access token (PAT) into AWX under Credentials.
  2. Create a Project:
    • Go to Projects > Add in AWX.
    • Select Git as the source control type.
    • Paste your specific Azure DevOps repository URL (app-web-infra).
    • Enable Update Revision on Launch so AWX always pulls the newest tested code.
  3. Create a Job Template: Link your AWX Project to your site.yml playbook and target inventory.
or
One Repo vs. Multi-Repo Strategy
The best practice for Azure DevOps and Ansible AWX is to use a single, monorepo-style repository for your Ansible configuration, rather than separate repositories for every small project.
Why a Unified Repository Wins
  • Shared Code: Centralizes common roles, custom modules, and plugins.
  • Easy Syncing: AWX only needs to track one main repository project.
  • Version Control: Keeps your entire infrastructure state in one source of truth.
When to Separate Repositories
  • Strict Security: Different teams must not see each other's code.
  • Independent Lifecycles: A specific application has a highly specialized deployment workflow.

Directory Architecture Example
Here is the ideal production-ready folder structure for your unified Ansible repository:
text
ansible-infrastructure/
├── .azure-pipelines/          # Azure DevOps CI/CD pipeline definitions
│   └── ansible-validate.yml
├── collections/               # Requirements for external collections
│   └── requirements.yml
├── inventories/               # Inventory files per environment
│   ├── development/
│   │   ├── hosts
│   │   └── group_vars/
│   └── production/
│       ├── hosts
│       └── group_vars/
├── playbooks/                 # Actionable playbooks targeted by AWX
│   ├── deploy_webserver.yml
│   └── configure_db.yml
├── roles/                     # Custom, reusable business logic
│   └── webserver/
│       ├── tasks/
│       │   └── main.yml
│       └── templates/
└── tests/                     # Test cases and Molecule configurations
    └── integration/
Use code with caution.

Testing Framework
Testing Ansible code requires syntax validation and execution testing.
1. Syntax and Linting (Static Analysis)
Use ansible-lint to catch syntax errors and non-standard practices.
yaml
# .azure-pipelines/ansible-validate.yml
trigger:
  - main

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: UsePythonVersion@0
  inputs:
    versionSpec: '3.x'

- script: |
    pip install ansible ansible-lint
    ansible-lint playbooks/*.yml
  displayName: 'Run Ansible Lint'
2. Local Integration Testing (Molecule)
Molecule tests your roles inside temporary Docker containers.
yaml
# tests/molecule_test.yml snippet
dependency:
  name: galaxy
driver:
  name: docker
platforms:
  - name: ubuntu22
    image: docker.io/pycontribs/ubuntu:latest
provisioner:
  name: ansible
verifier:
  name: ansible
VS Code Sync Guide
Follow these steps to develop locally in VS Code and push to Azure DevOps, which automatically syncs to AWX.
Step 1: Install Extensions
  • Install the Ansible extension by Red Hat.
  • Install the Azure Repos extension.
Step 2: Clone and Edit
  1. Open the command palette (Ctrl+Shift+P).
  2. Select Git: Clone.
  3. Paste your Azure DevOps repo URL: https://azure.com
  4. Open the workspace and write your code.
Step 3: Push to Git
bash
git add .
git commit -m "feat: add webserver role"
git push origin main
Step 4: Automate AWX Update
  1. Log into Ansible AWX.
  2. Go to Projects -> Your Project.
  3. Set SCM Type to Git.
  4. Paste the Azure DevOps URL and add your Azure personal access token (PAT) credentials.
  5. Check Update Revision on Launch. AWX will now automatically pull fresh code every time a job runs.

Interview Questions & Answers
Q1: Why choose a monorepo over separate repos for Ansible in an enterprise setup?
Answer: A monorepo prevents "code drift" and makes code reuse easier. It centralizes variables, custom roles, and linting rules. It also minimizes AWX configuration overhead because you only manage one SCM project sync instead of dozens.
Q2: How do you handle sensitive data/passwords in this repository?
Answer: Never store plain text secrets in Git. Use Ansible Vault to encrypt sensitive variables within the repository. Alternatively, look up secrets dynamically at runtime by integrating AWX with a credential manager like Azure Key Vault or HashiCorp Vault.
Q3: How do you ensure broken Ansible code doesn't execute in production via AWX?
Answer: Implement a strict Git GitFlow process. Developers commit to feature branches. An Azure DevOps pipeline runs ansible-lint and Molecule tests on every Pull Request. Code can only merge to main after all tests pass. AWX is configured to only read from the protected main branch.

or

The best practice for managing Ansible AWX code in Azure DevOps is to use a single, monorepo approach for common roles paired with individual repositories for distinct project playbooks.
Repository Structure Best Practice
Creating separate repositories for absolutely every project causes massive overhead. Instead, use a hybrid structure.
  • The Shared Role Repo: Store reusable roles (e.g., standard OS hardening, IIS setup) in one repository.
  • The Project Repos: Create separate repositories only for unique application deployments or distinct business units.
  • Why?: AWX Project Sync pulls from a single Git repository. Keeping playbooks separate prevents Team A from accidentally running or breaking Team B's automation.

Folder Example (The Multi-Project / Single Repo Approach)
If you manage a single department, structure your Azure Repo like this to keep AWX syncing simple:
text
ansible-infrastructure-repo/
├── .azure-pipelines/
│   └── pr-validation.yml      # CI pipeline for testing
├── roles/
│   ├── common_security/       # Shared across all projects
│   └── web_server/
├── project_alpha/             # Distinct AWX Project Folder
│   ├── site.yml               # Main playbook
│   └── group_vars/
└── project_beta/              # Distinct AWX Project Folder
    ├── deploy.yml
    └── group_vars/
In AWX, you create Project Alpha and Project Beta, both pointing to the same Azure Repo URL, but you change the execution pathways to target the specific folders.

Automated Test Cases (CI/CD)
Every time code is pushed to Azure DevOps, run automated tests using ansible-lint and Molecule before AWX pulls the updates.
Azure DevOps Pipeline Example (pr-validation.yml)
yaml
trigger:
  - main

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: UsePythonVersion@0
  inputs:
    versionSpec: '3.x'

- script: |
    pip install ansible ansible-lint molecule[docker]
  displayName: 'Install Testing Framework'

- script: |
    ansible-lint project_alpha/site.yml
  displayName: 'Lint Check'

- script: |
    cd roles/web_server && molecule test
  displayName: 'Run Molecule Integration Tests'
How to Sync with VS Code
To write code locally and sync it seamlessly with Azure DevOps and AWX, follow these steps:
  1. Clone the Azure Repo: Copy the Git URL from Azure DevOps. Open VS Code, press Ctrl+Shift+P, type Git: Clone, and paste the URL.
  2. Install Extensions: Install the Ansible extension (by Red Hat) and the Azure Repos extension.
  3. Local Development: Edit your playbooks. Use the built-in VS Code terminal to run local tests.
  4. Push to Azure: Use the Source Control tab (Ctrl+Shift+G) to commit and push changes to Azure DevOps.
  5. Trigger AWX: Configure your AWX Project with Update Revision on Launch. When you launch a template, AWX automatically pulls the fresh code you just pushed from VS Code.

Top Interview Questions & Answers
Q1: Why not create a separate Git repo for every single Ansible playbook?
  • Answer: It creates administrative chaos. Managing permissions, SSH keys, and CI/CD pipelines for 50 different repositories is inefficient. A hybrid approach (shared roles repo + distinct project repos) balances isolation with maintainability.
Q2: How does AWX know when code has changed in Azure DevOps?
  • Answer: You can configure a Webhook in Azure DevOps to notify AWX on a git push. Alternatively, enable the Update Revision on Launch setting in the AWX Project configuration so it pulls fresh code before every run.
Q3: How do you handle sensitive data (passwords) in this setup?
  • Answer: Never store plaintext secrets in Azure DevOps or VS Code. Use Ansible Vault to encrypt variables within the repository, or ideally, look up secrets dynamically at runtime using AWX credential linking with Azure Key Vault.
Q1: What is Azure Pipelines?
Answer: Azure Pipelines is a cloud service that allows you to automatically build, test, and deploy code. It provides Continuous Integration (CI) and Continuous Delivery (CD) capabilities for any language, platform, or cloud provider. 
Q2: What is the difference between Microsoft-hosted and Self-hosted agents?
Answer:
  • Microsoft-hosted agents: Maintenance and upgrades are taken care of by Microsoft. A fresh virtual machine is given for each pipeline run and discarded afterward. 
  • Self-hosted agents: Machines that you provision, configure, and manage independently. They give you deeper control over dependent software, offer caching capabilities for faster builds, and can run inside isolated private networks. 
Q3: What is YAML in Azure Pipelines, and why is it preferred over Classic Pipelines?
Answer: YAML is a human-readable configuration language used to define pipelines as code. It is preferred over the visual "Classic" editor because: 
  • It supports Pipeline as Code, meaning your build steps are version-controlled alongside your application code.
  • It makes tracking pipeline history, changes, and code reviews seamless via Pull Requests. 
Q4: What is a Service Connection in Azure DevOps?
Answer: A Service Connection is a secure mechanism that allows Azure Pipelines to connect to external systems and resources without exposing raw credentials. It is used to connect to your Azure Subscription, GitHub repositories, Docker registries, or Kubernetes clusters. 

 Advanced-Level Questions
Q5: Explain the structure of an Azure DevOps YAML pipeline. What are Stages, Jobs, and Steps?
Answer: A YAML pipeline follows a hierarchical structure: 
  • Stage: The highest organizing level (e.g., Build, Test, Deploy to QA, Deploy to Prod).
  • Job: A collection of steps that run on a single execution agent. Multiple jobs within a single stage can run concurrently.
  • Step: The smallest execution block, which runs sequentially inside a job. It can be a simple script block or a pre-configured Task (e.g., NodeTool@0). 
Q6: What are the differences between Build Artifacts and Pipeline Artifacts?
Answer: Both store files generated during a build, but they handle storage and performance differently: 
  • Pipeline Artifacts: The modern standard. They leverage deduplication features to compress data, significantly lowering transfer times and improving performance.
  • Build Artifacts: The legacy format. They lack optimization and upload speeds are slower. [
Q7: How do you implement Environment Gates and Approvals in Azure Pipelines?
Answer:
  • In Azure DevOps, you can define Environments (e.g., Production) under the Pipelines menu.
  • Within the environment settings, you can configure Approvals and Checks.
  • The pipeline will pause before executing a deployment stage targeting that environment until specified users manually approve it or until automated health checks (like an Azure Monitor alert check) clear it. 
Q8: How can you share variables across different stages in a Multi-Stage pipeline?
Answer: You can share variables using Variable Groups linked to the pipeline, or map task output parameters dynamically using the following syntax in an execution step: 
yaml
echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]myValue"
In subsequent stages, you reference it using dependencies: $[ stageDependencies.<Stage_Name>.<Job_Name>.outputs['<Task_Name>.myOutputVar'] ]. 

 Scenario & Troubleshooting Questions
Q9: Your deployment pipeline fails midway through execution. How do you troubleshoot?
Answer: I follow a structured checklist to identify and remediate pipeline failures:
  1. Analyze logs: Check the failed pipeline stage logs to pinpoint the exact step or task that triggered the error.
  2. Review variables & secrets: Ensure that target environment variables or database connection strings inside the Variable Group haven't expired or gone missing.
  3. Verify Service Connections: Check if the service connection permissions or underlying service principal credentials have expired.
  4. Agent Health: Ensure that the agent pool has available agents matching the requested demands.
  5. Mitigation: If the failure disrupts a critical environment, I trigger a roll back to the last stable release while debugging. 
Q10: How do you secure sensitive credentials or API keys inside an Azure Pipeline?
Answer:
  • Never hardcode secrets in azure-pipelines.yml.
  • Use Secret Variables inside Azure DevOps variable groups, which masks values in logging output.
  • For enterprise compliance, integrate Azure Key Vault. You can query Key Vault secrets dynamically at runtime inside the pipeline using the AzureKeyVault@2 task to keep credentials securely isolated. 

Question : what is the main branch and feature branches In Azure DevOps (Azure Repos), 

In Azure DevOps (Azure Repos), the main branch and feature branches are the two core elements of a modern, clean Git workflow. 
The fundamental rule is: Main represents your deployable, production-ready code, while feature branches isolate active development so you do not break the main build. 

The Main Branch: Your Source of Truth
The main branch (formerly master) is the default, permanent baseline of your application. 
  • State: Always stable, compiling, and passing tests.
  • Lifecycle: Permanent; it is never deleted.
  • Access: Highly restricted. Developers should never push code directly to main.
  • Automation: Typically bound to Continuous Integration (CI) and Deployment pipelines to deploy code straight to testing or production environments upon update. 

Feature Branches: Where Work Happens
A feature branch (also called a topic branch) is a temporary copy of the main branch used to develop a single task, feature, or bug fix in isolation. 
  • State: Can be unstable or incomplete during active development.
  • Lifecycle: Short-lived; created for a specific task and deleted immediately after merging.
  • Naming Convention: Grouped into folders using feature/your-feature-name (e.g., feature/user-login) to maintain repository structure.
  • Automation: Can trigger lightweight CI pipelines to run automated tests before the code is merged. 

Connecting the Two: The Azure DevOps Workflow
Azure DevOps provides built-in tools to manage the interaction between these branches seamlessly: 
1. Branch Policies (Protecting Main)
To keep your main branch clean, you configure Branch Policies in Azure DevOps. These policies force developers working in feature branches to meet strict quality checks before their code is accepted. 
  • Pull Requests (PRs): Requires team reviews and approvals to merge a feature into main.
  • Build Validation: Requires the feature branch to build successfully in a temporary pipeline before merging.
  • Work Item Linking: Enforces linking the feature branch to an active Azure Board task for complete traceability. 
2. The Development Lifecycle
 [main] -----------> (Known Good State) --------------------------> [Merged & Deployed]
   \                                                                     ^
    \---> [feature/new-login] ---> (Commits & PR Validation) -----------/
  1. Create: A developer creates a feature/ branch directly from an Azure Boards work item or locally in an IDE.
  2. Commit: The developer writes code, test cases, and pushes commits to the feature branch.
  3. Pull Request: Once completed, they submit a Pull Request targeting the main branch.
  4. Merge: Once reviews pass and build validation succeeds, Azure DevOps merges the feature branch into main and deletes the feature branch to keep the repo clean. 

Question: WHAT IS survey popup IN AWX

In Ansible AWX (and Red Hat Ansible Automation Controller), a survey popup is a dynamic user-interface form that appears when a user launches a Job Template or Workflow Template. It prompts the user for specific inputs—such as a target hostname, an IP address, or a deployment environment—and injects those inputs directly into the Ansible playbook as extra variables (extra_vars). 
How to Create a Survey Popup
To configure a survey popup in the AWX user interface, follow these steps: 
  1. Navigate to Templates: Open your AWX dashboard, click Templates in the left menu, and select your Job Template. 
  2. Access the Survey Tab: Click on the Survey tab at the top of the template settings. 
  3. Add Questions: Click the Add button to create a new prompt. Fill out the following fields for each question:
    • Question Text: What the user sees in the popup (e.g., "Which environment are you deploying to?").
    • Answer Variable: The exact variable name used inside your playbook (e.g., target_env).
    • Answer Type: Choose from Text, TextArea, Password (masked), Integer, Floating Point, or Multiple Choice. 
  4. Save and Enable: Click Save to store the question. Make sure to toggle the survey switch to Enabled. 
When a user clicks the Launch button on that template, the survey popup will block the job execution until the required inputs are filled out. 
Essential Requirements for the Popup to Appear
If the popup fails to appear when launching a job, verify the following configuration requirements:
  • Survey Toggle Enabled: Ensure the main survey switch is toggled to On inside the survey tab. 
  • Prompt on Launch Enabled: In the main Details tab of your Job Template, verify that the Prompt on Launch checkbox next to Variables is checked. If this is disabled, AWX will bypass user interaction and default to using the hardcoded template variables.
  • Job Type Restrictions: Surveys are only compatible with Run or Check job types; they cannot be utilized for Scan or Playbook Directory tasks. 
Common Limitations
  • No Conditional Logic (Native): You cannot natively build dependent "child" survey popups where a second question appears based on the answer to a first question. All enabled survey questions load simultaneously inside the popup. 
  • Overwriting Default Variables: If an optional survey field is left blank during launch, it passes an empty string ("") to the playbook. This empty string will completely overwrite any default values defined under the template's extra_vars section. Always define a default value inside the survey configuration itself to mitigate this behavior.

  • Q: Why does high ping (>30ms) severely impact Ansible performance compared to shell scripts?
    • A: Ansible opens a new SSH connection, performs key exchanges, and spins up a Python interpreter on the remote target for every single task by default. High latency multiplies this handshake overhead per task, making playbooks run extremely slowly. 
  • Q: How do you fix high connection latency in Ansible without changing the underlying physical network?
    • A: Enable SSH pipelining (reduces file transfers) and turn on SSH multiplexing (ControlMaster and ControlPersist) in ansible.cfg to reuse a single active SSH connection for multiple tasks. 
  • Q: On an ExaCC environment, what network layers should you check if InfiniBand/RoCE latency spikes?
    • A: Verify subnet manager status, check for local interface ring buffer drops (ethtool -S), and inspect switch-level congestion or faulty optical/copper transceivers.
  • Q: Why is a high ping time (>30ms) critical for Ansible automation on ExaCC?
    • A: Ansible opens a new SSH connection (or multiplexed session) for every task/node unless optimized. High latency multiplies this delay per task, causing slow playbooks, hanging states, or connection timeouts (Connection reset by peer). 
  • Q: How do you optimize Ansible for high-latency environments like ExaCC?
    • A: Enable SSH pipelining (pipelining = True in ansible.cfg) to reduce the number of SSH operations, turn on ControlPersist to reuse active SSH connections, and increase the timeout parameter in ansible.cfg. 
  • Q: What Linux tool helps determine if packet loss or queuing is causing the >30ms delay?
    • A: mtr (My Traceroute), which combines ping and traceroute to continuously display real-time transit loss and latency metrics for every router hop along the path to the ExaCC node. 

Question : How to troubleshoot if A ping time over 30 milliseconds on Exadata Cloud@Customer (ExaCC)


A ping time over 30 milliseconds on Exadata Cloud@Customer (ExaCC) will slow down Ansible playbooks because SSH connections and command handshakes take longer for each task. Higher latency adds up quickly across many tasks or servers, causing your automation to run much slower than normal.
Impacts on Ansible
  • Slow SSH Handshakes: Ansible opens a new SSH connection or multiplexed session for tasks, which drags when latency is high.
  • Higher Timeout Risks: Long delays can trigger connection timeout errors if tasks wait too long for a response.
  • Delayed Fact Gathering: The setup module takes extra time to run because it collects a large amount of system data over the slow link. 
How to Fix It
  • Turn on ControlPersist: Keep SSH connections open longer in your ansible.cfg file so you do not reconnect for every single task.
  • Use Pipelining: Enable pipelining = True in ansible.cfg to run modules without copying separate python files over SSH each time.
  • Check the Network Route: Verify why the control node and ExaCC environment have high latency by checking local switches, routing paths, or VPN hops.
  • Increase Timeouts: Raise the timeout value in your configuration if operations drop out prematurely. 

Step-by-Step Validation Process
  1. Verify Baseline ICMP Network Latency: Measure the raw round-trip time (RTT) between the Ansible control machine and the ExaCC client network interface.
  2. Execute an Ansible Connection Check: Test if the execution delay is network-bound or overhead from the Ansible/Python environment setup on ExaCC. 
  3. Analyze Network Hop Routing: Locate where delays are occurring (e.g., inside the corporate backbone, firewalls, or the ExaCC OCI-managed bridge). 
  4. Tune Ansible SSH Parameters: Apply optimizations to keep connections alive and mitigate latency penalties. 

Linux Troubleshooting Commands
If your test cases fail, run these native Linux commands from the Ansible Control Node to isolate the root cause.
1. Pinpoint Hop Delays & Routing Latency
ExaCC utilizes dedicated subnets for client connectivity. Use traceroute or mtr to inspect every hop along the network path. 
bash
# Display RTT for each hop to the ExaCC node
traceroute <ExaCC_Client_IP>

# Run a real-time, continuous traceroute analysis for 30 seconds
mtr --report --report-cycles 30 <ExaCC_Client_IP>
Look for sharp latency spikes at specific firewall or gateway IPs.
The command mtr --report --report-cycles 30 <ExaCC_Client_IP> runs a network diagnostic tool. It sends 30 ping packets to the target Exadata Cloud@Customer (ExaCC) client IP. It then prints a text report showing packet loss and response times for each network hop, and exits.]
Understanding the Command
  • mtr: Combines ping and traceroute into one tool.
  • --report: Runs the test in non-interactive mode and outputs the results.
  • --report-cycles 30: Sets the number of test packets sent to 30 (taking 30 seconds).
  • <ExaCC_Client_IP>: The destination IP address of your ExaCC client node. 
Reading the Output Columns
  • Loss%: Shows packet drop rate per hop.
  • Snt: Number of packets sent (30 in this case).
  • Last / Avg / Best / Wrst: Round-trip times in milliseconds.
  • StDev: Consistency of the response times. 
2. High-Frequency ICMP Ping Profile
Standard pings run once per second. Flood or rapid pings help discover intermittent packet drops or switch buffering issues on the ExaCC infrastructure. 
bash
# Send 50 packets at a rapid 0.1-second interval to calculate true min/avg/max metrics
ping -c 50 -i 0.1 <ExaCC_Client_IP>
3. Trace SSH Authentication & Protocol Handshake Delays 
If raw ICMP ping is under 30ms but Ansible remains slow, the issue is likely SSH authentication delays (e.g., DNS timeouts on ExaCC or GSSAPI configuration issues).
bash
# Run a verbose SSH session to check where the connection stalls
ssh -vvv -i /path/to/key.key oracle@<ExaCC_Client_IP> "hostname"
Watch out for pauses during debug1: Next authentication method: gssapi-with-mic or reverse DNS lookups.
4. Monitor TCP Packet Drops via Socket Statistics 
bash
# Review connection timings and dropped packets
ss -i -t -a 'dst <ExaCC_Client_IP>'
Linux Troubleshooting Commands
  • Check real-time packet loss and latency:
    ping -c 20 <exacc-ip>
  • Trace network hops and find where latency spikes:
    traceroute <exacc-ip>
  • Check active SSH connection performance and socket status:
    ss -t -a | grep ssh
  • Inspect network interface errors or dropped packets on the host:
    ip -s link show
  • Monitor real-time network interface traffic/load:
       iftop -i <interface_name> or sar -n DEV 1 5
     
Troubleshooting Steps & Remediations
  • Fix SSH Reverse DNS Lookups: If the ssh -vvv command hangs during authentication, connect to the ExaCC VM cluster and ensure /etc/ssh/sshd_config contains UseDNS no. Restart the service afterward (systemctl restart sshd).
  • Deactivate GSSAPI Authentication: Turn off GSSAPI to prevent timeouts if your corporate environment does not use Kerberos authentication for ExaCC. Update the configuration on your control node or managed nodes:
    ini
    GSSAPIAuthentication no
    

  • Mitigate Latency via ansible.cfg Optimization: When physical distance limits latency reduction, modify the control node's ansible.cfg file to dramatically decrease execution times: 
ini
[defaults]
# Increase default timeouts to prevent connection drops on congested routes
timeout = 60

[ssh_connection]
# Enable Pipelining to execute multiple tasks without reopening SSH channels
pipelining = True

# Configure ControlPersist to reuse an active SSH socket across tasks
ssh_args = -o ControlMaster=auto -o ControlPersist=1800s -o ConnectTimeout=60

Test Cases and Examples
  • Test Case 1: Validate ICMP Latency Threshold
    • Goal: Confirm if raw packet round-trip time (RTT) exceeds 30ms.
    • Example command: ping -c 10 -i 0.2 <exacc_host_ip>
    • Expected Result: Average RTT should ideally be < 5ms on an internal ExaCC InfiniBand/RoCE or client network. If > 30ms, log the anomaly. 
  • Test Case 2: Validate Ansible Connection Latency via Playbook
    • Goal: Test actual connection overhead using the built-in Ansible ping module.
    • Example Playbook (latency_test.yml):
      yaml
      - hosts: exacc_cluster
        gather_facts: false
        tasks:
          - name: Test basic connection speed
            ansible.builtin.ping:
      
      Execution: Run with timing flags: time ansible-playbook latency_test.yml 

Step-by-Step Troubleshooting
  1. Verify Physical/Virtual Path (ExaCC Network Segregation)
    • Ensure traffic isn't routing out to a corporate WAN instead of staying on the local client/backup VLAN designated for ExaCC.
  2. Check Name Resolution and DNS Lag
    • Slow reverse DNS lookups can artificially inflate connection setup times before the actual ping or SSH handshake begins.
  3. Inspect MTU Size Mismatch
    • Jumbo frames (MTU 9000) configured on switches but misconfigured on host interfaces cause packet fragmentation and latency spikes.

Linux Commands for Troubleshooting
  • Trace the network path and hop delays:
    bash
    traceroute -I <exacc_host_ip>
    

  • Check interface MTU and packet drop statistics:
    bash
    ip -s link show
    

  • Measure raw TCP handshake latency (Port 22):
    bash
    nc -zv <exacc_host_ip> 22
    

  • Analyze DNS lookup speed:
    bash
    dig <exacc_host_name>
To run a DNS lookup for an Oracle Exadata Database Service / Exadata Cloud at Customer (ExaCC) hostname, use the dig command with your fully qualified domain name (FQDN). For instance: dig +short ://domain.com. Remember that unlike the host command, dig bypasses local search domains unless you add the +search flag.
Common ExaCC DNS Lookups
  • Node IP Lookup: Check the A record for a specific database compute node.
  • SCAN VIP Lookup: Query the Single Client Access Name (SCAN) listener addresses.
  • Short vs FQDN: Provide the full domain name to prevent lookup failures.

or

When executing Ansible Automation on Oracle Exadata Cloud@Customer (ExaCC), network latency under 30 milliseconds (ms) is standard for efficient cross-node execution. If the network round-trip time (RTT) spikes above 30ms, Ansible's standard connection framework faces heavy performance degradation, SSH session timeouts, and unstable playbook runs. 
Here is a comprehensive framework covering automated verification, architectural workarounds, and step-by-step troubleshooting. 

Step-by-Step Implementation Flow
To handle, evaluate, and mitigate high-latency (>30ms) events dynamically within your workflows, follow this implementation path:
1. Setup the Host Inventory 
Ensure your inventory maps the exact ExaCC infrastructure layers (such as the VM Cluster DomU nodes).
ini
# inventory.ini
[exacc_cluster]
exacc-node01-vm1 ansible_host=192.168.10.11
exacc-node02-vm2 ansible_host=192.168.10.12
2. Create the Latency Enforcement Playbook
This playbook uses an explicit ICMP/Network ping (via the local shell) to calculate physical latency. It terminates gracefully or acts conditionally if the response time violates your 30ms service-level objective (SLO). 
yaml
---
- name: Evaluate network latency and decide whether to continue automation
  hosts: all
  gather_facts: false
  vars:
    latency_threshold_ms: 30.0
    default_rtt_ms: 9999.0

  tasks:
    - name: Measure ICMP latency to target host
      delegate_to: localhost
      ansible.builtin.shell: |
        set +e
        rtt=$(ping -c 5 "{{ ansible_host }}" 2>/dev/null | tail -1 | awk -F '/' '{print $5}')

        if [ -n "$rtt" ] && [ "$rtt" != "" ]; then
          echo "$rtt"
        else
          echo "{{ default_rtt_ms }}"
        fi
      register: ping_output
      changed_when: false
      failed_when: false

    - name: Parse RTT and store as float
      ansible.builtin.set_fact:
        current_rtt_ms: "{{ (ping_output.stdout | trim | float) if (ping_output.stdout | trim) else default_rtt_ms }}"

    - name: Show current latency status
      ansible.builtin.debug:
        msg: "Current RTT is {{ current_rtt_ms }} ms (threshold: {{ latency_threshold_ms }} ms)"

    - name: Warn when latency exceeds the allowed threshold
      ansible.builtin.debug:
        msg: "WARNING: High latency detected ({{ current_rtt_ms }} ms > {{ latency_threshold_ms }} ms). Review the network path before continuing."
      when: current_rtt_ms | float > latency_threshold_ms

    - name: Continue with standard automation when latency is acceptable
      ansible.builtin.debug:
        msg: "Latency is within the threshold. Proceeding with normal automation."
      when: current_rtt_ms | float <= latency_threshold_ms
Test Cases
Test Case 1: Ideal Infrastructure State (Normal Execution)
  • Pre-conditions: Local Control Node to ExaCC DomU network link is healthy (< 5ms RTT).
  • Execution: Run the playbook. 
  • Expected Result:
    • The parsing step records a latency below 30.0.
    • The system bypasses the warning block and successfully triggers downstream automation blocks. 
Test Case 2: High Latency Event (> 30ms)
  • Pre-conditions: Artificial or organic link degradation introduced via structural routing hops or network throttling tool (tc qdisc add dev eth0 root netem delay 35ms).
  • Execution: Run the playbook. 
  • Expected Result:
    • current_rtt_ms logs higher than 30.0.
    • The conditional when: current_rtt_ms | float > latency_threshold_ms triggers.
    • The execution captures a warning log, or breaks execution safely to prevent partial/flaky configurations. 

Mitigating Latency at the Ansible Layer
If your ExaCC environment must route across data centers where a sub-30ms RTT is physically impossible, optimize your ansible.cfg to dramatically reduce the overhead of high-latency connections: 
ini
# /etc/ansible/ansible.cfg
[defaults]
# Increase default connection time buffers
timeout = 60
# Parallel forks processing to optimize data pipes
forks = 20

[ssh_connection]
# Enable SSH Pipelining to group tasks into fewer operations over the network
pipelining = True

# Control persistent sockets to minimize connection handshake cycles over 30ms hops
ssh_args = -o ControlMaster=auto -o ControlPersist=1800s -o ConnectTimeout=60 -o ServerAliveInterval=30
retries = 3
Comprehensive Troubleshooting Steps
If your Ansible runs hang, fail with SSH timeouts, or show a ping RTT > 30ms on ExaCC, execute the following diagnostic workflow:
[Isolate Layer] ---> 1. Network (ICMP) ---> 2. SSH Handshake ---> 3. OS Resources
Step 1: Diagnose the Physical Network Layer 
  • Run a traceroute from the Ansible control node to identify where the high-latency hop lives:
    bash
    traceroute <ExaCC_DomU_IP>
    

  • Verify if the traffic is correctly leveraging the Oracle Infrastructure Private/Backup Network rather than pulling data through a throttled public or client-side VPN connection. 
Step 2: Trace Connection Overheads
  • Run Ansible's connection engine in extreme verbose mode (-vvvv) to discover where stalls occur:
    bash
    ansible exacc_cluster -m ansible.builtin.ping -vvvv
    

  • Look at the timestamps for the raw SSH commands. If it hangs at the GSSAPI authentication phase, disable it on your control node or inside ansible.cfg via -o GSSAPIAuthentication=no to immediately shave off unnecessary network round trips. 
Step 3: Check ExaCC DomU Operating System Resource Saturation
  • High CPU utilization on the ExaCC OVM/KVM guest nodes can artificially delay SSH packet processing times, mimicking network latency.
  • Log into the node and inspect the process monitor:
    bash
    top -b -n 1 | head -n 20
    

  • Ensure huge pages, Oracle Grid Infrastructure daemons, or backup utilities are not completely saturating the CPU scheduling queues.
Step 4: Validate MTU Discrepancies
  • Large packets sent during file transfers or heavy fact-gathering tasks can drop if maximum transmission unit (MTU) sizes differ along the route.
  • Test with large packets to verify fragmentation limits:
    bash
    ping -M do -s 1472 <ExaCC_DomU_IP>
    


Question AWX with Azure Devops

AWX is the open-source upstream project for Red Hat Ansible Automation Platform. It provides a web interface, REST API, and task engine to manage Ansible playbooks, inventories, and credentials across IT environments.
Core Features of AWX
  • Web UI and Dashboard: View job statuses, host metrics, and system health at a glance.
  • Role-Based Access Control (RBAC): Assign strict user and team permissions for security.
  • Centralized Logging: Audit who ran what playbook and when it finished.
  • Credential Management: Store secrets, SSH keys, and cloud tokens safely without exposing plain text.
  • Inventories: Group and manage target machines statically or dynamically.
AWX Use Cases in Azure DevOps
  • Automated Infrastructure Provisioning: Trigger AWX jobs from an Azure DevOps pipeline to spin up Azure virtual machines or networks using Ansible.
  • Continuous Configuration Management: Apply security baselines and software updates to target servers whenever application code updates in Azure Repos. 
  • Multi-Cloud Deployments: Orchestrate application deployments across Azure and on-premise data centers from a single Azure DevOps release pipeline. 
  • Post-Deployment Validation: Run automated health checks and tests via Ansible after an Azure DevOps deployment finishes. 

Question : Please share AWX Term


Ansible AWX is a free, open-source web application that provides a user interface, REST API, and task engine for Ansible. It serves as the upstream project for Red Hat's commercial Ansible Automation Platform controller. 
Core AWX Terms
  • Project: A collection of Ansible playbooks and related files stored in a source control system like Git.
  • Inventory: A list of hosts (servers or network devices) that your playbooks target and manage.
  • Job Template: A saved, reusable setup that combines a specific playbook, an inventory, and required credentials to run a task.
  • Job: An instance of a job template running against your hosts.
  • Credential: Securely stored authentication data (such as SSH keys, cloud tokens, or vault passwords) used to access managed nodes.
  • Workflow Template: A sequence of multiple job templates and project syncs linked together to execute as one complete unit.
  • RBAC (Role-Based Access Control): A security feature that gives specific users or teams granular permissions to run or view jobs. 

Introduction to DevOps - GeeksforGeeks

How does Azure DevOps trigger an Ansible AWX job?
  • REST API: Use AWX API endpoint /api/v2/job_templates/{id}/launch/ via curl or a PowerShell script task in Azure DevOps.
  • Authentication: Pass a Bearer Token or basic auth credentials stored securely in Azure DevOps Service Connections. 
Why use AWX instead of running Ansible directly from Azure Pipelines agent?
  • Centralized Credentials: AWX securely stores SSH keys and passwords; pipelines do not expose secrets.
  • RBAC & Auditing: AWX provides granular access control and logs for all automation runs.
  • Scalability: Offloads heavy parallel execution to AWX execution nodes rather than overloading the CI/CD build agents. 
How do you handle parameter passing from Azure DevOps to AWX?
  • Extra Vars: Send dynamic parameters like build numbers or environment names via the extra_vars JSON payload in the AWX API launch request.
How is job completion tracked back in Azure DevOps?
  • Polling: The pipeline runs a secondary script to poll the AWX job status endpoint (/api/v2/jobs/{id}/) until state changes to successful or failed.



Question: Git command

Common Git Commit Flags
Here are the most common flags used directly after git commit -:
  • -m "message": Commits staged changes with an inline description.
  • -am "message": Stages all tracked, modified files and commits them at once.
  • --amend: Modifies your very last commit instead of creating a new one.
  • -v: Shows the unified diff of your changes inside the commit message editor.
  • -p: Steps through changes interactively to let you commit specific chunks (hunks


Direct Examples
bash
# Standard commit with a message
git commit -m "Fix login page authentication bug"

# Stage and commit tracked files together
git commit -am "Update API endpoint routes"

# Modify the message of your last unpushed commit
git commit --amend -m "New and corrected message"


Question : How to install Oracle database


Oracle Database does not natively support Ubuntu Linux. 
Because Oracle only officially certifies Red Hat Enterprise Linux (RHEL) and Oracle Linux, installing it bare-metal on Ubuntu is a highly unstable "hack" prone to errors. The best practice for running Oracle Database on an Ubuntu Azure VM is to deploy it inside a Docker Container, utilizing Oracle's officially supported container images. 

Step 1: Configure Azure Network Security Group (NSG)
Before logging into your VM, you must open the standard Oracle communication port.
  1. Navigate to the Azure Portal and find your Ubuntu Virtual Machine.
  2. Under the left-hand menu, click Networking.
  3. Click Add inbound port rule.
  4. Set the Destination port ranges to 1521 and Protocol to TCP.
  5. Click Add to save. 

Step 2: Install Docker on the Ubuntu Azure VM
SSH into your Ubuntu VM and install the Docker engine. 
bash
# Update local package index
sudo apt-get update

# Install Docker
sudo apt-get install -y docker.io

# Start and enable the Docker service
sudo systemctl start docker
sudo systemctl enable docker
Step 3: Pull and Run the Oracle Database Container
You can pull an official pre-built Oracle Database image. For a lightweight and free option ideal for development, use the Oracle Database Express Edition (XE) or 23ai Free image. 
Run the following command to download the image and launch the container automatically: []
bash
sudo docker run -d \
  --name oracle23ai \
  -p 1521:1521 \
  -e ORACLE_PASSWORD=YourSecurePassword123 \
  ://oracle.com
Note: If you specifically require Enterprise Edition 19c, you can build or pull an image like banglamon/oracle193db:19.3.0-ee and map your variables accordingly. []
To monitor the logs and ensure the database initialization finishes successfully: []
bash
sudo docker logs -f oracle23ai
Look for the text DATABASE IS READY TO USE before proceeding. []

Step 4: Access SQL*Plus inside the Container
Once initialization completes, log directly into the running container to execute database commands. 
bash
# Access the container's bash environment
sudo docker exec -it oracle23ai bash

# Log into SQL*Plus as the System Administrator
sqlplus sys/YourSecurePassword123 as sysdba
Step 5: Test External Connection
You can now connect to your new Oracle Database from your local workstation using tools like Oracle SQL Developer or Toad. Use the following parameter configurations: 
  • Connection Type: Basic
  • Host: <Your_Azure_VM_Public_IP>
  • Port: 1521
  • Service Name / SID: FREE (or FREEPDB1 for the pluggable database. For 19c images, this is usually ORCL or SE).
  • Username: SYSTEM
  • Password: YourSecurePassword123 

A playbook is failing on a specific task. Describe your systematic approach to debugging the issue. What command-line flags and Ansible modules would you use?

To debug a failing Ansible task :

  1. Increase verbosity using -vvv to get detailed output.
  2. Isolate the issue with --limit and --start-at-task.
  3. Use debug and register to inspect variables and task output.
  4. Run in check mode with --check --diff to preview changes.

 How Can You Programmatically Access A Variable Name Within An Ansible Playbook?

To access a variable name programmatically within an Ansible playbook, setup the `set_fact` module with a task like:

- name: Extract variable name
   set_fact:
    var_name: "{{ my_variable | dict2items | selectattr('value', 'eq', my_value) | map(attribute='key') | first }}"

This task sets `var_name` based on the variable name corresponding to the specified value (`my_value`). Try on adjusting `my_variable` and `my_value` accordingly.

You have a playbook that takes an unacceptably long time to run against 500 hosts. What are the first three things you would investigate or tune to improve its performance?

To improve the performance of a slow playbook running against 500 hosts, I’d first investigate three key areas:

  1. Enable SSH Pipelining – Reduces overhead by reusing SSH connections, speeding up task execution.
  2. Increase Forks – Boosts parallelism by allowing Ansible to manage more hosts simultaneously (default is 5).
  3. Configure Fact Caching – Stores host facts to avoid re-gathering them on every run, saving time across large inventories.
Additional optimizations include using async tasks for long operations and the free strategy plugin to let hosts proceed independently.

Explain Ansible Inventory And Discuss Its Various Types.

Ansible Inventory is a collection of hosts (managed nodes) that Ansible targets during automation. It defines which machines to configure and how they are grouped.

Types of Inventory

  • Static Inventory
    Defined manually in an INI or YAML file.
  • Hosts and groups are explicitly listed.
  • Simple and ideal for small or stable environments.

Dynamic Inventory

  • Generated automatically using scripts or plugins.
  • Pulls host data from external sources like AWS, Azure, GCP, or CMDBs.
  • Ideal for cloud-native or large-scale environments with frequent changes.

 Can You Automate Password Input In An Ansible Playbook Using Encrypted Files?

Yes, you can automate password input in Ansible playbooks using encrypted files through Ansible Vault. Vault allows you to securely store sensitive data like passwords, API keys, or private credentials in encrypted YAML files. These files can be referenced in your playbooks just like regular variables, ensuring secure automation without exposing secrets in plain text. You can create a Vault file using:

ansible-vault create secrets.yml

Then include it in your playbook with vars_files, and unlock it during execution using --ask-vault-pass or --vault-password-file.

 Can You Automate Password Input In An Ansible Playbook Using Encrypted Files?

Yes, you can automate password input in Ansible playbooks using encrypted files through Ansible Vault. Vault allows you to securely store sensitive data like passwords, API keys, or private credentials in encrypted YAML files. These files can be referenced in your playbooks just like regular variables, ensuring secure automation without exposing secrets in plain text. You can create a Vault file using:

ansible-vault create secrets.yml

Then include it in your playbook with vars_files, and unlock it during execution using --ask-vault-pass or --vault-password-file.

 What Command Will You Use To Run An Ansible Playbook With a Specific Inventory File?

To run an Ansible playbook with a specific inventory file, use the ansible-playbook command with the -i option to specify the inventory.
Example:

ansible-playbook -i /path/to/inventory/file myplaybook.yml

Replace /path/to/inventory/file with the actual path to your inventory file and myplaybook.yml with your playbook name. The -i flag tells Ansible which inventory to use during execution.

Not all Ansible modules are inherently idempotent. How can a playbook author enforce idempotency when using modules like shell or command?

Modules like shell and command execute arbitrary commands without checking system state, risking unintended changes. To enforce idempotency, authors can use parameters like creates or removes to conditionally run tasks. More robustly, they can register command output and use changed when or when clauses to control execution based on actual system conditions. This discipline ensures predictable and resilient automation


How do Ansible roles promote modularity and collaboration in automation workflows? Describe the purpose of each key file in a standard role directory.

Ansible roles organize automation into reusable, modular units, making playbooks cleaner and easier to share.

  • tasks/main.yml: contains the core tasks the role performs.
  • handlers/main.yml: defines actions triggered by task notifications.
  • defaults/main.yml: sets low-priority, user-overridable variables.
  • vars/main.yml: holds high-priority internal variables.
  • meta/main.yml: includes role metadata and dependencies.

You’re tasked with deploying a new version of a multi-tier web application (web frontends, APIs, database) behind a load balancer. How would you design an Ansible-based rolling update strategy to ensure zero downtime? Describe the key plays, tasks, and features you'd use.

To ensure zero downtime during a rolling update of a multi-tier web application, Design a master orchestration playbook that sequences the deployment across tiers starting with database migrations, followed by API services, and finally the web frontends.

For the web and API tiers, Iuse the serial keyword (e.g., serial: 1 or serial: 25%) to update servers in controlled batches. Before updating each server, use the ansible.builtin.uri module to call the load balancer’s API and drain or disable the server from the active pool. Once isolated, run the application deployment role.

After deployment, Iperform health checks using either ansible.builtin.uri to hit a health endpoint or ansible.builtin.wait_for to confirm the service port is listening. If the server passes, re-enable it in the load balancer and proceed to the next one.

To handle failures gracefully, wrap the critical steps in a block with a rescue section. If anything fails like a health check. I could trigger a rollback, alert an operator, or re-add the server to the load balancer in its previous state to maintain capacity.

This strategy ensures safe, staged updates with minimal disruption to live traffic.


Question : What is azure pipline
An Azure Pipeline is a cloud-based service within the Azure DevOps ecosystem that automatically builds, tests, and deploys your code using continuous integration (CI) and continuous delivery (CD). It works across any programming language, platform, or cloud target. 
Core Structural Hierarchy
  • Trigger: The event that tells the pipeline to run, such as pushing code to a branch or making a pull request.
  • Stage: A major boundary in the pipeline (e.g., "Build Code", "Run QA Tests", "Deploy to Production").
  • Job: A series of steps that runs on a single execution agent. Jobs can run sequentially or in parallel.
  • Step/Task: The smallest building block, such as a script, command, or pre-built plugin that compiles code or copies files.
  • Agent: The computing engine (hosted by Microsoft or managed by you) that executes the jobs.
  • Artifact: The physical output generated by a build step (like a .zip or .war file) used for deployment. [
Standard Configuration Methods
You can configure pipelines using two primary models: 
  1. YAML Pipelines (Recommended): Your pipeline is defined entirely as code inside a file named azure-pipelines.yml at the root of your repository. This allows you to track pipeline changes using version control. 
  2. Classic Editor: A visual, drag-and-drop user interface inside the Azure DevOps web portal. This option is generally used for simpler legacy systems or quick graphical proofs-of-concept. 
Basic Starter YAML Template
This simple configuration executes every time code updates on the main branch, running on a Microsoft-hosted Ubuntu environment: 
yaml
trigger:
- main

pool:
  vmImage: ubuntu-latest

stages:
- stage: BuildStage
  jobs:
  - job: BuildJob
    steps:
    - script: echo "Compiling application source code..."
      displayName: 'Compile Code'

- stage: DeployStage
  dependsOn: BuildStage
  jobs:
  - job: DeployJob
    steps:
    - script: echo "Deploying artifact to hosting environment..."
      displayName: 'Execute Deployment'
Steps to Create a Pipeline
  1. Log into your organization via the Azure DevOps Portal.
  2. Select your target project, choose Pipelines from the left panel, and click New Pipeline.
  3. Point the wizard to your code repository (e.g., Azure Repos, GitHub, or Bitbucket).
  4. Select a preset configuration template matching your technology stack (such as Node.js, .NET Core, or Maven).
  5. Review the generated YAML schema, click Save and Run, and monitor the real-time build logs. [

Question : how to use ansible.builtin.import_task

ansible.builtin.import_tasks is a static reuse module in Ansible. It injects a list of external tasks into a playbook at parse time (before execution begins). Conditional statements or tags applied to an import_tasks line copy down to every individual child task inside the imported file. 
Practical Example
Main Playbook (playbook.yml):
yaml
- hosts: all
  tasks:
    - name: Import web server configuration tasks
      ansible.builtin.import_tasks: web_tasks.yml
      tags: ['web']
Task File (web_tasks.yml):
yaml
- name: Install Nginx
  ansible.builtin.apt:
    name: nginx
    state: present

- name: Start Nginx service
  ansible.builtin.service:
    name: nginx
    state: started
Test Case
Verify parse-time loading and correct execution using ansible-playbook with a syntax check and dry run: 
bash
# Check playbook syntax and verify static file resolution
ansible-playbook --syntax-check playbook.yml

# Run a dry-run check
ansible-playbook playbook.yml --check
Expected Behavior: Ansible reads web_tasks.yml during the initial parsing phase. If web_tasks.yml is missing, the command fails immediately even before connecting to any target hosts. 
Common Troubleshooting Steps
  • Missing File Errors (ERROR! the file/tasks file could not be found):
    • Cause: import_tasks evaluates paths at parse time. The target file must physically exist on the controller.
    • Fix: Ensure the relative path points accurately to the file location from the playbook root. 
  • Using Loops (with_* or loop) Fails:
    • Cause: Loops are not supported directly on import_tasks.
    • Fix: Switch the module to ansible.builtin.include_tasks if you require runtime iteration loops. 
  • Dynamic Variable in File Path Fails:
    • Cause: Host-level inventory variables are not resolved during the parse phase for file names.
    • Fix: Pass variables via --extra-vars or use include_tasks instead for dynamic filenames. 


Question : How to used failed when 

The failed_when conditional in Ansible overrides the default failure criteria of a task, allowing you to define exactly what constitutes a failure based on command output, return codes, or variable values. 
Basic Syntax and Example
By default, Ansible marks a task as "failed" if the return code (rc) is not 0. failed_when lets you change this logic. 
Here is an example that triggers a failure if the word "Error" appears in the command output, even if the return code is 0. 
yaml
- name: Run custom disk check script
  ansible.builtin.command: /usr/local/bin/check_disk.sh
  register: disk_result
  failed_when: "'Error' in disk_result.stdout"
Complete Test Case Playbook
This standalone playbook demonstrates multiple conditions. It fails only if the return code is greater than 2 and the output contains the word critical.
yaml
---
- name: Test Case for failed_when
  hosts: localhost
  gather_facts: false
  tasks:

    - name: Simulate a tool execution
      ansible.builtin.shell: |
        echo "Status: critical failure detected"
        exit 3
      register: tool_output
      ignore_errors: true # Prevents the playbook from stopping completely so we can see the result

    - name: Evaluate custom failure conditions
      ansible.builtin.debug:
        msg: "The previous task met custom failure criteria!"
      failed_when: 
        - tool_output.rc > 2
        - "'critical' in tool_output.stdout"
Common Troubleshooting Scenarios
1. Variable is Undefined
  • Issue: The task crashes with an "error": "The task includes an option with an undefined variable" message.
  • Cause: You tried to inspect stdout or rc on a task that skipped or did not register output.
  • Fix: Add a check to ensure the variable exists first.
    yaml
    failed_when: disk_result.stdout is defined and "Error" in disk_result.stdout
    

2. Logical Operator Confusion (and vs or)
  • Issue: The task fails when it should pass, or passes when it should fail.
  • Cause: Listing conditions as a YAML array implies an AND operation.
  • Fix: For an OR operation, write the condition explicitly on a single line.
    yaml
    # Fails if rc is 2 OR if stdout contains 'Failed'
    failed_when: tool_output.rc == 2 or "Failed" in tool_output.stdout
    

3. Overriding changed Status
  • Issue: The task reports failed but still shows a status of changed.
  • Fix: Combine failed_when with changed_when to cleanly manage the task lifecycle state. 


Question : what is purpose of ignore_unreachable: true 

ignore_unreachable: true is an Ansible keyword that prevents a playbook from failing entirely when a managed host cannot be reached via SSH or WinRM
By default, an unreachable host is immediately dropped from the play, and any remaining tasks for that host are skipped. Enabling this keyword allows Ansible to log the failure but continue executing the playbook for other tasks or handlers, which is highly useful for multi-tier deployments or dynamic environments. 

Basic Example
You can apply ignore_unreachable at the play level or individual task level. 
yaml
---
- name: Demonstrate ignore_unreachable at task level
  hosts: all
  gather_facts: no
  tasks:
    - name: Attempt to connect to a potentially offline server
      ansible.builtin.ping:
      ignore_unreachable: true
      register: ping_result

    - name: This task runs even if the host was unreachable above
      ansible.builtin.debug:
        msg: "The ping task completed. Unreachable status: {{ ping_result.unreachable | default(false) }}"
Step-by-Step Test Case
To safely test this behavior without breaking production systems, follow this localized test scenario.
1. Setup an Inventory 
Create an inventory file named hosts.ini containing one real local host and one fake, unreachable IP address. 
ini
[servers]
localhost ansible_connection=local
fake_server ansible_host=192.0.2.1 ansible_connection=ssh
2. Create the Test Playbook 
Save the following playbook as test_unreachable.yml. It uses ignore_unreachable: true to prevent the fake_server failure from halting the execution setup.
yaml
---
- name: Test Case for ignore_unreachable
  hosts: servers
  gather_facts: no
  tasks:
    - name: Execute a command on all hosts
      ansible.builtin.command: echo "Checking connectivity"
      ignore_unreachable: true
      register: task_output

    - name: Inspect the output variables
      ansible.builtin.debug:
        msg: "Host {{ inventory_hostname }} finished with unreachable status: {{ task_output.unreachable | default(false) }}"
3. Run and Analyze Results
Execute the playbook with the inventory file: 
bash
ansible-playbook -i hosts.ini test_unreachable.yml
  • Expected CLI Output:
    Ansible will display a red UNREACHABLE! warning message for fake_server, but instead of halting, it will smoothly proceed to the "Inspect the output variables" task.
     
  • Variable State:
    For fake_server, the task_output variable will contain "unreachable": true and "failed": true. You can use this registered dictionary downstream with when: task_output.unreachable to conditionally trigger fallback tasks.

Troubleshooting Common Gotchas
  • Subsequent Tasks Fail: If a host is truly offline, setting ignore_unreachable: true on Task A means Task B will still attempt to run on that offline host. Task B will then fail with an "Unreachable" error unless you also add the keyword to Task B or add a conditional check like when: task_output.unreachable is not defined. 
  • Play-level vs Task-level: If you set ignore_unreachable: true at the play level, it applies to gather_facts. If the host is unreachable during fact gathering, Ansible ignores it and proceeds into the tasks section with an empty fact cache for that host. 
  • Handlers are Skipped: If a host becomes unreachable during a task that notified a handler, that handler will not run for the unreachable host, even if ignore_unreachable is enabled. 
  • Differentiating from ignore_errors: Do not confuse these two settings. ignore_errors: true handles cases where the host is reachable, but a command returns a non-zero exit code. ignore_errors will not catch SSH connection timeouts or connection refused errors; only ignore_unreachable can catch those. 




Question : when block details

An Ansible block groups multiple tasks together to apply shared configurations or handle errors. It functions like a try-catch-finally block in traditional programming. [
Syntax and Example
Blocks allow you to apply directives like become or when to multiple tasks at once. 
yaml
---
- name: Managed web server configuration
  hosts: webservers
  tasks:
    - name: Setup Web Server Configuration
      block:
        - name: Install Apache
          ansible.builtin.apt:
            name: apache2
            state: present

        - name: Start Apache Service
          ansible.builtin.systemd:
            name: apache2
            state: started
            enabled: true
      become: true
      when: ansible_os_family == "Debian"
Error Handling (Test Case)
Combine block, rescue, and always to handle task failures gracefully. 
  • block: Runs the main tasks.
  • rescue: Runs only if a task in the block fails.
  • always: Runs no matter what happens in the previous sections. 
yaml
---
- name: Test error handling with blocks
  hosts: localhost
  gather_facts: false
  tasks:
    - name: Attempt dangerous file operation
      block:
        - name: Read a non-existent file
          ansible.builtin.command: cat /tmp/missing_file.txt
          register: file_output

      rescue:
        - name: Handle the failure
          ansible.builtin.debug:
            msg: "The file was missing! Creating a backup file now..."

        - name: Create fallback file
          ansible.builtin.file:
            path: /tmp/missing_file.txt
            state: touch

      always:
        - name: Final cleanup task
          ansible.builtin.debug:
            msg: "This task always runs, regardless of success or failure."
Troubleshooting Common Issues
  • Invalid Directives: You cannot apply loops (loop, with_items) to a block. Apply the loop to individual tasks inside the block instead.
  • Variable Scope: Variables registered inside a failed block task may be undefined in the rescue section. Use block_failed_task or check for variable existence using is defined before referencing them.
  • Playbook Failure: If a task in the rescue section fails, the entire playbook run will fail immediately. Keep rescue tasks simple and safe.
  • Task Status: If the rescue section successfully resolves the issue, the overall play status will show as ok (or changed), not failed. [






Question : How to manage Azure Repos
Azure Repos is a dedicated set of version control tools within the Microsoft Azure DevOps suite that allows development teams to manage, track, and collaborate on their codebase. It integrates seamlessly with Azure Pipelines for automated continuous integration and continuous delivery (CI/CD). 
Types of Version Control Supported
  • Git: The modern standard, offering distributed version control where every developer has a full copy of the repository locally.
  • Team Foundation Version Control (TFVC): A legacy, centralized version control system where history is maintained exclusively on a server. 
Core Features of Azure Repos
  • Unlimited Private Repos: Host unlimited repositories for small or enterprise-scale projects.
  • Pull Requests (PRs): Facilitate asynchronous code reviews, inline discussions, and feedback loops before merging code.
  • Branch Policies: Protect critical branches (like main) by enforcing rules such as required reviewers, successful build validation, or mandatory work item linking.
  • Semantic Code Search: Locate specific classes, functions, or text across all repositories using advanced query syntax.
  • IDE & Tooling Flexibility: Connect natively using Visual Studio, VS Code, Git CLI, or any standard Git client. [
Standard Git Workflow
  1. Create/Initialize: Set up a new repository in your project via the web portal or command line.
  2. Clone: Copy the remote repository locally using a secure HTTPS or SSH connection string.
  3. Branch: Create a feature branch to write your code changes safely away from production code.
  4. Commit & Push: Commit your local changes and push the branch back to Azure Repos.
  5. Merge: Open a pull request, complete code reviews, pass build pipelines, and merge changes. [

or

Azure DevOps Repos for Ansible AWX
Azure DevOps (AzDO) Repos serves as the single source of truth for your infrastructure as code (IaC). It securely stores your Ansible playbooks, inventories, and variables, tracking every change through Git version control. 
When integrated with Ansible AWX (the upstream open-source version of Red Hat Ansible Automation Platform), AzDO Repos acts as the remote project repository. AWX automatically pulls the latest playbooks from your AzDO Git repository to execute consistent, repeatable deployments. 

Workflow Architecture
[ Developer ] ---> ( Git Push ) ---> [ Azure DevOps Repo ]
                                              |
                                     ( Webhook Trigger )
                                              v
[ Managed Infrastructure ] <--- [ Ansible AWX Project Sync & Job Execution ]
  1. Code Commit: A developer updates an Ansible playbook or inventory file locally and pushes it to Azure Repos.
  2. Automation Trigger: Azure DevOps fires a service hook (webhook) to AWX, or AWX polls the repository on a schedule.
  3. Project Sync: AWX pulls the latest code from the specific Git branch.
  4. Job Execution: AWX runs the playbook against target environments using secure credentials stored natively within AWX. 

Step-by-Step Implementation Example
1. Repository Structure (Azure Repos)
Create a clean directory layout in your Azure DevOps Git repository: 
text
├── ansible.cfg
├── environments/
│   ├── dev/
│   │   └── hosts.yml
│   └── prod/
│       └── hosts.yml
├── playbooks/
│   └── deploy_web.yml
└── roles/
    └── webserver/
        └── tasks/
            └── main.yml
2. Sample Playbook (playbooks/deploy_web.yml)
yaml
---
- name: Configure Corporate Web Servers
  hosts: webservers
  become: yes
  tasks:
    - name: Ensure Apache is at the latest version
      ansible.builtin.package:
        name: httpd
        state: latest

    - name: Start and enable Apache service
      ansible.builtin.service:
        name: httpd
        state: started
        enabled: yes
3. Connecting Azure Repos to Ansible AWX
  • Generate Git Credentials: In Azure DevOps, go to User Settings > Personal Access Tokens (PAT). Create a token with Code (Read) permissions. 
  • Configure AWX Credentials:
    • Log into AWX and navigate to Credentials > Add.
    • Set Credential Type to Source Control.
    • Input your Azure DevOps username and paste the PAT into the Password/Token field. 
  • Create AWX Project:
    • Navigate to Projects > Add.
    • Set Source Control Type to Git.
    • Paste your Azure Repos HTTPS clone URL into the Source Control URL field.
    • Select the Source Control credential you created above.
    • Enable Update Revision on Launch to ensure AWX always pulls the newest code before running. 

Testing and Validation Case
To ensure your code updates do not break your production environments, implement an automated CI/CD validation pipeline inside Azure DevOps using an azure-pipelines.yml file. [
Automated Test Case (azure-pipelines.yml) 
This configuration tests your Ansible playbooks for syntax errors and style violations automatically on every pull request.
yaml
trigger:
  - main

pr:
  - main

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: UsePythonVersion@0
  inputs:
    versionSpec: '3.10'
  displayName: 'Set up Python'

- script: |
    python -m pip install --upgrade pip
    pip install ansible ansible-lint
  displayName: 'Install Ansible and Linting Tools'

- script: |
    ansible-lint playbooks/deploy_web.yml
  displayName: 'Run Ansible Lint (Static Code Analysis)'

- script: |
    ansible-playbook --syntax-check playbooks/deploy_web.yml
  displayName: 'Run Playbook Syntax Check'

or
Azure Repos is crucial for managing Ansible AWX and workflows. It acts as the single source of truth for playbooks, roles, and inventory files. Developers edit files in Visual Studio Code (VS Code), commit changes to Azure Repos, and trigger AWX projects to sync and execute automation safely
Workflow and Example
A standard Git workflow connects Visual Studio Code, Azure Repos, and Ansible AWX:
  • Write Code in VS Code: Clone your Azure repo locally. Create a feature branch. Write your Ansible playbook (site.yaml) and inventory files.
  • Commit and Push: Stage and commit your changes in VS Code. Push the feature branch to Azure Repos.
  • Pull Request (PR): Create a PR in Azure DevOps to merge the feature branch into the main branch. Peer review the YAML syntax.
  • AWX Sync: Configure Ansible AWX with a project pointing to your Azure Git repository via a Personal Access Token (PAT). AWX pulls the updated main branch automatically or via webhook.
  • Run Job Template: Execute the job template in AWX using the synced playbook from Azure Repos. [
Example Playbook & Test Case
Example Ansible Playbook (site.yaml)
yaml
---
- hosts: webservers
  become: yes
  tasks:
    - name: Ensure Nginx is installed
      apt:
        name: nginx
        state: present
    - name: Ensure Nginx is running
      service:
        name: nginx
        state: started
Test Case / Validation Scenario
  • Syntax Test (Pre-commit): Run ansible-playbook --syntax-check site.yaml locally inside VS Code terminal to verify YAML indentation and syntax rules.
  • Integration Test: Trigger an AWX job template in "Check Mode" (dry run) against a staging environment to confirm task viability before applying production changes. 
Interview Questions and Answers
  • Q: How does Ansible AWX authenticate with a private Azure DevOps Git repository?
    A: AWX authenticates using a Git Source Control credential configured with a Personal Access Token (PAT) generated from Azure DevOps.
     
  • Q: Why use VS Code for Ansible development instead of editing directly in AWX?
    A: VS Code provides local extension linting, syntax validation (ansible-lint), and local Git staging control before changes affect production workflows.
     
  • Q: How do you automate AWX project updates when a change is merged into Azure Repos?
    A: You can set the AWX Job Template to update the project on launch, or configure an Azure DevOps Service Hook / Webhook to call the AWX API whenever a push or merge occurs on the main branch.
     

Question : How to integrate Ansible AWX with Azure DevOps (ADO)

To integrate Ansible AWX with Azure DevOps (ADO), you need to sync your Ansible playbooks from Azure Repos to AWX and trigger AWX job templates from Azure Pipelines. 
Here is the complete, step-by-step implementation guide.
1. Sync Azure Repos to Ansible AWX (SCM Setup)
AWX uses Git to pull playbooks. Because standard HTTPS git authentication can struggle with Azure DevOps authentication requirements, the most reliable method is using SSH keys. 
In Azure DevOps:
  1. Generate an SSH key pair locally (ssh-keygen -t rsa -b 4048).
  2. Log into Azure DevOps.
  3. Click your User Profile Icon (top right) → User settings → SSH public keys.
  4. Click + New Key, paste your public key (id_rsa.pub), and save.
  5. Go to your repository and copy the SSH clone URL (e.g., git@://azure.com:v3/...). [
In Ansible AWX:
  1. Navigate to Credentials → Add.
  2. Name it Azure DevOps SSH Key.
  3. Set Credential Type to Source Control.
  4. Paste your private key (id_rsa) into the SSH Private Key box. Save it.
  5. Navigate to Projects → Add.
  6. Set Source Control Type to Git.
  7. Paste your Azure DevOps SSH clone URL into the Source Control URL field.
  8. Select the Azure DevOps SSH Key credential you created. Save and click Sync. [

2. Configure the AWX Job Template
Before automation can happen, AWX needs a template to execute. 
  1. Navigate to Templates → Add → Add job template.
  2. Link your Inventory, the newly synced Project, and select your target Playbook.
  3. Under Variables, check the box Prompt on Launch for Extra Variables (this allows Azure DevOps to pass runtime parameters dynamically).
  4. Save the template. Note the ID number from the URL (e.g., /templates/job_template/42/). [

3. Generate an AWX API Token
Azure DevOps needs a token to securely talk to the AWX REST API. 
  1. In AWX, click on Users and select your automation user.
  2. Click the Tokens tab → Add.
  3. Set Scope to Write and save.
  4. Copy the generated Bearer Token immediately. 

4. Create the Azure DevOps Pipeline
You will use a bash script step inside your azure-pipelines.yml file to send an API request to AWX. This triggers the template automatically when changes occur. 
Pipeline Configuration (azure-pipelines.yml)
yaml
trigger:
  - main

pool:
  vmImage: 'ubuntu-latest'

variables:
  # Map your secret token securely in the ADO library pipeline UI
  AWX_TOKEN: $(AWX_API_TOKEN) 
  AWX_URL: 'https://your-awx-url.com'
  TEMPLATE_ID: '42' # Replace with your template ID

steps:
- bash: |
    echo "Triggering Ansible AWX Job Template..."
    
    # Send the API request to launch the job
    RESPONSE=$(curl -X POST \
      -H "Authorization: Bearer $(AWX_TOKEN)" \
      -H "Content-Type: application/json" \
      -d '{"extra_vars": {"build_id": "$(Build.BuildId)", "environment": "production"}}' \
      -s -k "$(AWX_URL)/api/v2/job_templates/$(TEMPLATE_ID)/launch/")
    
    # Extract Job ID to track execution status
    JOB_ID=$(echo $RESPONSE | grep -oP '"job":\s*\K[0-9]+')
    
    if [ -z "$JOB_ID" ]; then
      echo "Failed to initiate AWX Job."
      echo "Response: $RESPONSE"
      exit 1
    fi
    
    echo "AWX Job successfully launched. Job ID: $JOB_ID"
    
    # Optional: Poll AWX API to track completion status
    echo "Checking job status..."
    while true; do
      STATUS_RESP=$(curl -X GET -H "Authorization: Bearer $(AWX_TOKEN)" -s -k "$(AWX_URL)/api/v2/jobs/$JOB_ID/")
      STATUS=$(echo $STATUS_RESP | grep -oP '"status":\s*"\K[^"]+')
      
      echo "Current Status: $STATUS"
      
      if [ "$STATUS" == "successful" ]; then
        echo "Ansible Playbook completed successfully!"
        break
      elif [ "$STATUS" == "failed" ] || [ "$STATUS" == "error" ] || [ "$STATUS" == "canceled" ]; then
        echo "Ansible Playbook failed."
        exit 1
      fi
      sleep 10
    done
  displayName: 'Trigger and Monitor Ansible AWX Job'
5. Securely Store Variables in Azure DevOps
To prevent plain-text exposure of your AWX token in your repository:
  1. Open your pipeline in the Azure DevOps editor.
  2. Click Variables in the top right corner.
  3. Click New variable.
  4. Name it AWX_API_TOKEN.
  5. Paste your AWX token into the value box.
  6. Check Keep this value secret to mask it in logs. 
When your code changes are pushed to the main branch, the pipeline will auto-fire, send the build details to AWX as extra_vars, and watch the deployment succeed in real-time. 

or
Integrating Azure DevOps with Ansible AWX allows you to use Azure DevOps for version control and CI/CD orchestration while leveraging AWX as your centralized infrastructure automation engine. This combination separates application development pipelines from secure infrastructure execution environments, providing role-based access control (RBAC), auditable logs, and centralized credential management. 

Integration Architecture Overview
When configuring this setup, responsibilities are split between the two platforms:
  • Azure Repos: Acts as the single source of truth, hosting your Ansible playbooks, roles, and configuration files.
  • Azure Pipelines: Triggers the CI/CD workflow upon a git push, performs linting/testing, and initiates deployment.
  • Ansible AWX: Acts as the execution hub. It pulls the playbooks from Azure Repos, injects secret credentials safely, and runs the actual jobs against target environments.

Step 1: Connect AWX to Azure Repos
AWX needs permission to pull your playbooks directly from your repository. 
  1. Generate a Token: In Azure DevOps, navigate to User Settings and generate a Personal Access Token (PAT) with Code (Read) scopes. 
  2. Create AWX Credential: Go to your AWX dashboard, click Credentials, and add a new credential.
    • Set the credential type to Source Control.
    • Input your Azure DevOps username and paste the PAT into the password field. 
  3. Create an AWX Project: Go to Projects in AWX and add a new project.
    • Select Git as the source control type.
    • Provide your Azure Repos HTTPS clone URL.
    • Attach the Source Control credential you just created.
    • (Optional) Check Update Revision on Launch to ensure AWX always fetches the latest code before running jobs. 

Step 2: Configure the AWX Job Template
A Job Template defines the parameters required to run a specific playbook. 
  1. Navigate to Templates -> Add Job Template in AWX.
  2. Link your newly created Project and select the specific .yml playbook file you want to target.
  3. Assign your target machine Inventory and target machine Credentials (e.g., SSH keys or Azure Resource Manager credentials).
  4. Under Options, check Prompt on Launch for any variables that need to be injected dynamically by Azure DevOps during runtime. [

Step 3: Trigger AWX from Azure Pipelines
Instead of executing Ansible code locally inside an Azure hosted runner, your pipeline will send a REST API call to AWX to kick off a managed job template. 
Below is an example of an Azure DevOps YAML Pipeline (azure-pipelines.yml) using curl to trigger AWX:
yaml
trigger:
  - main

variables:
  - name: AWX_URL
    value: 'https://your-awx-instance.com'
  - name: TEMPLATE_ID
    value: '42' # The ID of your AWX Job Template

stages:
- stage: Deploy
  jobs:
  - job: TriggerAWX
    pool:
      vmImage: 'ubuntu-latest'
    steps:
    - script: |
        echo "Triggering Ansible AWX Job Template $(TEMPLATE_ID)..."
        
        # Send API request to AWX to launch the job
        response=$(curl -s -X POST \
          -H "Authorization: Bearer $(AWX_TOKEN)" \
          -H "Content-Type: application/json" \
          -d '{"extra_vars": {"deployment_env": "production"}}' \
          $(AWX_URL)/api/v2/job_templates/$(TEMPLATE_ID)/launch/)
          
        # Extract Job ID from response to track status if needed
        job_id=$(echo $response | grep -oP '"job":\K[0-9]+')
        echo "AWX Job successfully launched. Job ID: $job_id"
      displayName: 'Launch Ansible Job via AWX API'
      env:
        AWX_TOKEN: $(AWX_API_TOKEN) # Stored securely in Azure DevOps Secret Variables
Summary of Benefits
FeatureLocal Pipeline Agent ExecutionAWX-Integrated Execution
Credential SecurityKeys exposed to the pipeline log or runner filesystem.Secrets stay locked inside AWX; never shared with Azure.
Execution Stateephemeral; logs disappear if pipeline history is cleared.Persistent central logs, audit trails, and execution histories.
Network SecurityRunners require direct firewall line-of-sight to target servers.Only AWX needs access to target nodes; Azure only talks to AWX API.
Would you like help setting up an Azure DevOps webhook so that AWX automatically synchronizes code whenever you merge a pull request? Or would you prefer to explore configuring Azure Dynamic Inventories within AWX to auto-discover your cloud virtual machines? 

Question : How to set up code deployments in Azure DevOps,


How to Run Ansible Playbooks From AWX GUI | Step-by-Step Tutorial

To set up code deployments in Azure DevOps, you must manually create an Azure DevOps organization via the web portal, as automated organization creation is not natively supported. This setup creates the foundational container for your deployment projects, pipelines, and target environments. [
 Step 1: Create an Azure DevOps Organization
  1. Navigate to Azure DevOps Services and click Start free.
  2. Sign in using your Microsoft account, GitHub account, or a Work/School account linked to Microsoft Entra ID. [
  3. Click New organization from the left pane or click Continue on the initial prompt. 
  4. Enter an Organization Name following these constraints:
    • Use English alphabet letters, numbers, or hyphens only.
    • Must start and end with a letter or number.
    • Keep the name under 50 characters. 
  5. Select your closest hosting geography (e.g., United States, Europe, India) to reduce pipeline latency. 
  6. Complete the CAPTCHA and click Continue. 
 Step 2: Establish Your Deployment Project
Once inside your new organization dashboard, configure a project container to host your code repositories and pipeline triggers: 
  1. Click the New project button in the upper-right corner.
  2. Assign a specific Project Name and short description.
  3. Choose your visibility level (Public or Private).
  4. Select your preferred Version Control system (usually Git) and Work item process template (e.g., Agile, Scrum).
  5. Click Create. [
 Step 3: Setup the Deployment Infrastructure
After your organization and project are live, map your target servers for deployments through the Azure Pipelines tab: 
  • For Cloud App Services / Kubernetes: Go to Pipelines > Environments > Create environment to group physical or virtual cloud resources for pipeline orchestration. 
  • For On-Premises VMs: Go to Pipelines > Deployment groups > New, select your OS target type, and execute the provided registration script on your target servers. 

Question : How to manager WSL
To manage and maintain Windows Subsystem for Linux (WSL), use the wsl command-line utility in Windows PowerShell or Command Prompt. The core shutdown command is wsl --shutdown, while maintenance tasks use options like --terminate, --export, and --set-version. 
Shutdown Commands
  • Shut down all running distributions and the WSL 2 lightweight utility VM: wsl --shutdown
  • Stop a single specific Linux distribution: wsl --terminate <DistributionName> (or wsl -t <DistributionName>) 
Maintenance & Management Commands
  • List all installed distributions and check if they are running or stopped: wsl --list --verbose (or wsl -l -v)
  • Change a distribution version between WSL 1 and WSL 2: wsl --set-version <DistributionName> <Version>
  • Backup or export a distribution to a tar file for maintenance: wsl --export <DistributionName> <FileName.tar>
  • Restore or import a distribution from a tar backup file: wsl --import <DistributionName> <InstallLocation> <FileName.tar>
  • Completely remove and delete a distribution and its data: wsl --unregister <DistributionName> 


 To install Docker Engine on Ubuntu, the recommended approach is to set up Docker's official repository and install the native packages. This ensures you get the latest stable version and security updates. 

1. Clear Old Versions
Remove conflicting or older versions before starting: 
bash
sudo apt-get remove docker docker-engine docker.io containerd runc
Use code with caution.
2. Set Up the Repository
Install required tools and add Docker's official GPG key to verify packages: 
bash
# Update package index
sudo apt-get update

# Install prerequisites
sudo apt-get install ca-certificates curl gnupg -y

# Add the official GPG key
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to APT sources
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Use code with caution.
3. Install Docker Engine
Update the repository indexes and install Docker alongside Docker Compose: 
bash
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y

No comments:

Post a Comment