on master help sign in
tutorial: Deploy a ship to Azure Container Instances
commitc5fd869aca1c8385118567230d9432b10362fd95 authorEdward Amsden <edward@blackriversoft.com> dateWed 20 Jan 2021, 06:58 (6 years ago) parent499160b
2 files changed+184
tutorials/azure-container-instances.md+120 tutorials/urbit-azure.jq+64
tutorials/azure-container-instances.mdnew file+120
@@ -0,0 +1,120 @@
1++++
2+title = "Deploying to an Azure Container Instance"
3+weight = 8
4+template = "doc.html"
5+aliases = ["docs/using/azure-container-instance"]
6++++
7+
8+Urbit can be deployed as a [Docker Image](https://hub.docker.com/r/tloncorp/urbit). Microsoft's [Azure](https://azure.com) hosting service allows docker containers to be deployed without necessitating the management of underlying VM instances.
9+
10+## Initialize your ship
11+
12+When deploying a ship in a container, it is best to boot your ship locally and then copy your pier to the cloud storage which will be volume-mounted. Container-hosting services generally do not provide console access to individual containers.
13+
14+In particular, you will want to run `+code` from your dojo locally before copying your pier to the cloud. Save the provided code, you will use it when signing into your ship's Landscape frontend or running API calls against it.
15+
16+## Warnings
17+
18+- We recommend deploying only moons or comets via this method, unless you are absolutely sure you know what you are doing. Mistakes in the deployment procedure can lead to data loss and/or require a breach.
19+- Landscape will be exposed via *insecure HTTP over the public internet*. Thus, this guide should only be used for experimentation or as a basis for creating more secure deployments, e.g. by deploying nginx with LetsEncrypt as a reverse proxy.
20+
21+## Install `azure-cli` and log in
22+
23+This guide assumes that you are running a recent version of a major Linux distribution.
24+Ensure that the [`azure-cli` package is installed](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) on your machine.
25+
26+Log in to your Azure subscription:
27+
28+```shell
29+az login
30+```
31+
32+This should open a browser window for you to log in to your Azure account and select your subscription.
33+If not, it will print a URL to visit in your browser and a code for you to enter at that URL.
34+Once you have successfully logged in in the browser, the `az login` command should complete in the terminal.
35+
36+## Create a resource group
37+
38+All Azure resources must be part of a resource group. By creating a resource group just for your ship deployment,
39+it will be easy to remove all resources when you are done experimenting or if you decide to migrate
40+your ship elsewhere.
41+
42+```shell
43+URBIT_AZ_RESOURCE_GROUP_NAME=sapmel-palnet-ritpub-sipsyl
44+URBIT_AZ_REGION=eastus # change to whichever Azure region seems best to you
45+az group create -n $URBIT_AZ_RESOURCE_GROUP_NAME -l $URBIT_AZ_REGION
46+```
47+
48+## Create a storage account and file share
49+
50+Azure storage resources share authentication credentials as part of storage accounts. Create a storage account
51+in the resource group we set up in the previous step:
52+
53+```shell
54+URBIT_AZ_STORAGE_ACCOUNT_NAME=sapmelpalnetritpubsipsyl
55+az storage account create \
56+ --resource-group $URBIT_AZ_RESOURCE_GROUP_NAME \
57+ --name $URBIT_AZ_STORAGE_ACCOUNT_NAME \
58+ --location $URBIT_AZ_REGION
59+```
60+
61+Create an Azure file share which will hold your ship's pier and be mounted to the container:
62+
63+```shell
64+URBIT_AZ_SHARE_NAME=sapmel-palnet-ritpub-sipysl
65+az storage share create \
66+ --name $URBIT_AZ_SHARE_NAME \
67+ --account-name $URBIT_AZ_STORAGE_ACCOUNT_NAME
68+```
69+
70+Get the storage key for the storage account and store it in a variable:
71+
72+```shell
73+URBIT_AZ_STORAGE_KEY=$(az storage account keys list --resource-group $URBIT_AZ_RESOURCE_GROUP_NAME --account-name $URBIT_AZ_STORAGE_ACCOUNT_NAME --query "[0].value" --output tsv)
74+```
75+
76+## Copy the urbit ship to the file share
77+
78+The Azure CLI has a convenient command for copying files to a file share:
79+
80+Assuming your pier (the directory containing the data for your ship) is in e.g. `sapmel-palnet-ritpub-sipsyl`:
81+
82+```shell
83+az storage file upload-batch \
84+ --source sapmel-palnet-ritpub-sipsyl \
85+ --destination $URBIT_AZ_SHARE_NAME \
86+ --account-name $URBIT_AZ_STORAGE_ACCOUNT_NAME \
87+ --destination-path sapmel-palnet-ritpub-sipsyl
88+```
89+
90+## Start an ACI container
91+Download the [`urbit-azure.jq`](urbit-azure.jq) JQ filter.
92+We will use this JQ filter to create the YAML description for our ACI deployment.
93+(Recall that YAML is a superset of JSON, so we can use JSON tooling to create valid YAML.)
94+
95+Pass the environment variables from before as arguments to the filter.
96+
97+```shell
98+jq -n -f urbit-azure.jq \
99+ --arg SHIPNAME sapmel-palnet-ritpub-sipsyl \
100+ --arg SHARENAME $URBIT_AZ_SHARE_NAME \
101+ --arg STORAGEACCOUNTNAME $URBIT_AZ_STORAGE_ACCOUNT_NAME \
102+ --arg STORAGEACCOUNTKEY $URBIT_AZ_STORAGE_KEY \
103+ > urbit-azure.yaml
104+```
105+
106+Create an azure container in your resource group using the spec:
107+
108+```shell
109+az container create -g $URBIT_AZ_RESOURCE_GROUP_NAME --file urbit-azure.yaml
110+```
111+
112+## Access your ship
113+
114+Once the `az container create` command finishes, the output will include a public DNS name.
115+Since the container maps your ship's HTTP interface on port 80, you can simply browse to this DNS name in a web browser and authenticate using the code you obtained earlier.
116+
117+**Remember, this is an *insecure* HTTP connection.**
118+
119+## Parting thoughts
120+Setting up an HTTPS proxy for Urbit is beyond the scope of this tutorial, but an easy and standard way to approach the problem would be to configure an [Azure Application Gateway](https://docs.microsoft.com/en-us/azure/application-gateway/) instance in front of your Azure Container Instance runing your Urbit ship, and configure the application gateway for SSL.
tutorials/urbit-azure.jqnew file+64
@@ -0,0 +1,64 @@
1+{
2+ "apiVersion": "2019-12-01",
3+ "location": "eastus",
4+ "name": $SHIPNAME,
5+ "properties": {
6+ "containers": [
7+ {
8+ "name": $SHIPNAME,
9+ "properties": {
10+ "environmentVariables": [],
11+ "image": "tloncorp/urbit:latest",
12+ "ports": [
13+ {
14+ "port": 80
15+ },
16+ {
17+ "port": 34343,
18+ "protocol": "UDP"
19+ }
20+ ],
21+ "resources": {
22+ "requests": {
23+ "cpu": 1,
24+ "memoryInGB": 1.5
25+ }
26+ },
27+ "volumeMounts": [
28+ {
29+ "mountPath": "/urbit",
30+ "name": "piervolume"
31+ }
32+ ]
33+ }
34+ }
35+ ],
36+ "osType": "Linux",
37+ "restartPolicy": "Always",
38+ "ipAddress": {
39+ "type": "Public",
40+ "ports": [
41+ {
42+ "port": 80
43+ },
44+ {
45+ "port": 34343,
46+ "protocol": "UDP"
47+ }
48+ ],
49+ "dnsNameLabel": $SHIPNAME
50+ },
51+ "volumes": [
52+ {
53+ "name": "piervolume",
54+ "azureFile": {
55+ "sharename": $SHARENAME,
56+ "storageAccountName": $STORAGEACCOUNTNAME,
57+ "storageAccountKey": $STORAGEACCOUNTKEY
58+ }
59+ }
60+ ]
61+ },
62+ "tags": {},
63+ "type": "Microsoft.ContainerInstance/containerGroups"
64+}