# Part 6: Running Ansible from Jenkins

### Jenkins CI/CD Series

| Part | Article |
| --- | --- |
| 1 | [Install Jenkins with Docker](https://ask-abhi.com/part-1-install-jenkins-with-docker) |
| 2 | [Creating Your First Jenkins Pipeline](https://ask-abhi.com/part-2-creating-your-first-jenkins-pipeline) |
| 3 | [Jenkins SSH Remote Execution](https://ask-abhi.com/part-3-jenkins-ssh-remote-execution) |
| 4 | [Automating MySQL Backup to AWS S3](https://ask-abhi.com/part-4-automating-mysql-backup-to-aws-s3) |
| 5 | [Making Jenkins Automation Scalable](https://ask-abhi.com/part-5-making-jenkins-automation-scalable) |
| 6 | [Running Ansible from Jenkins](https://ask-abhi.com/part-6-running-ansible-from-jenkins) |
| 7 | [Jenkins Pipeline from GitHub](https://ask-abhi.com/part-7-control-jenkins-pipeline-through-github) |
| 8 | [Multibranch Pipelines](https://ask-abhi.com/part-8-multibranch-pipelines) |
| 9 | [Parameterized Pipelines](https://ask-abhi.com/part-9-parameterized-pipelines) |
| 10 | [Environment Variables in Pipelines](https://ask-abhi.com/part-10-environment-variables-in-pipelines) |

* * *

### Goal

Enable Jenkins to execute **Ansible automation tasks** by integrating Ansible into the Jenkins container, allowing centralized orchestration of remote infrastructure using playbooks.

* * *

### Purpose

The purpose of this part is to extend your CI/CD pipeline capabilities by introducing **configuration management with Ansible**.

By the end of this setup, you will:

*   Run Ansible commands directly from Jenkins
    
*   Manage remote systems using **Ansible inventory + playbooks**
    
*   Automate infrastructure tasks via Jenkins jobs
    
*   Establish a foundation for **Infrastructure as Code (IaC)**
    

This bridges the gap between **CI/CD pipelines and infrastructure automation**, which is a core DevOps skill.

* * *

### Prerequisites

Before starting this part, ensure you have:

*   Ready to use `Host` and the `directory` structure to run `Dockerfiles` and `docker-compose.yml` (Refer to [Part 1](https://ask-abhi.com/part-1-install-jenkins-with-docker))
    

* * *

### Step-by-step implementation

### Install Ansible on Docker (on an existing Jenkins Container)

Create another folder `/home/jenkins/jenkins_home/jenkins-ansible$`

*   **Create a customized Dockerfile for Jenkins to create a Jenkins container to support Ansible**
    

```dockerfile
FROM jenkins/jenkins
USER root

RUN apt-get update && apt-get install python3-pip -y

# New lines to set up a virtual environment
####
ENV ANSIBLE_VENV=/ansible_venv
RUN mkdir $ANSIBLE_VENV && \
    chown jenkins:jenkins $ANSIBLE_VENV && \
    apt-get install python3-venv -y
####

USER jenkins

# Activate the virtual environment
RUN python3 -m venv $ANSIBLE_VENV

# Use the venv to install Ansible
RUN $ANSIBLE_VENV/bin/pip3 install ansible

# Ensure the Ansible binary is accessible
ENV PATH=$PATH:$ANSIBLE_VENV/bin
```

*   **Go back to one more directory, where we have our Docker Compose file, and update the content to fetch details from the Dockerfile we created in the earlier step.**
    

`/home/jenkins/jenkins_home/docker-compose.yml`

```yaml
services:
  jenkins:
    container_name: jenkins
    image: jenkins-ansible
    build:
      context: jenkins-ansible
    ports:
      - "8080:8080"
    volumes:
      - $PWD/jenkins_home:/var/jenkins_home
    networks:
      - net

  remote_host:
    container_name: remote-host
    image: remote-host
    build:
      context: centos7
    volumes:
      - "$PWD/aws-s3.sh:/tmp/script.sh"
    networks:
      - net

  db_host:
    container_name: db
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: 1234
    volumes:
      - $PWD/db_data:/var/lib/mysql
    networks:
      - net

networks:
  net:
```

> Tips - Update Jenkins block (`image: jenkins-ansible, build: context: jenkins-ansible)`

```plaintext
docker compose build
```

> Note- Always run the docker compose from the directory where we have docker-compose.yml

*   **The new Jenkins Image has been built**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/2335e87b-906f-436e-9444-ce2c2ef6e91e.png align="center")

*   **Create a Jenkins container by using this Image**
    

```shell
#Below commands used to vrify Jenkins container has ansible installed

docker compose up -d
docker ps
docker exec -it jenkins bash
ansible
```

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/923b84a5-26ce-4c6c-b794-f3191a7ebd6d.png align="center")

> Note- Typing ansible will show avaible options to run any command means, its installed

Created an Ansible folder for the Ansible home directory

`/home/jenkins/jenkins_home/ansible`

> Note- /jenkins\_home is acting as an volumes for our jenkins container since we have given same context in docker-compose.yml

*   **Copy the remote key to the Ansible folder directly**
    

```plaintext
home/jenkins/jenkins_home$ sudo cp centos7/remote-key jenkins_home/ansible/
```

Since we're moving around the **remote-key** file, it's always a good idea to ensure that **Jenkins has the correct permissions** for it.

*   **Run the following command to set the right permissions:**
    

```plaintext
docker exec # Asks Docker to run a command 
-u root # Using the root user 
jenkins # On the container named jenkins 
bash # Using bash 
-c "chmod 400 /var/jenkins_home/ansible/remote-key && chown 1000:1000 /var/jenkins_home/ansible -R" # Set proper permissions
```

*   **What does this do?**
    

`chmod 400 /tmp/remote-key` → Sets read-only permissions for the key file.

`chown 1000:1000 /tmp/remote-key` → Ensures Jenkins (user ID 1000) owns the key.

This step prevents permission issues when using the key inside the container.

* * *

*   **Create Inventory in Ansible**
    

Create a file named `hosts` on `/home/jenkins/jenkins_home/jenkins-ansible` and add the below content

```plaintext
[all:vars]

ansible_connection - ssh

[test] 
test1 ansible_host=remote_host ansible_user=remote_user ansible_private_key_file=/var/jenkins_home/ansible/remote-key
```

*   **Copy the hosts file to the** `Jenkins` **container in** `jenkins_home/ansible` **folder**
    

```plaintext
cp hosts ../jenkins_home/ansible
```

*   **Log in to the Jenkins container and run the command**
    

```plaintext
docker exec -it jenkins bash
```

*   **Verify files**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/4a5e9199-3a5e-4104-9a00-3d1138e880b6.png align="center")

*   **Run the inventory**
    

```plaintext
ansible -i hosts -m ping test1
```

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/59477006-3016-4182-9eb0-46fbaeb68b03.png align="center")

> Note - Run ansible command from where is the inventory file located
> 
> any issues to connect, it must be SSH key permission issue or when connecting to from jenkins to remote\_host
> 
> `ssh -i /var/jenkins_home/ansible/remote-key remote_user@remote_host`

* * *

### Create a Playbook `play.yml` at the host directory `/home/jenkins/jenkins_home/jenkins-ansible`

```yaml
- name: Test playbook 
  hosts: test1 
  tasks:
    - name: Create file using shell 
      shell: echo Hello World > /tmp/ansible-file
```

*   **Copy play.yml to the Jenkins container**
    

```plaintext
cp play.yml ../jenkins_home/ansible/
```

*   **Log in to the Jenkins container**
    
*   **Check if the file is present**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/ecb590e4-3bd8-4a62-abb9-8128620944e0.png align="center")

*   **Run the** `play.yml`
    

```plaintext
ansible-playbook -i hosts play.yml
```

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/79de2169-1ad6-4238-99c2-3ee1b7061352.png align="center")

*   **Check where the file is generated?**
    

**Here it is on the remote-host**

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/4a3134f3-0527-4d42-91e7-af38ea7159dc.png align="center")

* * *

### Jenkins and Ansible Integration

*   **Log in to the Jenkins console and install the Ansible plugin.**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/9daa9b88-f309-4110-ab03-dc374aa7dc74.png align="center")

*   **Create Freestyle pipeline ansible-test**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/80eacd0c-6fba-49ac-be8a-e80edfdba04a.png align="center")

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/4fb7c298-395b-400a-8346-6a0ab3e2a86d.png align="center")

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/167fcc1e-cf67-46bd-bfe0-851f32af19b6.png align="center")

*   **Click on** `Build Now` **and** `Console Output`
    
*   **Verify output**
    

![](https://cdn.hashnode.com/uploads/covers/6997142f587b14d25b5231b7/68e1f28b-2e95-4e56-be0a-e6cb9ee0136b.png align="center")

### Done!!!

* * *

### Conclusion

In this part, you successfully integrated **Ansible with Jenkins**, transforming your CI/CD pipeline into a powerful automation engine capable of managing infrastructure.

You have:

*   Installed Ansible inside a custom Jenkins container
    
*   Configured secure SSH access using private keys
    
*   Created and tested Ansible inventory and playbooks
    
*   Executed automation tasks on remote systems
    
*   Integrated Ansible execution into Jenkins jobs
    

This is a **major milestone** in your DevOps journey — you are no longer just building pipelines, but **automating infrastructure at scale**.

This setup reflects real-world practices where Jenkins acts as an **orchestrator**, and Ansible handles **configuration management and deployment**.

* * *

### 🔗 Continue the Series

⬅️ **Previous Article:** [Part 5 Making Jenkins Automation Scalable](https://ask-abhi.com/part-5-making-jenkins-automation-scalable)  
➡️ **Next Article:** [Part 7 Jenkins Pipeline from GitHub](https://ask-abhi.com/part-7-control-jenkins-pipeline-through-github)

* * *

⭐ If you found this article useful, follow **https://ask-abhi.com** for more DevOps tutorials.

* * *
