<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Guguweb - ansible</title><link href="https://www.guguweb.com/" rel="alternate"></link><link href="https://www.guguweb.com/feeds/ansible.atom.xml" rel="self"></link><id>https://www.guguweb.com/</id><updated>2022-03-30T14:50:52+02:00</updated><subtitle>Freelance developer and sysadmin</subtitle><entry><title>Bitbucket Pipelines and Ansible: Continuous delivery for your Django project</title><link href="https://www.guguweb.com/2020/01/03/bitbucket-pipelines-and-ansible-continuous-delivery-for-your-django-project/" rel="alternate"></link><published>2020-01-03T08:33:41+00:00</published><updated>2022-01-14T21:08:18+01:00</updated><author><name>Augusto Destrero</name></author><id>tag:www.guguweb.com,2020-01-03:/2020/01/03/bitbucket-pipelines-and-ansible-continuous-delivery-for-your-django-project/</id><summary type="html">&lt;p class="lead"&gt;
  &amp;#8220;Bitbucket Pipelines and Ansible: Continuous delivery for your Django project&amp;#8221; was originally published as a guest post on &lt;a href="https://bitbucket.org/blog/continuous-delivery-for-django-projects-with-bitbucket-pipelines-and-ansible"&gt;Bitbucket Blog&lt;/a&gt;.
&lt;/p&gt;

&lt;div class="toc"&gt;&lt;span class="toctitle"&gt;Table of Contents&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#introduction"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#let-the-automation-begin"&gt;Let the automation begin!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#setup-your-pipelines"&gt;Setup your pipelines&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#conclusion"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.ansible.com/"&gt;Ansible&lt;/a&gt; is a powerful tool for the automation of your server administration. It can be used both …&lt;/p&gt;</summary><content type="html">&lt;p class="lead"&gt;
  &amp;#8220;Bitbucket Pipelines and Ansible: Continuous delivery for your Django project&amp;#8221; was originally published as a guest post on &lt;a href="https://bitbucket.org/blog/continuous-delivery-for-django-projects-with-bitbucket-pipelines-and-ansible"&gt;Bitbucket Blog&lt;/a&gt;.
&lt;/p&gt;

&lt;div class="toc"&gt;&lt;span class="toctitle"&gt;Table of Contents&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#introduction"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#let-the-automation-begin"&gt;Let the automation begin!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#setup-your-pipelines"&gt;Setup your pipelines&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#conclusion"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.ansible.com/"&gt;Ansible&lt;/a&gt; is a powerful tool for the automation of your server administration. It can be used both to install and configure the software needed for your application and to deploy a new version of your application.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bitbucket.org/product/features/pipelines"&gt;Bitbucket Pipelines&lt;/a&gt; are basically Docker containers, hosted in the Bitbucket infrastructure, that you can launch automatically to build or deploy your code. They can be attached to “events” happening in your repository, usually a push on one branch.&lt;/p&gt;
&lt;p&gt;These tools are complementary to each other, because on Ansible you can define exactly what you want to do on your target server to deploy your application, while on Bitbucket Pipelines you can configure and launch a container to perform the actual deploy.&lt;/p&gt;
&lt;p&gt;In a previous post I described &lt;a href="https://www.guguweb.com/2017/05/02/how-to-deploy-a-django-project-in-15-minutes-with-ansible/"&gt;how to deploy a Django project using Ansible&lt;/a&gt;. Here I explain how to make a step further and deploy a Django project using &lt;a href="https://bitbucket.org/product/features/pipelines"&gt;Bitbucket Pipelines&lt;/a&gt; and &lt;a href="https://www.ansible.com/"&gt;Ansible&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The use-cases for deploying a Django project automatically are many. Even if your Django project has a simple architecture, there are many steps you have to perform in the right order to complete a successful deploy in the general case. As a bare minimum you&amp;#8217;ll have to: update the application code, install or update project dependencies, migrate the database, collect static files, restart the application server.&lt;/p&gt;
&lt;p&gt;Automating all these steps in a reproducible and formal way will save you a lot of time in the long run and will help you to avoid human errors. Think about how many times you&amp;#8217;ll deploy a new version of your application in the future.&lt;/p&gt;
&lt;p&gt;If your architecture is more complex, the number of steps to perform will be larger and the deploy process will be more error-prone, so the benefits of an automated deploy will be even greater.&lt;/p&gt;
&lt;h2 id="let-the-automation-begin"&gt;Let the automation begin!&lt;/h2&gt;
&lt;p&gt;You can clone or fork &lt;a href="https://bitbucket.org/baxeico/django_ansible"&gt;this Bitbucket repository&lt;/a&gt; to follow along with this tutorial.&lt;/p&gt;
&lt;p&gt;First thing first, add a file named &lt;strong&gt;bitbucket-pipelines.yml&lt;/strong&gt; to the root of your repository. The content of the file should be similar to this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# use the official Python 2.7.16 docker image&lt;/span&gt;
&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;python:2.7.16&lt;/span&gt;

&lt;span class="nt"&gt;pipelines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nt"&gt;branches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# deploy only when pushing to the master branch&lt;/span&gt;
    &lt;span class="nt"&gt;master&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;step&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;Deploy to prod&lt;/span&gt;
          &lt;span class="c1"&gt;# this is the name of the Bitbucket Deployment&lt;/span&gt;
          &lt;span class="nt"&gt;deployment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;Production&lt;/span&gt;
          &lt;span class="nt"&gt;caches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# cache the Ansible installation&lt;/span&gt;
            &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;pip&lt;/span&gt;
          &lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# install Ansible&lt;/span&gt;
            &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;pip install ansible==2.8.0&lt;/span&gt;
            &lt;span class="c1"&gt;# go into the ansible directory&lt;/span&gt;
            &lt;span class="c1"&gt;# in this same repository&lt;/span&gt;
            &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;cd ansible&lt;/span&gt;
            &lt;span class="c1"&gt;# perform the actual deploy&lt;/span&gt;
            &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;ansible-playbook -i ./hosts deploy.yaml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Let&amp;#8217;s examine the configuration line by line:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;On line &lt;strong&gt;2&lt;/strong&gt; you define the docker image you want to use;&lt;/li&gt;
&lt;li&gt;On line &lt;strong&gt;7&lt;/strong&gt; you define the branch that will trigger the deploy (&lt;em&gt;master&lt;/em&gt; in this example);&lt;/li&gt;
&lt;li&gt;On line &lt;strong&gt;11&lt;/strong&gt; 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, &amp;#8230;) 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 &lt;em&gt;Production&lt;/em&gt;) without configuring any variable in this environment;&lt;/li&gt;
&lt;li&gt;On line &lt;strong&gt;14&lt;/strong&gt; 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. The build time for Bitbucket Pipelines is limited to &lt;strong&gt;50 minutes/month in the free plan&lt;/strong&gt;, so it&amp;#8217;s important to have the libraries already installed to save some build/deploy time.&lt;/li&gt;
&lt;li&gt;From line &lt;strong&gt;16&lt;/strong&gt; to line &lt;strong&gt;22&lt;/strong&gt; you define the actual steps for deployment: install Ansible (if not already cached), go into the &lt;em&gt;ansible&lt;/em&gt; directory, make the deploy. Please check the playbook &lt;em&gt;ansible/deploy.yaml&lt;/em&gt; to see what it will actually do on the target server.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ansible will perform the actual deploy by:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pulling the &lt;em&gt;master&lt;/em&gt; branch from your Git repository;&lt;/li&gt;
&lt;li&gt;installing all needed production requirements;&lt;/li&gt;
&lt;li&gt;running Django migrate and collectstatic commands;&lt;/li&gt;
&lt;li&gt;restarting the application server uwsgi.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Please check the Ansible playbook &lt;em&gt;ansible/deploy.yaml&lt;/em&gt; to see what it will actually do on the target server in details.&lt;/p&gt;
&lt;p&gt;Commit and push the &lt;strong&gt;bitbucket-pipelines.yml&lt;/strong&gt; file on the root of your Bitbucket repository.&lt;/p&gt;
&lt;h2 id="setup-your-pipelines"&gt;Setup your pipelines&lt;/h2&gt;
&lt;p&gt;Now go on your repository settings and click &lt;em&gt;Settings&lt;/em&gt; under the section &lt;em&gt;PIPELINES&lt;/em&gt;:&lt;/p&gt;
&lt;div class="d-flex"&gt;
    &lt;figure class="figure mx-auto"&gt;
        &lt;img src="/images/2019/05/thumbnails/800x_/pipelines_settings2.png" class="figure-img img-fluid rounded" alt="Pipelines settings"&gt;
        &lt;figcaption class="figure-caption text-center"&gt;Pipelines settings&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;Now click on &lt;em&gt;Enable Pipelines&lt;/em&gt;:&lt;/p&gt;
&lt;div class="d-flex"&gt;
    &lt;figure class="figure mx-auto"&gt;
        &lt;img src="/images/2019/05/thumbnails/800x_/pipelines_settings3.png" class="figure-img img-fluid rounded" alt="Pipelines settings"&gt;
        &lt;figcaption class="figure-caption text-center"&gt;Pipelines settings&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;If you have read my previous post on &lt;a href="https://www.guguweb.com/2017/05/02/how-to-deploy-a-django-project-in-15-minutes-with-ansible/"&gt;how to deploy a Django project using Ansible&lt;/a&gt;, 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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Go on the settings of your repository, under PIPELINES navigate to SSH keys:&lt;/p&gt;
&lt;div class="d-flex"&gt;
    &lt;figure class="figure mx-auto"&gt;
        &lt;img src="/images/2019/05/thumbnails/800x_/pipelines_settings.png" class="figure-img img-fluid rounded" alt="Pipelines settings"&gt;
        &lt;figcaption class="figure-caption text-center"&gt;Pipelines settings&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;Now click on &amp;#8220;Generate keys&amp;#8221; to let Bitbucket generate a new SSH keypair for you.&lt;/p&gt;
&lt;div class="d-flex"&gt;
    &lt;figure class="figure mx-auto"&gt;
        &lt;img src="/images/2019/05/thumbnails/800x_/pipelines_settings4.png" class="figure-img img-fluid rounded" alt="Pipelines settings"&gt;
        &lt;figcaption class="figure-caption text-center"&gt;Pipelines settings&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;Now you can copy the generated public key and paste it in the &lt;em&gt;.ssh/authorized_keys&lt;/em&gt; file of your deploy target.&lt;/p&gt;
&lt;div class="d-flex"&gt;
    &lt;figure class="figure mx-auto"&gt;
        &lt;img src="/images/2019/05/thumbnails/800x_/pipelines_settings5.png" class="figure-img img-fluid rounded" alt="Pipelines settings"&gt;
        &lt;figcaption class="figure-caption text-center"&gt;Pipelines settings&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;You&amp;#8217;ll also have to add your server fingerprint to the Known hosts section in the same page. Insert your target server hostname in the &amp;#8220;Host address&amp;#8221; field, press the &amp;#8220;Fetch&amp;#8221; button and finally the &amp;#8220;Add host&amp;#8221; button.&lt;/p&gt;
&lt;div class="d-flex"&gt;
    &lt;figure class="figure mx-auto"&gt;
        &lt;img src="/images/2019/09/thumbnails/800x_/bitbucket_known_hosts.png" class="figure-img img-fluid rounded" alt="Known hosts settings"&gt;
        &lt;figcaption class="figure-caption text-center"&gt;Known hosts settings&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;You can refer to the &lt;a href="https://confluence.atlassian.com/bitbucket/use-ssh-keys-in-bitbucket-pipelines-847452940.html"&gt;Bitbucket documentation about SSH keys&lt;/a&gt;, if you need more details.&lt;/p&gt;
&lt;p&gt;You can test that the deploy is working simply by pushing some changes to the &lt;em&gt;master&lt;/em&gt; branch of the repository&lt;/p&gt;
&lt;p&gt;If you want to push some changes on &lt;em&gt;master&lt;/em&gt;, but you &lt;strong&gt;do not want&lt;/strong&gt; to deploy the change automatically on the server, you can put the string &lt;em&gt;[skip-ci]&lt;/em&gt; in your commit message.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In this tutorial I explained a simple yet powerful setup for the continuous delivery of a Django project. This is only a little example of what you can do with Bitbucket Pipelines and Ansible, but I hope that this  helped you to understand the great potential of these technologies.&lt;/p&gt;
&lt;p&gt;I think that learning and implementing this kind of automation in your projects is always worth the effort. Time saved and less human errors in the deploy process will make a big difference in the long run.&lt;/p&gt;</content><category term="sysadmin"></category><category term="ansible"></category><category term="bitbucket"></category><category term="continuous delivery"></category><category term="devops"></category><category term="django"></category><category term="docker"></category><category term="git"></category></entry><entry><title>How to deploy a Django project in 15 minutes with Ansible</title><link href="https://www.guguweb.com/2017/05/02/how-to-deploy-a-django-project-in-15-minutes-with-ansible/" rel="alternate"></link><published>2017-05-02T11:01:47+00:00</published><updated>2022-03-30T14:50:52+02:00</updated><author><name>Augusto Destrero</name></author><id>tag:www.guguweb.com,2017-05-02:/2017/05/02/how-to-deploy-a-django-project-in-15-minutes-with-ansible/</id><summary type="html">&lt;p&gt;In this tutorial I will explain how to deploy a Django project in 15 minutes with Ansible. I will assume that you are a &lt;a href="https://www.djangoproject.com/"&gt;Django&lt;/a&gt; developer and you have built and tested a project locally. It&amp;#8217;s time to deploy the project on a public server to let users access …&lt;/p&gt;</summary><content type="html">&lt;p&gt;In this tutorial I will explain how to deploy a Django project in 15 minutes with Ansible. I will assume that you are a &lt;a href="https://www.djangoproject.com/"&gt;Django&lt;/a&gt; developer and you have built and tested a project locally. It&amp;#8217;s time to deploy the project on a public server to let users access your awesome application.&lt;/p&gt;
&lt;p&gt;If you are new in deploying Django on a production server you can read my post &lt;a href="https://www.guguweb.com/2019/11/13/django-nginx-deploy-your-django-project-on-a-production-server/"&gt;Django – NGINX: deploy your Django project on a production server&lt;/a&gt; to have a basic introduction on the steps needed.&lt;/p&gt;
&lt;p&gt;So you need a VPS with an SSH access, then you will access the server, install and configure all necessary software (web server, application server, database server), create a database user, configure Django to use it, copy your Django project on the server, migrate the database, collect static files, trial and error, fix, trial and error, &amp;#8230;&lt;/p&gt;
&lt;p&gt;All this boring stuff will take some good hours that you should definitely spend in a more profitable way, don&amp;#8217;t you think? The good news is that you can automate almost all the work needed to go from a vanilla VPS to a fully deployed server hosting your Django project.&lt;/p&gt;
&lt;p&gt;Follow this tutorial and I&amp;#8217;ll show you how to leverage the power of &lt;a href="https://www.ansible.com/"&gt;Ansible&lt;/a&gt; to automate all the needed steps in 15 minutes. Are you ready? Check the time on your clock and follow me!&lt;/p&gt;
&lt;div class="toc"&gt;&lt;span class="toctitle"&gt;Table of Contents&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#1-setup-the-ssh-access-to-your-vps"&gt;1. Setup the SSH access to your VPS&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#add-the-vps-address-to-your-ssh-configuration"&gt;Add the VPS address to your SSH configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#configure-ssh-access-without-using-a-password"&gt;Configure SSH access without using a password&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#2-deploy-your-django-project-with-ansible"&gt;2. Deploy your Django project with Ansible&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#clone-the-template-repository"&gt;Clone the template repository&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#django"&gt;django&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#requirements"&gt;requirements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#ansible"&gt;ansible&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#push-your-django-project-in-a-publicly-accessible-git-repository"&gt;Push your Django project in a publicly accessible GIT repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#let-the-ansible-automation-begins"&gt;Let the Ansible automation begins!&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#3-update-your-django-project"&gt;3. Update your Django project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#4-continuous-delivery-using-bitbucket-pipelines"&gt;4. Continuous delivery using Bitbucket Pipelines&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#5-conclusions"&gt;5. Conclusions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="1-setup-the-ssh-access-to-your-vps"&gt;1. Setup the SSH access to your VPS&lt;/h2&gt;
&lt;p&gt;There are plenty of good VPS providers out there, and the choice of the VPS is out of scope of this tutorial.&lt;/p&gt;
&lt;p&gt;If you are looking for a cheap and powerful cloud provider to host your project I highly suggest &lt;a class="aff" href="/r/do"&gt;DigitalOcean.&lt;/a&gt; It is very flexible and powerful, the price is very good for what they offer and you&amp;#8217;ll get no surprises on your billing at the end of the month! Join by using &lt;a class="aff" href="/r/do"&gt;this link&lt;/a&gt; and you&amp;#8217;ll get a &lt;strong&gt;100$ free credit&lt;/strong&gt; to use in 60 days.&lt;/p&gt;
&lt;p&gt;Here I assume that you already bought a Debian/Ubuntu based VPS with a public IP/hostname and root SSH access. I tested the procedure described in this tutorial using Ubuntu server 18.04.&lt;/p&gt;
&lt;h3 id="add-the-vps-address-to-your-ssh-configuration"&gt;Add the VPS address to your SSH configuration&lt;/h3&gt;
&lt;p&gt;If you use OpenSSH client on Linux/UNIX, you can add an entry like this in &lt;em&gt;~/.ssh/config&lt;/em&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Host yourserver
User root
Port 22
HostName yourserver.example.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Pay attention to what you use on &lt;em&gt;Host&lt;/em&gt; value, &lt;em&gt;yourserver&lt;/em&gt; in this example, because this is the label you&amp;#8217;ll use in the following steps to refer to this particular server.&lt;/p&gt;
&lt;p&gt;In &lt;em&gt;HostName&lt;/em&gt; you&amp;#8217;ll configure the actual IP address or hostname of your VPS, according to the access data received by your provider.&lt;/p&gt;
&lt;h3 id="configure-ssh-access-without-using-a-password"&gt;Configure SSH access without using a password&lt;/h3&gt;
&lt;p&gt;To be able to connect to your VPS without using a password, you have to setup a public/private SSH key on your workstation (if you don&amp;#8217;t already have one), this is very simple and can be done with the following command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ssh-keygen
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then you can configure a password-less access to your VPS using the command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ssh-copy-id yourserver
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That&amp;#8217;s it. You should now be able to connect to your VPS using SSH without entering your password every time.&lt;/p&gt;
&lt;h2 id="2-deploy-your-django-project-with-ansible"&gt;2. Deploy your Django project with Ansible&lt;/h2&gt;
&lt;h3 id="clone-the-template-repository"&gt;Clone the template repository&lt;/h3&gt;
&lt;p&gt;I prepared a &lt;a href="https://github.com/baxeico/django_ansible"&gt;template repository&lt;/a&gt; of a Django project, you can clone it at the following address before proceeding:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git clone https://github.com/baxeico/django_ansible.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the repository you&amp;#8217;ll find three directories:&lt;/p&gt;
&lt;h4 id="django"&gt;django&lt;/h4&gt;
&lt;p&gt;This directory is a sample Django project created with the usual:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;django-admin.py startproject yourproject
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I renamed the root directory created by the command to be simply &lt;em&gt;django&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;It is just a bare template not meant to be used as is, but it should give you an idea on how the Django settings are supposed to be structured in this tutorial.&lt;/p&gt;
&lt;p&gt;I always follow a best practice when starting a new Django project, by splitting the monolithic &lt;em&gt;settings.py&lt;/em&gt; file in different files, one for each deploy environment (local, test, production, &amp;#8230;). You can read a more &lt;a href="https://www.coderedcorp.com/blog/django-settings-for-multiple-environments/"&gt;in depth explanation&lt;/a&gt; of this approach if you aren&amp;#8217;t used to it.&lt;/p&gt;
&lt;p&gt;So inside &lt;em&gt;yourproject&lt;/em&gt; sub-directory you&amp;#8217;ll find a &lt;em&gt;settings&lt;/em&gt; package containing different modules for different deploy environments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;base.py&lt;/em&gt; &amp;#8211; This is the common settings which will be inherited (and possibly overridden) from all deploy environments;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;local.py&lt;/em&gt; &amp;#8211; This will be the &lt;em&gt;DJANGO_SETTINGS_MODULE&lt;/em&gt; used in your local development environment. Nothing special here, it only makes Django to use sqlite as DB for local development;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;production.py&lt;/em&gt; &amp;#8211; This will be the &lt;em&gt;DJANGO_SETTINGS_MODULE&lt;/em&gt; used in production. Here you&amp;#8217;ll find that the database used by Django is defined using &lt;a href="https://github.com/kennethreitz/dj-database-url"&gt;dj-database-url&lt;/a&gt; package, by means of an environment variable. Also the &lt;em&gt;STATIC_ROOT&lt;/em&gt; settings variable is defined by means of an environment variable.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="requirements"&gt;requirements&lt;/h4&gt;
&lt;p&gt;This directory contains the minimum Python requirements of your project, you&amp;#8217;ll find three files there:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;base.txt&lt;/em&gt; &amp;#8211; contains the basic requirements for all deploy environment (only Django in the example, it&amp;#8217;s a Django project after all, isn&amp;#8217;t it?);&lt;/li&gt;
&lt;li&gt;&lt;em&gt;local.txt&lt;/em&gt; &amp;#8211; it inherits from &lt;em&gt;base.txt&lt;/em&gt; and adds Ansible as a requirement for your local development environment. Version 2.3.0 is the latest Ansible version at the time of writing;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;production.txt&lt;/em&gt; &amp;#8211; it also inherits from &lt;em&gt;base.txt&lt;/em&gt; and adds &lt;a href="https://github.com/kennethreitz/dj-database-url"&gt;dj-database-url&lt;/a&gt; as a requirement for your production environment. It will be used to configure the database used by Django by means of the environment variable &lt;em&gt;DATABASE_URL&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Notice how this structure mimics the different Django settings modules described above. You can install the local requirements using this command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip install -r requirements/local.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I strongly suggest to use &lt;a href="https://virtualenv.pypa.io/en/stable/"&gt;Virtualenv&lt;/a&gt;, together with &lt;a href="https://virtualenvwrapper.readthedocs.io/en/latest/"&gt;virtualenvwrapper&lt;/a&gt; to create and manage an isolated environment for your project.&lt;/p&gt;
&lt;h4 id="ansible"&gt;ansible&lt;/h4&gt;
&lt;p&gt;In this directory you&amp;#8217;ll find the most interesting part, that is a set of Ansible playbooks to automate the installation and configuration of the server and the deployment of your project.&lt;/p&gt;
&lt;p&gt;I suggest to copy the &lt;em&gt;ansible&lt;/em&gt; directory in your project root, and eventually adapt the playbooks to your needs.&lt;/p&gt;
&lt;p&gt;The first thing to customize is the &lt;em&gt;hosts&lt;/em&gt; file. This is the file where you could list all the hosts controlled by Ansible. In this example you should have only one entry, corresponding to the &lt;em&gt;Host&lt;/em&gt; value you entered in SSH client configuration.&lt;/p&gt;
&lt;p&gt;Then you can proceed to rename the file &lt;em&gt;host_vars/yourserver&lt;/em&gt;, using the label you gave to your server in the &lt;em&gt;hosts&lt;/em&gt; file. Here you&amp;#8217;ll also find some variables used in the playbooks.&lt;/p&gt;
&lt;p&gt;Here is a brief description of each playbook you&amp;#8217;ll find:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;config_files.yaml&lt;/em&gt; &amp;#8211; Copy nginx and uwsgi configuration files on remote server.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;deploy.yaml&lt;/em&gt; &amp;#8211; Deploy your Django project on the server, pulling the master branch from your GIT repository, installing all needed production requirements, running migrate and collectstatic and restarting uwsgi.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;packages.yaml&lt;/em&gt; &amp;#8211; Install needed software packages on remote server using &lt;em&gt;apt&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;postgresql.yaml&lt;/em&gt; &amp;#8211; Create and configure the access to a &lt;a href="https://www.postgresql.org/"&gt;Postgresql&lt;/a&gt; database used by your Django project on remote server. Notice how the database password is randomly generated and stored in the local file &lt;em&gt;postgresqlpasswd&lt;/em&gt;. The password will be automatically inserted in the &lt;em&gt;DATABASE_URL&lt;/em&gt; environment variable, to be used in Django production settings.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;system.yaml&lt;/em&gt; &amp;#8211; Create an user &lt;em&gt;ubuntu&lt;/em&gt; on remote server, together with a private/public SSH key pair. The public key is returned as output when you run the playbook, to be used as a &amp;#8220;deploy key&amp;#8221; on the server. More details later on this step.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;upgrade.yaml&lt;/em&gt; &amp;#8211; Upgrade all &lt;em&gt;apt&lt;/em&gt; packages on remote server.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="push-your-django-project-in-a-publicly-accessible-git-repository"&gt;Push your Django project in a publicly accessible GIT repository&lt;/h3&gt;
&lt;p&gt;Probably you already have your project sources hosted on a public GIT repository like &lt;a href="https://github.com/"&gt;Github&lt;/a&gt; or &lt;a href="https://bitbucket.org/"&gt;Bitbucket&lt;/a&gt;. If you don&amp;#8217;t, this is a perfect time to do it! I personally use Bitbucket, because it offers an unlimited number of private repositories.&lt;/p&gt;
&lt;p&gt;In the following steps I assume that you have your Django project hosted on Bitbucket, under this path:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nl"&gt;ssh&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="nv"&gt;@bitbucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;youruser&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;yourproject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="let-the-ansible-automation-begins"&gt;Let the Ansible automation begins!&lt;/h3&gt;
&lt;p&gt;Inside the &lt;em&gt;ansible&lt;/em&gt; directory, run the following command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;./ansible.sh system.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You should see an output similar to this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ok: &lt;span class="o"&gt;[&lt;/span&gt;yourserver&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&amp;gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;changed&amp;quot;&lt;/span&gt;: false,
    &lt;span class="s2"&gt;&amp;quot;msg&amp;quot;&lt;/span&gt;: &lt;span class="s2"&gt;&amp;quot;ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC1kvkW9... ansible-generated on yourserver.example.com\n&amp;quot;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;What you find in the &lt;em&gt;msg&lt;/em&gt; variable is the public SSH key generated for the &lt;em&gt;ubuntu&lt;/em&gt; user on remote server. You should copy the public key and add it as a &amp;#8220;deploy key&amp;#8221; in the settings of your GIT repository.&lt;/p&gt;
&lt;p&gt;A deploy key is a read-only SSH key that will be used to clone your repository from the remote server. You can find more details in the &lt;a href="https://confluence.atlassian.com/bitbucket/use-access-keys-294486051.html"&gt;Bitbucket&lt;/a&gt; and &lt;a href="https://developer.github.com/guides/managing-deploy-keys/#deploy-keys"&gt;Github&lt;/a&gt; documentation.&lt;/p&gt;
&lt;p&gt;Now you are ready to complete the deploy of your Django project! Run the following commands inside the &lt;em&gt;ansible&lt;/em&gt; directory:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;./ansible.sh packages.yaml
./ansible.sh postgresql.yaml
./ansible.sh config_files.yaml
./ansible.sh deploy.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If all goes well you should be able to reach your Django project on your remote server public address, on port 80.&lt;/p&gt;
&lt;h2 id="3-update-your-django-project"&gt;3. Update your Django project&lt;/h2&gt;
&lt;p&gt;Keeping your Django project updated on the remote server is very easy in this setup. You only need to push your changes to your GIT repository (on the &lt;em&gt;master&lt;/em&gt; branch) and then you can run the following command inside the &lt;em&gt;ansible&lt;/em&gt; directory:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;./ansible.sh deploy.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This playbook will perform the following tasks for you:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pull the updated master branch from your GIT repository;&lt;/li&gt;
&lt;li&gt;eventually install new Python production requirements, and update the existing ones;&lt;/li&gt;
&lt;li&gt;migrate the database to the latest version;&lt;/li&gt;
&lt;li&gt;update your static files with collectstatic;&lt;/li&gt;
&lt;li&gt;restart uwsgi.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="4-continuous-delivery-using-bitbucket-pipelines"&gt;4. Continuous delivery using Bitbucket Pipelines&lt;/h2&gt;
&lt;p&gt;In the follow up article &lt;a href="https://www.guguweb.com/2020/01/03/bitbucket-pipelines-and-ansible-continuous-delivery-for-your-django-project/"&gt;Bitbucket Pipelines and Ansible: Continuous delivery for your Django project&lt;/a&gt; I explained how you can use Ansible together with Bitbucket Pipelines to implement a simple yet powerful continuous delivery setup for your Django project.&lt;/p&gt;
&lt;h2 id="5-conclusions"&gt;5. Conclusions&lt;/h2&gt;
&lt;p&gt;In this article I explained how to deploy a Django project in 15 minutes with Ansible. The key here is in following some Django best practices and leveraging the power on Ansible to quickly deploy a Django project on a remote server. I think that the time spent to learn and master those technologies is worth the effort for the time you&amp;#8217;ll save in the future and all the human errors you&amp;#8217;ll avoid by automating and standardizing your processes.&lt;/p&gt;
&lt;p&gt;Of course this is only the tip of the iceberg of what you could do and automate with Ansible, but I found this simple approach to be already a big time saver in my daily work.&lt;/p&gt;
&lt;p&gt;Have fun with Ansible!&lt;/p&gt;</content><category term="sysadmin"></category><category term="ansible"></category><category term="devops"></category><category term="django"></category><category term="ubuntu"></category></entry></feed>