Bitbucket Pipelines are basically docker containers, hosted in the Bitbucket infrastructure, that you can run to build or deploy your code, attaching them to “events” happening in your repository. Usually a push on one branch.
You can clone or fork this Bitbucket repository to follow along with this tutorial.
First thing first, add a file named bitbucket-pipelines.yml to the root of your repository. The content of the file should be similar to this:
# use the official Python 2.7.16 docker image image: python:2.7.16 pipelines: branches: # deploy only when pushing to the master branch master: - step: name: Deploy to prod # this is the name of the Bitbucket Deployment deployment: Production caches: # cache the Ansible installation - pip script: # install Ansible - pip install ansible==2.8.0 # go into the ansible directory # in this same repository - cd ansible # perform the actual deploy - ansible-playbook -i ./hosts deploy.yaml
Let’s examine the configuration line by line:
- On line 2 you define the docker image you want to use;
- On line 7 you define the branch that will trigger the deploy (master in this example);
- On line 11 you define the deployment, that is basically an environment (managed by Bitbucket) where you can define some variables. In this way you can have different deployments (staging, production, …) with different variables that you can use in your build/deploy steps. In this example I do not use this feature, and I merely use one of the default Bitbucket deployments (named Production) without configuring any variable in this environment;
- On line 14 you are asking Bitbucket to cache the installation of packages installed by pip. This is useful to avoid to reinstall every time the Python libraries you need for your deployment (Ansible 2.8.0 in this example) from scratch. Having the libraries already installed save you some build/deploy time, which is important because the build time for Bitbucket Pipelines is limited to 50 minutes/month in the free plan.
- From line 16 to line 22 you define the actual steps for deployment: install Ansible (if not already cached), go into the ansible directory, make the deploy. Please check the playbook ansible/deploy.yaml to see what it will actually do on the target server.
Commit and push the bitbucket-pipelines.yml file on the root of your Bitbucket repository.
Now go on your repository settings and click Settings under the section PIPELINES:
Now click on Enable Pipelines:
If you have read my previous post on how to deploy a Django project using Ansible, you should know that Ansible work through an SSH connection made between the client host (the Bitbucket Pipeline docker container in this case) and the server where you want to deploy your code.
For this SSH connection to work you have to setup an SSH public/private keypair on the Bitbucket Pipeline, and allow the public key on your server authorized_keys.
Go on the settings of your repository, under PIPELINES navigate to SSH keys:
Now click on “Generate keys” to let Bitbucket generate a new SSH keypair for you.
Now you can copy the generated public key and paste it in the .ssh/authorized_keys file of your deploy target.
You can refer to the Bitbucket documentation about SSH keys, if you need more details.
You can test that the deploy is working simply by pushing some changes to the master branch of the repository
If you want to push some changes on master, but you do not want to deploy the change automatically on the server, you can put the string [skip-ci] in your commit message.
I hope that this tutorial helped you understand the potential of Bitbucket Pipelines and Ansible to simplify your workflow and setup a simple but powerful continuous delivery for your Django project!