Effortlessly Deploy to AKS with Open Source Tools Draft and Acorn
Tags: cloudnative, kubernetes, draft, acorn
Published: 2023-01-03 23:41:50

---
title: Effortlessly Deploy to AKS with Open Source Tools Draft and Acorn
published: true
date: 2023-01-03 23:39:01 UTC
tags: cloudnative, kubernetes, draft, acorn
canonical_url: https://paulyu.dev/article/app-to-aks-with-draft-and-acorn/
---

In this post, I'll walk you through deploying a web application to [Azure Kubernetes Service (AKS)](https://learn.microsoft.com/azure/aks) without having to write any Docker or Kubernetes manifest files.

Using open-source command-line tools [Draft](https://github.com/Azure/draft) and [Acorn](https://docs.acorn.io), we'll containerize and deploy to AKS in just a few steps! Let's go 🚀

## Pre-requisites

Before you begin, make sure you have access to an [Azure Subscription](https://aka.ms/freeazure). You will also need to have the following tools installed on your machine.

- [Azure CLI](https://aka.ms/azure-cli)
- [Git CLI](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
- [Draft CLI](https://github.com/Azure/draft#installation)
- [Acorn CLI](https://docs.acorn.io/installation/installing#acorn-cli)

> If you already have these tools installed, feel free to jump to Step 1.

I ran the commands below from a terminal on macOS. If you are on a Linux or Windows machine, please refer to each tool's documentation page (linked above) for OS-specific installation instructions.

```bash
# Install Azure CLI
brew update && brew install azure-cli

# Install Git CLI
brew install git

# Install Draft CLI
brew tap azure/draft
brew install draft

# Install Acorn CLI
brew install acorn-io/cli/acorn
```

## Step 1: Create an AKS cluster and install Acorn

Creating an AKS cluster can take a few minutes, so let's get the process started.

```bash
# Make sure you are logged into Azure
az login

# Make sure you are working with the proper Azure subscription
az account --set <YOUR_SUBSCRIPTION_NAME>

# Change this to your preferred Azure region
location=westus3

# To avoid any naming conflicts, store a random number which will be used in deployments
rand=$RANDOM

# Create a resource group
az group create --name rg-demoapp$rand \
  --location $location

# Create an AKS cluster
az aks create --name aks-demoapp$rand \
  --resource-group rg-demoapp$rand \
  --enable-addons web_application_routing # <-- this installs a managed nginx ingress controller
```

For this demo, the only requirement is the Kubernetes cluster must have an [ingress controller](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/) for Acorn to expose web applications with publicly accessible endpoints. Rather than installing an ingress controller manually, we'll leverage the [Web Application Routing add-on for AKS](https://learn.microsoft.com/azure/aks/web-app-routing?tabs=without-osm).

> AKS clusters are highly configurable, so I recommend you explore the documentation linked above or visit some of the [OSS Labs](https://aka.ms/oss-labs) repo that I've been contributing to.

With the AKS cluster deployed, you'll need to grab the credentials so we can connect to the cluster using `kubectl` and install Acorn into it.

> If you don't have `kubectl` installed, run the following command to install it.
>
> `az aks install-cli`

Pull down the `kubectl` credentials with the following command.

```bash
az aks get-credentials --name aks-demoapp$rand \
  --resource-group rg-demoapp$rand
```

Verify you have access to the cluster.

```bash
kubectl cluster-info
```

Installing Acorn on the cluster.

```bash
acorn install
```

If you are interested in learning about what gets installed with the command above, visit the [Acorn docs](https://docs.acorn.io/installation/installing) to learn more. If you are familiar with Kubernetes and want to see all the objects that gets created in your cluster, you can run the following command to output the manifest files.

```bash
acorn install -o yaml
```

## Step 2: Package your Acorn app

We need an app to deploy, so clone a version of the **Azure Voting App**, which I've re-written using [Rust](https://www.rust-lang.org/) (I'm learning Rust so be kind 😅).

```bash
git clone --branch postgres https://github.com/pauldotyu/azure-voting-app-rust.git
cd azure-voting-app-rust
```

Acorn will take care of creating your Kubernetes manifest files but it expects that you have a [`Dockerfile`](https://docs.docker.com/engine/reference/builder/) ready to containerize your app. Instead of writing a `Dockerfile` from scratch, we'll use the [Draft CLI](https://github.com/Azure/draft) to generate one for us. Draft is able to detect languages used within your project and generate the appropriate Docker manifest to containerize your app.

> Make sure you are in the `azure-voting-app-rust` directory before running the `draft` command.

```bash
draft create --dockerfile-only
```

You will be prompted to enter the port to expose in the container. Enter `8080` as the port.

```text
[Draft] --- Dockerfile Creation ---
✔ Please Enter the port exposed in the application: 8080
```

Draft may not always produce a perfect `Dockerfile` and may require tweaking. However, it does provide a solid starting point. As an example, if you inspect the newly created `Dockerfile`, you'll notice it's using an older version of Rust (`1.58.0`). Let's update the first line of the `Dockerfile` to use the latest version; which at the time of this writing is `1.64.0`.

```bash
sed -i -e 's/rust:1.58.0/rust:1.64.0/' Dockerfile
```

Now here's the "gotcha"... you don't need to write Kubernetes manifest files to deploy your app. Instead, you will need to create another type of manifest file named `Acornfile`. This file is written in JSON-like syntax, feels very similar to a [Docker Compose](https://docs.docker.com/compose/) or [Helm](https://helm.sh/), and is used to package your application as an Acorn app.

Let's create an `Acornfile` that describes how our application should be deployed to Kubernetes. The `Acornfile` will deploy two containers with environment variables for each; one database container with the password set in plain text, and one web app container with a connection string to the database. It will also expose the web application over HTTP using the Kubnernetes ingress controller that has been deployed in your cluster.

> The password is in plain text for demo purposes but you should take a look at Acorn's [secrets management system](https://www.acorn.io/unlocking-acorns-native-secret-management/).

```bash
cat << EOF > Acornfile
containers: db: {
  image: "postgres:15.0-alpine"
  env: {
    "POSTGRES_PASSWORD": "mypassword"
  }
  ports: "5432/tcp"
}
containers: web: {
  build: "."
  env: {
    "DATABASE_URL": "postgres://postgres:mypassword@db"
  }
  ports: publish: "8080/http"
  dependsOn: ["db"]
}
EOF
```

> The full reference for `Acornfile` schema can be found [here](https://docs.acorn.io/reference/acornfile)

## Step 3: Deploy the Acorn app to AKS

Now, you could run the [`acorn run` command](https://docs.acorn.io/getting-started#step-4-run-your-acorn-app) and have Acorn build your container and deploy to AKS at the same time. Instead, we'll publish the Acorn app artifacts to [Azure Container Registry (ACR)](https://learn.microsoft.com/azure/container-registry) and deploy it from there.

If you do not have an ACR resource yet, create one using the following command.

```bash
az acr create --name acrdemoapp$rand \
  --resource-group rg-demoapp$rand \
  --sku Standard \
  --admin-enabled
```

Log into the container registry by grabbing the admin credentials and passing it into the `acorn login` command.

```bash
az acr credential show --name acrdemoapp$rand --query "passwords[0].value" -o tsv | acorn login acrdemoapp$rand.azurecr.io -u acrdemoapp$rand --password-stdin
```

Build the Acorn artifact.

```bash
acorn build -t acrdemoapp$rand.azurecr.io/azure-vote:v0.1 .
```

Push the Acorn artifact to ACR.

```bash
acorn push acrdemoapp$rand.azurecr.io/azure-vote:v0.1
```

Deploy the Acorn app to AKS and wait for the endpoints to become healthy.

```bash
acorn run --name azure-vote-$rand acrdemoapp$rand.azurecr.io/azure-vote:v0.1
```

You can also run the following command to view the status of the app. Once the app is fully deployed you will be able to navigate to the endpoint URL listed. Below is an example of what the output should look like.

```bash
$ acorn apps
NAME               IMAGE                                        HEALTHY   UP-TO-DATE   CREATED   ENDPOINTS                                                                       MESSAGE
azure-vote-10981   acrdemoapp10981.azurecr.io/azure-vote:v0.1   2         2            78s ago   http://web-azure-vote-10981-d70891c5f27d.v9lov9.alpha.on-acorn.io => web:8080   OK
```

Finally, you can browse to the endpoint URL and submit your vote!

## Summary

Overall, I think the Draft and Acorn projects are awesome tools to get developers up and running as quick as possible on Kubernetes.

One of the initial hurdles developers face when considering Kubernetes as a hosting platform is knowing how to package their applications into containers. Learning how to author a `Dockerfile` can be a challenge but with Draft CLI, you can automate most of this. Draft does more than just create Docker manifests... it can also create Kubernetes manifests, Helm charts, GitHub automation workflows, and publish your containers to Azure Container Registry. There is also an [extension for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=ms-kubernetes-tools.aks-devx-tools) that will provide a graphical user interface for some of the `draft` CLI commands.

When it comes to Kubernetes, the Acorn packaging framework aims to abstract much of Kubernetes away from you. Granted you will need to become familiar with the `Acornfile` schema and [`acorn` CLI commands](https://docs.acorn.io/reference/command-line/acorn) but it may be a more approachable way to onboarding and operating your apps on any Kubernetes cluster.

Lastly, with the AKS Web Application Routing add-on, even ingress controller installation and management can be abstracted away from you as Azure will take care of this.

I'd love to hear how this approach to onboarding to Kubernetes and/or AKS works for you. If you have any feedback or questions, feel free to let me know in the comments below or on social channels ([Twitter](https://twitter.com/pauldotyu), [Mastodon](https://hachyderm.io/@paul), or [Linkedin](https://www.linkedin.com/in/yupaul/)). Cheers!

## Clean up

When you're done testing, you should tear down the deployment using the following commands.

```bash
# Stop and remove the Acorn app deployment
acorn rm $(acorn apps -qa)

# Delete the Azure resources
az group delete --name rg-demoapp$rand -y --no-wait
```

## Resources

- [Draft](https://github.com/Azure/draft)
- [Acorn](https://docs.acorn.io/)
- [Azure Kubernetes Service](https://learn.microsoft.com/azure/aks)
- [Web Application Routing add-on for AKS](https://learn.microsoft.com/azure/aks/web-app-routing?tabs=without-osm)
- [Azure Container Registry](https://learn.microsoft.com/azure/container-registry)
- [Azure Open-Source Labs](https://aka.ms/oss-labs)