Skip to content

Getting started

Prerequisites

Django

You need to have an existing Django project. Setting up a Django project is out of scope of this package, refer to the official documentation for that: https://www.djangoproject.com/start/

I do recommend to update your project to use the most recent version as possible. Not only is this best practice overall, due to time constraints I only support the most recent version since that is what I use and thus can properly test.

Pulumi

You need to have Pulumi installed. Pulumi is an Infrastructure as Code library that allows you to define infrastructure in your preferred programming language; in our case Python. If you are not familiar with IaC, now is a great moment to get started with it since it brings you many advantages such as automation, consistency,...

You can refer to the official documentation: https://www.pulumi.com/docs/iac/download-install/

Setup steps

  1. Add pulumi-django-azure to your project. If you are using Poetry, which we recommend this is as simple as:
    poetry add pulumi-django-azure
    
  2. Create a Pulumi stack in your project. We would do this in a directory cicd/pulumi but you are free to do it wherever it suits you. Go to the directory and init a stack:
    cd cicd/pulumi
    pulumi stack init prod
    
    We call our stack "prod" but again you name it as you wish. Note however that in your prod stack, you could still have a production and a test Django deployment. They would share the same database and Application Service Plan (= computing power). More on that and possible alternatives can be found here.
  3. Set up a basic stack. It could look like this:

    import pulumi
    import pulumi_azure_native as azure
    import requests
    from pulumi_django_azure import DjangoDeployment, HostDefinition
    
    stack = pulumi.get_stack()
    config = pulumi.Config()
    
    
    def get_public_ip():
        response = requests.get("https://ipinfo.io/json")
        data = response.json()
        return data["ip"]
    
    
    # Create resource group
    rg = azure.resources.ResourceGroup(f"rg-erp-{stack}")
    
    # Create VNet
    vnet = azure.network.VirtualNetwork(
        f"vnet-erp-{stack}",
        resource_group_name=rg.name,
        address_space=azure.network.AddressSpaceArgs(
            address_prefixes=["10.0.0.0/16"],
        ),
    )
    
    # Deploy the website and all its components
    django = DjangoDeployment(
        "your-application-name",
        tenant_id=config.require("tenant_id"),
        resource_group_name=rg.name,
        vnet=vnet,
        pgsql_sku=azure.dbforpostgresql.SkuArgs(
            name="Standard_B1ms",
            tier=azure.dbforpostgresql.SkuTier.BURSTABLE,
        ),
        pgsql_ip_prefix="10.0.10.0/24",
        pgadmin_access_ip=[f"{get_public_ip()}/32"],
        pgadmin_dns_zone=dns_zone,
        app_service_ip_prefix="10.0.20.0/24",
        app_service_sku=azure.web.SkuDescriptionArgs(
            name="B2",
            tier="Basic",
        ),
        # Note that you can only use alphanumeric characters here, and it should be globally unique on azure.
        storage_account_name="yourapplicationame",
        storage_allowed_origins=[
            "*",
        ],
        cdn_host=HostDefinition(host="cdn.yourapplication.com"),
    )
    
    django.add_django_website(
        name="prod",
        db_name="prod",
        repository_url="git@gitlab.com:yourname/yourapplication.git",
        repository_branch="main",
        website_hosts=[
            HostDefinition(identifier="yourapplication-com", host="yourapplication.com"),
            HostDefinition(identifier="www-yourapplication-com", host="www.yourapplication.com"),
        ],
        django_settings_module="yourapplication.settings.production",
        #
        vault_administrators=["b306adf1-fc61-4a32-8156-ce032dc1571f"],
        comms_data_location="europe",
        comms_domains=[
            HostDefinition(identifier="yourapplication-com", host="yourapplication.com"),
        ],
    )
    
    
    # Add database administrator
    django.add_database_administrator(
        object_id="b306adf5-fc61-4a32-8156-ce032dc1571f",
        user_name="you@yourapplication.com",
    )
    
  4. Add pulumi_django_azure to your Django INSTALLED_APPS

  5. Add to your (production) settings file:
    from pulumi_django_azure.settings import *  # noqa: F403
    
    INSTALLED_APPS += [
         # Collectfasta - must come before django.contrib.staticfiles!
         "collectfasta",
         # Pulumi Django Azure
         "pulumi_django_azure",
         # Django Tasks
         "django_rq",
         "django_tasks",
     ]
    
    # This will provide the health check middleware that will also take care of credential rotation.
    MIDDLEWARE += ["pulumi_django_azure.middleware.HealthCheckMiddleware"]
    
    This will pre-configure most settings to make your app work on Azure. You can check the source for details, and ofcourse override any value after importing them.