Deploy application to Kubernetes with Ansible
This tutorial contains a pipeline that deploys an simple hello-world application to a Kubernetes cluster.
Prerequisites
You will need a running Kubernetes cluster, that supports services with LoadBalancer
type, and a kubeconfig file that can be used to deploy application (a deployment and a service) into the cluster.
Preparing the Jenkins instance
The pipeline provided by this tutorial can be added to any Jenkins instance you have administrator access and can run pipeline stages with docker agent. For example, Jenkins configuration from Jenkins with access to hosts Docker engine tutorial can be used.
We will use secret file to configure credentials for managing the target Kubernetes cluster. To create the secret file credential, open Global credentials from Jenkins credentials store from Manage Jenkins > Manage Credentials and click Add Credentials from the left side menu.
In the New credentials form:
- Select Secret file as the credential kind
- Upload your kubeconfig to the file input
- Configure ID for the credential. Jenkinsfile uses
kubeconfig
as the ID. - (Optionally) add a description.
Configure the pipeline
First, create a new pipeline via New Item button in the rigth side menu of the Jenkins dashboard. The name of the pipeline could be for example Animals
and it should be an pipeline.
In the configure pipeline view, scroll to the bottom and under Pipeline sub-header select Pipeline script from SCM
. SCM type should be Git
and Repository URL the url of this repository: https://github.com/cicd-tutorials/cicd-tutorials.net.git
. Ensure that branch specifier includes main
branch of the repository and modify the Script Path to be docs/tutorials/jenkins/ansible-kubernetes/Jenkinsfile
.
The pipeline deploys an example application to a Kubernetes cluster using Ansible playbook. The playbook selects a container image tag based on Jenkins build parameter.
String d = "docs/tutorials/jenkins/ansible-kubernetes"
pipeline {
agent any
parameters {
choice(name: 'ANIMAL', choices: ['cat', 'cow', 'dog', 'lion', 'pig'], description: 'Tag to use for deployment image')
}
stages {
stage("deploy") {
agent {
dockerfile {
dir "$d"
reuseNode true
}
}
environment {
K8S_AUTH_KUBECONFIG = credentials('kubeconfig')
KUBECONFIG = credentials('kubeconfig')
}
steps {
sh """
ansible-playbook $d/deploy-to-kubernetes.yml --extra-vars "animal=${params.ANIMAL}"
./$d/wait-until-service-up.sh
"""
}
}
}
}
After you have created the pipeline, try to execute it by clicking Build Now. The pipeline should have deployed the example application into the Kubernetes cluster with the default image tag (cow
) defined in the deploy-to-kubernetes.yml Ansible playbook.
- name: Deploy and expose application
hosts: localhost
gather_facts: no
vars:
animal: cow
tasks:
- name: Create a deployment
kubernetes.core.k8s:
definition:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: animals
name: animals
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: animals
template:
metadata:
labels:
app: animals
spec:
containers:
- image: ghcr.io/cicd-tutorials/animals:{{ animal }}
name: animals
- name: Expose the deployment
kubernetes.core.k8s:
definition:
apiVersion: v1
kind: Service
metadata:
labels:
app: animals
name: animals
namespace: default
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: animals
type: LoadBalancer
After the Ansible playbook has been executed, the pipeline runs wait-until-service-up.sh script. The script waits until the load-balancer created by the Kubernetes service has reached running state and parses the URL where the example application is running.
#!/bin/sh -xe
get_hostname() {
kubectl get service animals -o json | \
jq -re .status.loadBalancer.ingress[0].hostname
}
# Wait until hostname is available
until get_hostname; do
sleep 15;
done;
# Wait until animals application is up
hostname=$(get_hostname)
until curl -sSf $hostname; do
sleep 15;
done;
echo "Load-balancer URL: $hostname"
You can find the URL of the created load-balancer from the console output of the build. Open the application with your browser or user curl to see the application response.
In addition, after the first execution Jenkins should have updated the project configuration to contain parameters defined in the pipeline and we can configure the image tag in Build with Parameters menu.