bookmark_borderDeploy on Docker using Ansible & Jenkins

  1. Prerequisites
  2. Install Ansible
  3. Add Ansible Server user
    1. Sudo Access to ansible user
  4. Install Docker in ansible server
  5. Add a new user in Docker Group
  6. Setting up Password Authentication
  7. Create SSH Keygen
  8. Add ansible user at the target server
  9. Copy Key for Target System
  10. Test Connectivity by PING TEST
  11. Integrate Ansible with Jenkins
  12. Basic Jenkins Job for Ansible
  13. After adding Docker file and yml file, run ansible-playbook in Ansible server
  14. Run ansible-playbook in Jenkins
  15. Poll SCM for automation for GitHub
  16. DockerHub integration with Ansible
  17. Using Ansible, push Docker image to Docker Hub.
  18. Using Jenkins Job, Docker Deploy using Docker Hub
    1. Manual
    2. Automation with Jenkins

Prerequisites

  1. EC2 Instance
    • With Internet Access
    • Security Group with Port 8080 open for internet

2. Jenkins Server & Target Server.

Install Ansible

$ sudo su -
$ yum install python
$ yum install python-pip
$ pip install ansible
$ ansible --version
  • You need python to install Ansible.

Directory is needed for recent version of ansible.

$ mkdir /etc/ansible

Add Ansible Server user

$ sudo su -
$ useradd ansadmin
$ passwd ansadmin
Changing password for user ansadmin
New password:
Retype new password: 
passwd: all authentication tokens updated successfully.
  • Remember the password

Grant sudo Access to ansible user

$ visudo

## Read drop-in files from /etc/sudoers.d (the # here does not mean a comment)
#includedir /etc/sudoers.d
ansadmin ALL=(ALL) NOPASSWD: ALL
  • ansadmin ALL=(ALL) NOPASSWD: ALL 추가

Install Docker in ansible server

$ yum install docker
$ service docker status
$ service docker start
  • Install and Execute Docker

Add a new user in Docker Group

$ usermod -aG docker ansadmin
$ sudo service docker restart

Setting up Password Authentication

EC2(Amazon Linux Server), default password authentication setting is no

$ vi /etc/ssh/sshd_config
# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication yes
#PermitEmptyPasswords no
#PasswordAuthentication no

PasswordAuthentication yes

Service reload

$ service sshd reload

Create SSH Keygen

$ su - ansadmin
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/ansadmin/.ssh/id_rsa): 
Created directory '/home/ansadmin/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/ansadmin/.ssh/id_rsa.
Your public key has been saved in /home/ansadmin/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:JVLpKGadkV21y062amUhv0WQG5KoQZVPlWmqPrAJG6E ansadmin@ip-172-31-42-234.ap-northeast-2.compute.internal
The key's randomart image is:
+---[RSA 2048]----+
|     ..+o=.+o+   |
|      +.= + B.   |
|     ..B.o.+.+   |
|    = =..o+.o..  |
|   + o  S. o=o   |
|  E o . .  ++..  |
|     + =   ooo   |
|    . o o ...    |
|         o.      |
+----[SHA256]-----+
$ pwd
/home/ansadmin/.ssh
  • Enter file in which to save the key (/home/ansadmin/.ssh/id_rsa):
    • home/ansadmin/.ssh 폴더에 id_rsa 키젠 생성

Add ansible user at the target server

In Target Server

$ sudo su -
$ useradd ansadmin
$ passwd ansadmin
Changing password for user ansadmin
New password:
Retype new password: 
passwd: all authentication tokens updated successfully.
$ vi /etc/ssh/sshd_config
# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication yes
#PermitEmptyPasswords no
#PasswordAuthentication no

Copy Key for Target System

In Ansible Server

$ su - ansadmin
$ ssh-copy-id ansadmin@{target server private-ip}
$ ssh-copy-id ansadmin@{target server private-ip}
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/ansadmin/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
ansadmin@172.31.13.186's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'ansadmin@172.31.13.186'"
and check to make sure that only the key(s) you wanted were added.
$ ssh ansadmin@{target server private-ip}
  • Now, you can access from Ansible server to Target server.

Test Connectivity by PING TEST

In Ansible Server

Create hosts file in /etc/ansible

$ sudo vi hosts
target server private-ip
localhost

Before the test localhost Keygen id copy

$ ssh-copy-id localhost

PING TEST

$ ansible all -m ping
{target server private-ip} | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
localhost | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

Integrate Ansible with Jenkins

Manage Jenkins→ Configure System

Publish over SSH → Jenkins can access to ansible server by SSH.

  • SSH server Name: ansible-server
  • Hostname: ansible-host-IP(private)
  • Username: ansadmin
    • Advance check Use password authentication, or use a different key
    • password: ansadmin-password
  • Test Configuration
  • Apply & Save

Basic Jenkins Job for Ansible

In Ansible Server

$ cd /opt
$ sudo mkdir docker
$ sudo chown -R ansadmin:ansadmin /opt/docker
  • Create folder for managing docker image

New Item → Enter an item name (Maven Project) → Edit Description

Enter an item name: deploy_container_using_ansible

Edit Description: deploy_container_using_ansible

Source Code Management: git

Build

  • Goals and options: clean install package

Post-build Actions

  • Send build artifacts over SSH example) Name: ansible-server Transfers Transfer Set
    • Source files: webapp/target/*.war
    • Remove prefix: webapp/target/
    • Remote directory : //opt//docker

Apply & Save

Build Now

SSH: Connecting from host [ip-172-31-46-226.ap-northeast-2.compute.internal]
SSH: Connecting with configuration [ansible] ...
SSH: Disconnecting configuration [ansible] ...
SSH: Transferred 1 file(s)
Finished: SUCCESS

Check War file is saved in ansible server.

In Ansible Server

$ pwd
/opt/docker
$ ls
webapp.war

After adding Docker file and yml file, run ansible-playbook in Ansible server

Adding Dockerfile & docker-image.yml in /opt/docker

$ sudo vi Dockerfile
FROM tomcat:latest

MAINTAINER AR Shankar

COPY ./webapp.war /usr/local/tomcat/webapps
$ sudo vi devops-image.yml
---
- hosts: all
  become: true
  tasks:
  - name: stop if we have old docker container
    command: docker stop devops-container
    ignore_errors: yes

  - name: remove stopped docker container
    command: docker rm devops-container
    ignore_errors: yes

  - name: remove current docker image
    command: docker rmi devops-image
    ignore_errors: yes
#    register: result
#    failed_when:
#      - result.rc == 0
#      - '"docker" not in result.stdout'


  - name: building docker image
    command: docker build -t devops-image .
    args:
      chdir: /opt/docker

  - name: creating docker image
    command: docker run -d --name devops-container -p 8080:8080 devops-image
  • ignore_errors: Setting up as yes for the case Docker image or container is not existed.
  • Create image and Container

Add hosts file in /opt/docker

$ sudo vi hosts
localhost

check & run ansible playbook

$ ansible-playbook -i hosts devops-image.yml --check
$ ansible-playbook -i hosts devops-image.yml
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
a5245d24f49a        devops-image        "catalina.sh run"   16 seconds ago      Up 15 seconds       0.0.0.0:8080->8080/tcp   devops-container

check web app is running at http://ansible-server-ip:8080/webapp/

Run ansible-playbook in Jenkins

In Jenkins, before execute ansible playbook, delete docker image and container

  • devops-image.yml

Edit Jenkins fob for Ansible with ansible command

Send build artifacts over SSH

deploy_container_using_ansible → configuration

SSH Publishers

  • Add Transfers Exec command ansible-playbook -i /opt/docker/hosts /opt/docker/devops-image.yml;

Apply & Save

After Build, you can see that docker image and container are created.

$ docker ps
36fb15f04958        devops-image        "catalina.sh run"   19 seconds ago      Up 18 seconds       0.0.0.0:8080->8080/tcp   devops-container

check: http://ansible-server-ip:8080/webapp/

Poll SCM for automation for GitHub

deploy_container_using_ansible → configuration.

Build Triggers – Poll SCM – Schedule

* * * * *

Every 1 minute, Check GitHub’s repository Update.

DockerHub integration with Ansible

  • Push to Public repository

In Ansible Server

Manually image is pushed to DockerHub

$ docker tag devops-image jayjodev/devops-image
$ docker login
  • Enroll DockerHub.
  • Docker login as a root user
$ docker push jayjodev/devops-image
  • Check your image is in DockerHub.

Using Ansible, push Docker image to Docker Hub

In Ansible Server

Create dockerhub-devops-image.yml in /opt/docker

---
- hosts: all
  become: true

  tasks:
  - name: create docker image using war file
    command: docker build -t devops-image:latest .
    args:
      chdir: /opt/docker

  - name: create tag to image
    command: docker tag devops-image jayjodev/devops-image

  - name: push image on to dockerhub
    command: docker push jayjodev/devops-image

  - name: remove docker images from ansible server
    command: docker rmi devops-image:latest jayjodev/devops-image
    ignore_errors: yes
$ ansible-playbook -i hosts dockerhub-devops-image.yml

From Docker hub bring image. devops-image.yml in /opt/docker

---
- hosts: all
  become: true
  tasks:
  - name: stop if we have old docker container
    command: docker stop devops-container
    ignore_errors: yes

  - name: remove stopped docker container
    command: docker rm devops-container
    ignore_errors: yes

  - name: remove current docker image
    command: docker rmi jayjodev/devops-image
    ignore_errors: yes
#    register: result
#    failed_when:
#      - result.rc == 0
#      - '"docker" not in result.stdout'


#  - name: building docker image
#    command: docker build -t devops-image .
#    args:
#      chdir: /opt/docker

  - name: pull docker image from dockerhub
    command: docker pull jayjodev/devops-image:latest

  - name: creating docker image
    command: docker run -d --name devops-container -p 8080:8080 jayjodev/devops-image

Test

$ ansible-playbook -i hosts devops-image.yml

For Jenkins Job, Add target system ip in hosts in /opt/docker

$ sudo vi hosts
target-server-ip(private)
localhost

Using Jenkins Job, Docker Deploy using Docker Hub

Manually

In Ansible Server

  • limit to specific system Test in /opt/docker
$ ansible-playbook -i hosts dockerhub-devops-image.yml --limit localhost
  1. TASK [create docker image using war file]
  2. TASK [create tag to image]
  3. TASK [push image on to dockerhub]
  4. TASK [remove docker images from ansible server]

From Docker hub, pull docker image to target System and execute.

$ ansible-playbook -i hosts devops-image.yml --limit {target-server-ip(private)}
  1. TASK [stop if we have old docker container] changed: [target server]
  2. TASK [remove stopped docker container] changed: [target server]
  3. TASK [remove current docker image] changed: [target server]
  4. TASK [pull docker image from dockerhub] changed: [target server]
  5. TASK [creating docker image]

In Target Server

$ docker ps
CONTAINER ID        IMAGE                   COMMAND             CREATED             STATUS              PORTS                    NAMES
1c088b934aac        jayjodev/devops-image   "catalina.sh run"   3 minutes ago       Up 3 minutes        0.0.0.0:8080->8080/tcp   devops-container

check web app is running at http://target-server-ip:8080/webapp/

Automation with Jenkins

New Item → Enter an item name (Maven Project) → Edit Description

Enter an item name: automation_ansible

Edit Description: automation_ansible

Source Code Management: git

Build Triggers

Poll SCM / Schedule

* * * * *

Every 1 minute, Check GitHub’s repository Update

Build

  • Goals and options: clean install package

Post-build Actions

  • Send build artifacts over SSH example) Name: ansible-server Transfers Transfer Set
    • Source files: webapp/target/*.war
    • Remove prefix: webapp/target/
    • Remote directory : //opt//docker
    • Exec command:
ansible-playbook -i /opt/docker/hosts /opt/docker/dockerhub-devops-image.yml --limit localhost;
ansible-playbook -i /opt/docker/hosts /opt/docker/devops-image.yml --limit {target-server-ip(private)};

Apply & Save

Build Now

log exampe)

TASK [create docker image using war file] **************************************
changed: [localhost]

TASK [create tag to image] *****************************************************
changed: [localhost]

TASK [push image on to dockerhub] **********************************************
changed: [localhost]

TASK [remove docker images from ansible server] ********************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=5    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   


PLAY [all] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [target server]

TASK [stop if we have old docker container] ************************************
changed: [target server]

TASK [remove stopped docker container] *****************************************
changed: [target server]

TASK [remove current docker image] *********************************************
changed: [target server]

TASK [pull docker image from dockerhub] ****************************************
changed: [target server]

TASK [creating docker image] ***************************************************
changed: [target server]

PLAY RECAP *********************************************************************
target server              : ok=6    changed=5    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

SSH: EXEC: completed after 27,225 ms
SSH: Disconnecting configuration [ansible] ...
SSH: Transferred 1 file(s)
Finished: SUCCESS
  • After Build, check Docker Hub. Also, check the Container in the target server.

Source: https://www.udemy.com/course/valaxy-devops/

ANOTE.DEV