{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.5.7.13",
  "metadata": {
    "comments": "ArgonDB v1.5.7.13 on one Azure VM, installed from the PUBLISHED Linux tarball at https://releases.argondb.ai. No container image and no registry credential. The customData below is GENERATED: variables.cloudConfig is the canonical cloud-config from deploy/cloud-oneclick/lib/user-data-tool.py and the identical bytes appear in aws/argondb-vm.cfn.yaml. Edit user-data/argondb-bootstrap.sh, then run ./sync-user-data.sh --write; ./sync-user-data.sh --check refuses drift. SECURITY POSTURE: the box binds 127.0.0.1 by default (crates/argondb-ctl/src/serve.rs:5997, resolve_bind, re-read at the v1.5.7.13 cut sha), so this NSG opens only SSH and the recommended connect route is an SSH tunnel. databaseAllowedCidr is the deliberate deployer-supplied exception; it opens 5432/8018/8019 to that CIDR alone. The MCP admin (8020) and write (8017) surfaces stay loopback in every case \u2014 each has its own loopback-unless-configured variable, so a 0.0.0.0 global listen reaches neither the control plane nor the write plane (crates/argondb-mcp/src/lib.rs:6307, resolve_surface_listen); that is why v1.4.0's argondb-write door adds no rule to this NSG. Every credential is generated on the VM and no output carries one. SINCE v1.5.5 (docs/releases/v1.5.5.md, section 18): with the bind widened by databaseAllowedCidr AND [compute] idle_stop on, an off-box client is now asked for a password where v1.5.0-v1.5.4 served it as a loopback client; this template leaves idle_stop off, so the default posture was never exposed either way. V1.5.7.13 AND DATA ON DISK: this template always creates a NEW VM on a NEW managed OS disk, so there is no prior data directory: NEITHER of the box's two refusals over old data is reachable here, and the one-time uuid re-derive (docs/releases/v1.5.4.md, v1.5.3 section 16, carried forward through v1.5.7.13) finds nothing to re-derive. All three ARE reachable if you later attach a RESTORED disk. A v1.3.x lake store: v1.4.0 changed the on-disk layout, so run 'argondb lake-store migrate' first (docs/releases/v1.4.0.md, 'Upgrading'); no release since has changed that layout. A v1.4.x LAKE: since v1.5.0 a lake table is named by database/schema/table and the box refuses to start its tail over old flat-named tables, printing 'LAKE IDENTITY GATE - REFUSED' and leaving Postgres and the lake plane up as the migration window; run 'argondb lake migrate-identity' (a catalog-only move; docs/releases/v1.5.4.md, 'Upgrading from v1.4.x'). A v1.5.0-v1.5.2 LAKE holding a table with a uuid column: the first v1.5.4-or-later tail start re-derives that table once, at the current position, and its snapshot history below that point is gone. v1.5.5 through v1.5.7.13 add no lake schema change and no migration a one-database box needs: 'argondb estate migrate' (v1.5.6) versions ArgonDB's own per-company schema inside tenant databases, and the v1.5.7 boot migration of a publication's consent tables (docs/releases/v1.5.7.md, section 1) finds no publication here; upgrading a box is replacing the binaries. WHAT v1.5.6 THROUGH v1.5.7.13 CHANGE ON THIS VM (docs/releases/v1.5.6.md, v1.5.6.1.md, v1.5.7.md, v1.5.7.1.md, v1.5.7.2.md, v1.5.7.3.md and the v1.5.7.4 to v1.5.7.13 notes; v1.5.6 and v1.5.6.1 never shipped on this channel; a VM from the previous template ran v1.5.7.3, from the three before it v1.5.7.2, v1.5.7.1 and v1.5.7, and from the one before those v1.5.5). None of it opens a port here. (1) The shipped extension set, the glibc floor (2.43) and the eight host libraries are as at v1.5.5: pgvector and the HTAP offload hook still do not ship. (2) The pooler key is 'on', 'auto' or 'off', and a missing PgBouncer never refuses a boot (v1.5.6 section 10): the artifact's install.sh writes [pooler] enabled = 'on' as a record of intent, this template installs no pgbouncer, and the box boots on the direct port (5432) saying so; install PgBouncer 1.25.2 or newer from the PostgreSQL apt repository and restart the box to get the pooled port (5632). (3) A fresh 'argondb tenant create' and a default 'argondb estate migrate' FINISH on v1.5.7 (v1.5.6.1 section 1, in this release from main); on v1.5.6 both refused. (4) A tenant key holding an underscore is REFUSED AT THE DOOR (v1.5.7 section 10): on v1.5.6 and v1.5.6.1 such a key took a lake box off the air at its next boot; a box that already holds one now boots with that database dark instead of down, and 'argondb destroy-tenant' is the remedy. (5) Every company gets its own MCP token scoped to its own database (v1.5.6 section 3), and on v1.5.7 that token reads the company's own derived schema (section 8). (6) Sharing between tenants as data -- a publication names its grantees, lands by replace, merge or append, a cross-party mount needs the requester's accept, a continuous view lands as one slice per grantee (v1.5.7 sections 1-5) -- and the catalog-authz 'takes effect at next boot' notice (section 13) are reachable only after you create a second database or publish a table. (7) [compute] per_tenant stays off by default; with it on, per-tenant compute has no count cap on Linux (section 7; the notes say an AWS/Azure approach to uncapped per-tenant compute is not designed), a sleeping company's application port answers 503 with a Retry-After (section 11), and there is no tenant move (section 9). (8) STOP THE BOX CLEANLY: v1.5.5 section 19 stated that an unclean stop of the catalog's PostgreSQL -- a kill, a power loss -- leaves a box that does not boot again until its catalog data directory is repaired by hand; v1.5.6 through v1.5.7.13 neither fix it nor restate it, so treat it as standing. 'systemctl stop argondb-box' sends TERM to 'argondb serve' with a 180 s stop timeout; whether every stop path through the autoShutdownTime schedule or a portal stop reaches the catalog's clean stop is NOT proven by this template's rehearsal, so prefer 'argondb stop' on the VM before a scheduled (autoShutdownTime) or portal stop on a box that holds data you cannot recreate. (9) v1.5.7.1 (docs/releases/v1.5.7.1.md, section 1): a box that has run 'argondb tenant create' comes back from a restart. On v1.5.7 the box's argondb-tail bound the FIRST timeline the pageserver listed rather than the box primary's, and 'tenant create' cuts a timeline on this one-database VM too (per_tenant off or not), so a restart after 'tenant create' could refuse the boot ('QUARANTINED postgres__argon_estate__system at boot', 'argondb-tail exited before it bound Flight ... refusing the boot'); the aws/azure v1.5.7 channel notes carry it as an ERRATA. 'argondb serve' now names the primary's timeline to the tail, which binds exactly that one and names every other as a tenant's or ORPHAN without streaming it; 'argondb tenant delete <key>' removes a tenant whole (rows, database, timeline, directory), and a hand 'DROP DATABASE' is not a supported way to remove a tenant. (10) v1.5.7.2 (docs/releases/v1.5.7.2.md, section 1), the one product change of that fix release: a tenant on its own compute does its own lake work. With [compute] per_tenant = true the box spawns one argondb-tail beside each tenant compute, bound to that tenant's timeline, with the tenant's own lake paths and watermarks; the box tail serves only the box primary. No separate switch: this is what [compute] per_tenant = true means. A tenant's tail stops and wakes with its compute; while the tenant sleeps its lake does not advance, and the first query after wake pays the catch-up. On v1.5.7 and v1.5.7.1 such a tenant had no tail of its own and rows written through its compute never landed in its lake. This VM runs ONE database with per_tenant off, so nothing changes on it unless you turn per_tenant on in /var/lib/argondb/argon.toml; a tenant created under per_tenant on v1.5.7 or v1.5.7.1 gains its tail on the first v1.5.7.2 boot. (11) v1.5.7.3 (docs/releases/v1.5.7.3.md, section 1), the one product change of that fix release: deleting a tenant that publishes a continuous view no longer breaks the box. On v1.5.7.1 and v1.5.7.2, 'argondb tenant delete' of such a tenant while its publication was in force left the dead publisher's view grant in the cross-tenant reader's roster (reader.views in /var/lib/argondb/lake-store-credentials.json), and every later 'argondb tenant create', tenant-wall pass and 'publication land' panicked ('index out of bounds: the len is N but the index is N', crates/argondb-query/src/lib.rs:496). v1.5.7.3 keeps the pin's roster and handles as one list, skips by name a granted view it cannot look up, and has 'tenant delete' and the tenant-wall pass remove a dead owner's grants and print them by name. This VM runs ONE database, so the defect is reachable only after you create tenants and publish a view. A VM already running v1.5.7.2 was NOT upgraded by that template: replace its binaries with the v1.5.7.13 artifact's install.sh before restarting it; after the upgrade the first tenant-wall pass removes a dead publisher's grant by name and logs it, no hand edit needed; until then, revoke a tenant's view publications before deleting the tenant. A deleted tenant's lake data is still not removed. Nothing else changed: v1.5.7.3 is the v1.5.7.2 tag plus that fix, and the shipped guides are the v1.5.7 tag's own. (12) v1.5.7.4 THROUGH v1.5.7.13 (ten Linux cuts; the first aws/azure template since v1.5.7.3 is this one, so a VM from the previous template ran v1.5.7.3): the notes are served at releases.argondb.ai/linux/<version>/RELEASE-NOTES.md (v1.5.7.4 to v1.5.7.10 also in docs/releases/), and the channel notes docs/releases/aws-v1.5.7.13.md and azure-v1.5.7.13.md list what reaches this VM. None of it opens a port here, none changes the first boot of a one-database VM, no catalog or lake migration runs, and every new configuration key ships default-off (v1.5.7.4 section 7: [storage] remote WAL backup, [storage] sole_owner, [lake] scheme = azure). The one install-time difference: the artifact's install.sh now PRINTS one optional root step at its end, 'argondb box install-useradd-helper --user argondb' (v1.5.7.4 section 4.9), needed only by a box that runs multi-tenant sidecars; this template does not take it, and a one-database VM does not need it. The ArgonDBCloud crates in the source tree are not in the artifact (v1.5.7.13 section 5). THE CATALOG LOGIN (unchanged since v1.5.4): the box turns its Iceberg catalog login ON by default once it holds more than one database, and the policy engine it needs (bin/openfga, OpenFGA v1.14.2, unchanged from v1.5.4) is IN the tarball this template installs. The VM this template creates holds ONE database, so its catalog boots open, by design; the first boot after you create a second database walls it, with nothing to install and no new port opened here (docs/releases/v1.5.4.md, v1.5.3 section 13, and sections 5 and 6 of v1.5.4; carried forward through v1.5.7.13); none of that is reachable on the one-database VM this template creates. THE TAIL'S MEMORY BOUND (v1.5.4, section 11; unchanged since v1.5.5, whose section 4 retires only the gate's positive control, not the bound): the box places argondb-tail in a 6 GiB kernel cgroup cap where it can write the cgroup tree, and prints UNCAPPED with a WARNING where it cannot. The kernel cap has NOT been measured under load; at the cap the kernel kills the tail and the supervisor respawns it from its resume point. v1.5.3's 'plan at least 24 GiB of headroom for the tail' limit stays WITHDRAWN."
  },
  "parameters": {
    "adminUsername": {
      "type": "string",
      "defaultValue": "azureuser",
      "metadata": {
        "description": "Login name for SSH on the VM."
      }
    },
    "adminPublicKey": {
      "type": "string",
      "metadata": {
        "description": "Your SSH PUBLIC key (contents of ~/.ssh/id_ed25519.pub). Password login is disabled; SSH is the only way in, and the only way to the database."
      }
    },
    "sshAllowedCidr": {
      "type": "string",
      "metadata": {
        "description": "CIDR allowed to reach SSH (port 22). No default on purpose: put your own address here (whatismyip, then /32), not 0.0.0.0/0."
      }
    },
    "databaseAllowedCidr": {
      "type": "string",
      "defaultValue": "",
      "metadata": {
        "description": "LEAVE EMPTY unless you know you need it. Empty (the default) keeps PostgreSQL and the agent endpoints bound to loopback, reachable only through an SSH tunnel. Supplying a CIDR binds them to all interfaces and opens 5432/8018/8019 to that CIDR."
      }
    },
    "vmSize": {
      "type": "string",
      "defaultValue": "Standard_D2as_v5",
      "allowedValues": [
        "Standard_D2as_v5",
        "Standard_D4as_v5",
        "Standard_D2s_v5",
        "Standard_D4s_v5",
        "Standard_B2ms"
      ],
      "metadata": {
        "description": "8 GiB RAM minimum. Standard_D2as_v5 is 2 vCPU / 8 GiB."
      }
    },
    "osDiskSizeGb": {
      "type": "int",
      "defaultValue": 64,
      "minValue": 40,
      "maxValue": 1024,
      "metadata": {
        "description": "OS disk, GiB. The artifact's install.sh REFUSES below 20 GiB free, and the 451 MB download plus the unpacked tree plus the installed prefix are all paid before the box holds any data."
      }
    },
    "imageOffer": {
      "type": "string",
      "defaultValue": "ubuntu-26_04-lts",
      "metadata": {
        "description": "Canonical marketplace offer for Ubuntu 26.04 LTS. Ubuntu 26.04 is REQUIRED: the artifact's glibc floor is 2.43 and 24.04 (2.39) is refused by install.sh. Editable here if Canonical's offer name differs in your cloud."
      }
    },
    "imageSku": {
      "type": "string",
      "defaultValue": "server",
      "metadata": {
        "description": "Canonical image SKU (server, or server-gen1 for a generation-1 VM size). Editable here if the URN differs in your cloud."
      }
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "Region. Defaults to the resource group's."
      }
    },
    "autoShutdownTime": {
      "type": "string",
      "defaultValue": "",
      "metadata": {
        "description": "OPT-IN, and NOT idle-based: Azure has no idle-based stop for a bare VM, only a time-of-day schedule -- the same 'Auto-shutdown' feature the portal exposes per VM (Microsoft.DevTestLab/schedules under the hood). It is also NOT ArgonDB's own [compute] idle_stop (new in v1.4.0, off by default and not enabled here), which stops only the primary PostgreSQL inside a RUNNING box and wakes it on the next connection. This is also NOT scale-to-zero: nothing wakes the VM on a connection, and only 'az vm start' (see ../README.md, Sizing and cost) brings it back. LEAVE EMPTY (the default) for never. A nonzero value is a 24-hour clock time, HHmm (e.g. 1900 for 7pm), in autoShutdownTimeZone. The OS disk is a managed disk, not ephemeral, so it and /var/lib/argondb survive the stop."
      }
    },
    "autoShutdownTimeZone": {
      "type": "string",
      "defaultValue": "UTC",
      "metadata": {
        "description": "Windows time zone ID for autoShutdownTime (e.g. UTC, Pacific Standard Time, Eastern Standard Time). Ignored when autoShutdownTime is empty."
      }
    }
  },
  "variables": {
    "prefix": "[concat('argondb-', uniqueString(resourceGroup().id))]",
    "vnetName": "[concat(variables('prefix'), '-vnet')]",
    "subnetName": "box",
    "nsgName": "[concat(variables('prefix'), '-nsg')]",
    "pipName": "[concat(variables('prefix'), '-pip')]",
    "nicName": "[concat(variables('prefix'), '-nic')]",
    "vmName": "[concat(variables('prefix'), '-vm')]",
    "subnetId": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vnetName'), variables('subnetName'))]",
    "sshRule": [
      {
        "name": "ssh",
        "properties": {
          "description": "SSH - the recommended route to the database is a tunnel over this",
          "protocol": "Tcp",
          "sourcePortRange": "*",
          "destinationPortRange": "22",
          "sourceAddressPrefix": "[parameters('sshAllowedCidr')]",
          "destinationAddressPrefix": "*",
          "access": "Allow",
          "priority": 1000,
          "direction": "Inbound"
        }
      }
    ],
    "databaseRules": [
      {
        "name": "postgresql",
        "properties": {
          "description": "PostgreSQL wire protocol, deployer-supplied CIDR only",
          "protocol": "Tcp",
          "sourcePortRange": "*",
          "destinationPortRange": "5432",
          "sourceAddressPrefix": "[parameters('databaseAllowedCidr')]",
          "destinationAddressPrefix": "*",
          "access": "Allow",
          "priority": 1010,
          "direction": "Inbound"
        }
      },
      {
        "name": "mcp-analyst",
        "properties": {
          "description": "MCP analyst surface, bearer token required",
          "protocol": "Tcp",
          "sourcePortRange": "*",
          "destinationPortRange": "8018",
          "sourceAddressPrefix": "[parameters('databaseAllowedCidr')]",
          "destinationAddressPrefix": "*",
          "access": "Allow",
          "priority": 1020,
          "direction": "Inbound"
        }
      },
      {
        "name": "mcp-dba",
        "properties": {
          "description": "MCP DBA surface, bearer token required",
          "protocol": "Tcp",
          "sourcePortRange": "*",
          "destinationPortRange": "8019",
          "sourceAddressPrefix": "[parameters('databaseAllowedCidr')]",
          "destinationAddressPrefix": "*",
          "access": "Allow",
          "priority": 1030,
          "direction": "Inbound"
        }
      }
    ],
    "securityRules": "[if(empty(parameters('databaseAllowedCidr')), variables('sshRule'), concat(variables('sshRule'), variables('databaseRules')))]",
    "cloudConfig": "#cloud-config\nwrite_files:\n  - path: /etc/argondb/bootstrap.env\n    owner: root:root\n    permissions: '0644'\n    content: |\n      ARGONDB_VM_DB_CIDR=__DB_CIDR__\n  - path: /usr/local/sbin/argondb-bootstrap.sh\n    owner: root:root\n    permissions: '0755'\n    encoding: b64\n    content: IyEvdXNyL2Jpbi9lbnYgYmFzaAojIGFyZ29uZGItYm9vdHN0cmFwLnNoIOKAlCBib290IE9ORSBBcmdvbkRCIHYxLjUuNy4xMyBib3ggb24gYSBmcmVzaCBVYnVudHUgMjYuMDQgVk0KIyBmcm9tIHRoZSBQVUJMSVNIRUQgcmVsZWFzZSB0YXJiYWxsLiBSdW5zIGFzIHJvb3QgZnJvbSBjbG91ZC1pbml0IGBydW5jbWRgLgojCiMgVEhFIE9ORSBQQVlMT0FEOiBieXRlLWlkZW50aWNhbCBpbiBhd3MvYXJnb25kYi12bS5jZm4ueWFtbCBhbmQKIyBhenVyZS9henVyZWRlcGxveS5qc29uIChib3RoIGVtYmVkIGJhc2U2NCBvZiBUSElTIGZpbGUpLiBzeW5jLXVzZXItZGF0YS5zaAojIHJlbmRlcnMgaXQgaW50byBib3RoIGFuZCAtLWNoZWNrIHByb3ZlcyB0aGV5IHN0aWxsIG1hdGNoLiBPbmUgcHJlZGljYXRlLCB0d28KIyBjYWxsZXJzLiBFdmVyeXRoaW5nIGNsb3VkLXNwZWNpZmljIGFycml2ZXMgaW4gL2V0Yy9hcmdvbmRiL2Jvb3RzdHJhcC5lbnYsCiMgd3JpdHRlbiBieSB0aGUgdGVtcGxhdGUgYmVmb3JlIHRoaXMgcnVuczsgdGhpcyBmaWxlIHRha2VzIG5vIHBhcmFtZXRlcnMuCiMKIyBCWVRFUyBDT1NUOiBFQzIgdXNlci1kYXRhIGlzIGNhcHBlZCBhdCAxNjM4NCBieXRlcyByYXcgYW5kIHRoaXMgc2NyaXB0IGlzIHRoZQojIGJ1bGsgb2YgaXQgKHN5bmMtdXNlci1kYXRhLnNoIGFzc2VydHMgdGhlIHJlbmRlcmVkIHNpemUsIGJvdGggY2xvdWRzKS4KIyBDb21tZW50cyBoZXJlIGNhcnJ5IGEgcnVsZSBvciBhIGNpdGF0aW9uOyBuYXJyYXRpdmUgbGl2ZXMgaW4gLi4vUkVBRE1FLm1kLgpzZXQgLXVvIHBpcGVmYWlsCgpWRVJTSU9OPSIxLjUuNy4xMyIKVEFSQkFMTD0iYXJnb25kYi0xLjUuNy4xMy1saW51eC14ODZfNjQudGFyLnpzdCIKVVJMPSJodHRwczovL3JlbGVhc2VzLmFyZ29uZGIuYWkvbGludXgvdjEuNS43LjEzLyR7VEFSQkFMTH0iCiMgcmVsZWFzZXMuYXJnb25kYi5haS9saW51eC92MS41LjcuMTMvUkVMRUFTRS1OT1RFUy5tZCwgIkJ1aWxkIGZhY3RzIi4gQSBNSVNNQVRDSCBJUyBGQVRBTDogdGhpcyBpcyB0aGUgb25seQojIHRoaW5nIGJldHdlZW4gdGhlIFZNIGFuZCBhIHN1YnN0aXR1dGVkIGFydGlmYWN0LgpTSEEyNTY9IjFlNTMyMWIwZGRiOTEzYzNkNjhmM2EwZmE1NzNlODEwMWVhNzBkNDJhMjMwMGI5ZWMyMWFkNGQwYmE4YzBiNjIiClBSRUZJWD0iL29wdC9hcmdvbmRiIjsgREFUQT0iL3Zhci9saWIvYXJnb25kYiI7IFNSQ0RJUj0iL29wdC9hcmdvbmRiLXNyYyIKRVRDPSIvZXRjL2FyZ29uZGIiOyBVTklUPSIvZXRjL3N5c3RlbWQvc3lzdGVtL2FyZ29uZGItYm94LnNlcnZpY2UiCgpzYXkoKSB7IGVjaG8gIj09PSBhcmdvbmRiLWJvb3RzdHJhcDogJCogPT09IjsgfQpkaWUoKSB7IGVjaG8gImFyZ29uZGItYm9vdHN0cmFwOiBGQVRBTDogJCoiID4mMjsgbWtkaXIgLXAgIiRFVEMiOyBlY2hvICIkKiIgPiIkRVRDL2Jvb3RzdHJhcC1mYWlsZWQiOyBleGl0IDE7IH0KClsgIiQoaWQgLXUpIiA9ICIwIiBdIHx8IGRpZSAibXVzdCBydW4gYXMgcm9vdCIKc2F5ICJBcmdvbkRCICRWRVJTSU9OIGJvb3RzdHJhcCBvbiAkKHVuYW1lIC1tKSwgJChkYXRlIC11ICslRlQlVFopIgoKbWtkaXIgLXAgIiRFVEMiCiMgQVJHT05EQl9WTV9EQl9DSURSIG5vbi1lbXB0eSDih5IgdGhlIGRlcGxveWVyIGFza2VkIGZvciB0aGUgZGF0YWJhc2UvYWdlbnQKIyBwb3J0cyB0byBiZSByZWFjaGFibGUgZnJvbSB0aGF0IENJRFIsIHdoaWNoIHRoZSB0ZW1wbGF0ZSBoYXMgYWxyZWFkeSBvcGVuZWQKIyBpbiBpdHMgc2VjdXJpdHkgZ3JvdXAgLyBOU0cuIEVtcHR5ICh0aGUgZGVmYXVsdCkg4oeSIGxvb3BiYWNrIG9ubHkuCkFSR09OREJfVk1fREJfQ0lEUj0iIgpbIC1yICIkRVRDL2Jvb3RzdHJhcC5lbnYiIF0gJiYgLiAiJEVUQy9ib290c3RyYXAuZW52IgoKc2F5ICJsZWcgMS83IHByZWZsaWdodCIKWyAiJCh1bmFtZSAtbSkiID0gIng4Nl82NCIgXSB8fCBkaWUgInRoZSB2JFZFUlNJT04gYXJ0aWZhY3QgaXMgeDg2XzY0LW9ubHk7IHRoaXMgaG9zdCBpcyAkKHVuYW1lIC1tKSIKIyBnbGliYyBmbG9vciAyLjQzIChyZWxlYXNlcy5hcmdvbmRiLmFpL2xpbnV4L3YxLjUuNy4xMy9SRUxFQVNFLU5PVEVTLm1kKS4gaW5zdGFsbC5zaCByZWZ1c2VzIGJlbG93IGl0IHRvbzsKIyByZWZ1c2luZyBIRVJFIG5hbWVzIHRoZSBjYXVzZSBiZWZvcmUgNDgzIE1CIGlzIGRvd25sb2FkZWQuCmhhdmU9IiQobGRkIC0tdmVyc2lvbiAyPi9kZXYvbnVsbCB8IHNlZCAtbiAnMXMvLipbWzpzcGFjZTpdXVwoWzAtOV1cK1wuWzAtOV1cK1wpJC9cMS9wJykiClsgLW4gIiRoYXZlIiBdIHx8IGRpZSAiY291bGQgbm90IHJlYWQgdGhpcyBob3N0J3MgZ2xpYmMgZnJvbSAnbGRkIC0tdmVyc2lvbiciCmxvdz0iJChwcmludGYgJzIuNDNcbiVzXG4nICIkaGF2ZSIgfCBzb3J0IC1WIHwgaGVhZCAtMSkiClsgIiRoYXZlIiA9ICIyLjQzIiBdIHx8IFsgIiRsb3ciID0gIjIuNDMiIF0gfHwgXAogIGRpZSAiQXJnb25EQiAkVkVSU0lPTiBuZWVkcyBnbGliYyA+PSAyLjQzOyBob3N0IGhhcyAkaGF2ZSAoVWJ1bnR1IDI2LjA0IHJlcXVpcmVkOyAyNC4wNCBoYXMgMi4zOSkiCmVjaG8gImdsaWJjOiBmbG9vciAyLjQzLCBob3N0ICRoYXZlIOKAlCBPSyIKCnNheSAibGVnIDIvNyBwYWNrYWdlcyIKZXhwb3J0IERFQklBTl9GUk9OVEVORD1ub25pbnRlcmFjdGl2ZQojIERQa2c6OkxvY2s6OlRpbWVvdXQg4oCUIGEgZmlyc3QtYm9vdCBydW5jbWQgcmFjZXMgdW5hdHRlbmRlZC11cGdyYWRlcyBmb3IgdGhlCiMgZHBrZyBsb2NrLiBXYWl0aW5nIGlzIHRoZSBmaXgsIG5vdCBhIHJldHJ5IGxvb3AuCkE9Ii1vIERQa2c6OkxvY2s6OlRpbWVvdXQ9NjAwIgphcHQtZ2V0ICRBIHVwZGF0ZSAtcXEgfHwgZGllICJhcHQtZ2V0IHVwZGF0ZSBmYWlsZWQiCiMgenN0ZCB1bnBhY2tzIHRoZSBhcnRpZmFjdDsgYmludXRpbHMgc3VwcGxpZXMgcmVhZGVsZiwgd2hpY2ggaW5zdGFsbC5zaCdzCiMgcmVsb2NhdGlvbiBjaGVjayByZXF1aXJlcyBieSBuYW1lOyBjdXJsIGZldGNoZXMgaXQuCmFwdC1nZXQgJEEgaW5zdGFsbCAteSAtcXEgenN0ZCBiaW51dGlscyBjdXJsIGNhLWNlcnRpZmljYXRlcyB8fCBkaWUgImFwdC1nZXQgaW5zdGFsbCBmYWlsZWQiCiMgUlVOVElNRSBMSUJSQVJJRVMgdGhlIGFydGlmYWN0IGxpbmtzIGJ1dCBkb2VzIG5vdCBidW5kbGU6IElDVSAodGhlIHNoaXBwZWQKIyBwb3N0Z3JlcykgYW5kIHJlYWRsaW5lICh0aGUgc2hpcHBlZCBwc3FsKS4gVGhlIFVidW50dSBTZXJ2ZXIgMjYuMDQgY2xvdWQKIyBpbWFnZSBhbHJlYWR5IGNhcnJpZXMgYm90aCwgc28gdGhpcyBpcyBhIG5vLW9wIG9uIEFXUy9BenVyZSBhbmQgdGhlIGZpeCBvbiBhCiMgbWluaW1hbCBpbWFnZS4gQkVTVC1FRkZPUlQgQlkgREVTSUdOLCBhbmQgaXQgc2F5cyB3aGljaCBicmFuY2ggaXQgdG9vazogdGhlCiMgcGFja2FnZSBuYW1lcyBhcmUgcmVsZWFzZS1zcGVjaWZpYywgYW5kIGluc3RhbGwuc2ggcHJvdmVzIHRoZSBiaW5hcmllcwojIGFjdHVhbGx5IGV4ZWN1dGUgdHdvIGxlZ3MgbGF0ZXIg4oCUIHRoYXQgaXMgdGhlIHJlYWwgZ2F0ZSBhbmQgaXQgZmFpbHMgbG91ZGx5LgppZiBhcHQtZ2V0ICRBIGluc3RhbGwgLXkgLXFxIGxpYmljdTc4IGxpYnJlYWRsaW5lOHQ2NDsgdGhlbgogIGVjaG8gInJ1bnRpbWUgbGliczogbGliaWN1NzggKyBsaWJyZWFkbGluZTh0NjQgaW5zdGFsbGVkIG9yIGFscmVhZHkgcHJlc2VudCIKZWxzZQogIGVjaG8gInJ1bnRpbWUgbGliczogTk9URSDigJQgbGliaWN1NzgvbGlicmVhZGxpbmU4dDY0IG5vdCBpbnN0YWxsYWJsZSBieSBuYW1lIG9uIHRoaXMgaW1hZ2U7IGNvbnRpbnVpbmcsIGluc3RhbGwuc2gncyBleGVjIGNoZWNrIGlzIHRoZSBnYXRlIgpmaQpmb3IgYyBpbiB6c3RkIHJlYWRlbGYgY3VybCBzaGEyNTZzdW07IGRvCiAgY29tbWFuZCAtdiAiJGMiID4vZGV2L251bGwgMj4mMSB8fCBkaWUgIiRjIHN0aWxsIG5vdCBvbiBQQVRIIGFmdGVyIGFwdC1nZXQgaW5zdGFsbCIKZG9uZQoKc2F5ICJsZWcgMy83IHNlcnZpY2UgdXNlciBhbmQgbGF5b3V0IgojIFBvc3RncmVTUUwgcmVmdXNlcyB0byBydW4gYXMgcm9vdCwgc28gdGhlIGJveCBnZXRzIGl0cyBvd24gc3lzdGVtIGFjY291bnQuCmdldGVudCBncm91cCBhcmdvbmRiID4vZGV2L251bGwgfHwgZ3JvdXBhZGQgLS1zeXN0ZW0gYXJnb25kYgpnZXRlbnQgcGFzc3dkIGFyZ29uZGIgPi9kZXYvbnVsbCB8fCBcCiAgdXNlcmFkZCAtLXN5c3RlbSAtLWdpZCBhcmdvbmRiIC0taG9tZS1kaXIgIiREQVRBIiAtLXNoZWxsIC91c3Ivc2Jpbi9ub2xvZ2luIGFyZ29uZGIKbWtkaXIgLXAgIiRQUkVGSVgiICIkREFUQSIgIiRTUkNESVIiCmNob3duIGFyZ29uZGI6YXJnb25kYiAiJERBVEEiOyBjaG1vZCAwNzUwICIkREFUQSIKCnNheSAibGVnIDQvNyBkb3dubG9hZCAkVEFSQkFMTCIKY3VybCAtZlNMIC0tcmV0cnkgNSAtLXJldHJ5LWRlbGF5IDUgLS1yZXRyeS1jb25ucmVmdXNlZCAtbyAiJFNSQ0RJUi8kVEFSQkFMTCIgIiRVUkwiIFwKICB8fCBkaWUgImRvd25sb2FkIGZhaWxlZDogJFVSTCIKZ290PSIkKHNoYTI1NnN1bSAiJFNSQ0RJUi8kVEFSQkFMTCIgfCBjdXQgLWQnICcgLWYxKSIKZWNobyAiYnl0ZXM6ICAgICAgICQoc3RhdCAtYyAlcyAiJFNSQ0RJUi8kVEFSQkFMTCIpIgplY2hvICJ3YW50IHNoYTI1NjogJFNIQTI1NiIKZWNobyAiZ290ICBzaGEyNTY6ICRnb3QiClsgIiRnb3QiID0gIiRTSEEyNTYiIF0gfHwgZGllICJzaGEyNTYgTUlTTUFUQ0gg4oCUIHJlZnVzaW5nIHRvIGluc3RhbGwiCmVjaG8gInNoYTI1NiBWRVJJRklFRCIKCnNheSAibGVnIDUvNyBpbnN0YWxsIgp0YXIgLUMgIiRTUkNESVIiIC0tdXNlLWNvbXByZXNzLXByb2dyYW09J3pzdGQgLWQnIC14ZiAiJFNSQ0RJUi8kVEFSQkFMTCIgfHwgZGllICJ1bnBhY2sgZmFpbGVkIgpTUkM9IiQoZmluZCAiJFNSQ0RJUiIgLW1pbmRlcHRoIDEgLW1heGRlcHRoIDEgLXR5cGUgZCB8IGhlYWQgLTEpIgpbIC1uICIkU1JDIiBdICYmIFsgLWYgIiRTUkMvaW5zdGFsbC5zaCIgXSB8fCBkaWUgImFydGlmYWN0IHVucGFja2VkIHRvIG5vIGRpciBob2xkaW5nIGluc3RhbGwuc2giCiMgVGhlIENVU1RPTUVSIHBhdGg6IGluc3RhbGwuc2ggd2l0aCBubyAtLXNtb2tlIChvcGVyYXRvci1vbmx5OyBpdCBuZWVkcyBhbgojIGFyZ29uIHNvdXJjZSBjaGVja291dCB0aGlzIFZNIGRvZXMgbm90IGhhdmUpLgpiYXNoICIkU1JDL2luc3RhbGwuc2giIC0tcHJlZml4ICIkUFJFRklYIiB8fCBkaWUgImluc3RhbGwuc2ggZmFpbGVkIgpbIC14ICIkUFJFRklYL2Jpbi9hcmdvbmRiIiBdIHx8IGRpZSAibm8gJFBSRUZJWC9iaW4vYXJnb25kYiBhZnRlciBpbnN0YWxsIgpybSAtcmYgIiRTUkNESVIiCgojIFRIRSBQUkVGSVggSVMgUk9PVC1PV05FRCBBTkQgVEhFIEJPWCBSVU5TIFVOUFJJVklMRUdFRCwgc28gdGhlIGJveCBjYW5ub3QgZG8KIyB0aGlzIGZvciBpdHNlbGYgYXQgYm9vdC4gVGhlIGJ1bmRsZWQgTGFrZWtlZXBlcidzIG1pZ3JhdGlvbnMgbmVlZCB1dWlkLW9zc3AsCiMgYW5kIFBvc3RncmVTUUwgMTcgcmVzb2x2ZXMgZXh0ZW5zaW9uIGNvbnRyb2wgZmlsZXMgT05MWSB1bmRlcgojIDxzaGFyZT4vZXh0ZW5zaW9uLCBzbyB0aGUgc2hpbSBoYXMgdG8gYmUgdGhlcmUgYmVmb3JlIGZpcnN0IGJvb3Qg4oCUIHJlbWVkeSAxCiMgb2YgdGhlIGZvdXIgdGhlIGJveCBpdHNlbGYgbmFtZXMgd2hlbiBpdCByZWZ1c2VzLiBgdmVyaWZ5YCB3cml0ZXMgbm90aGluZyBhbmQKIyBleGl0cyAwIGV4YWN0bHkgd2hlbiBhIGJvb3QgbmVlZHMgbm8gd3JpdGUgaGVyZSwgd2hpY2ggaXMgdGhlIHByb29mIHRoYXQgdGhpcwojIHBnX2luc3RhbGwgY2FuIHN0YXkgcmVhZC1vbmx5LgoiJFBSRUZJWC9iaW4vYXJnb25kYiIgcGctZXh0ZW5zaW9uLXNoaW0gaW5zdGFsbCAtLXBnLWRpc3RyaWIgIiRQUkVGSVgvcGdfaW5zdGFsbCIgXAogIHx8IGRpZSAicGctZXh0ZW5zaW9uLXNoaW0gaW5zdGFsbCBmYWlsZWQiCiIkUFJFRklYL2Jpbi9hcmdvbmRiIiBwZy1leHRlbnNpb24tc2hpbSB2ZXJpZnkgLS1wZy1kaXN0cmliICIkUFJFRklYL3BnX2luc3RhbGwiIFwKICB8fCBkaWUgInBnLWV4dGVuc2lvbi1zaGltIHZlcmlmeSBmYWlsZWQgYWZ0ZXIgaW5zdGFsbCIKZWNobyAicGctZXh0ZW5zaW9uLXNoaW06IGluc3RhbGxlZCBhbmQgdmVyaWZpZWQgKHBnX2luc3RhbGwgc3RheXMgcmVhZC1vbmx5KSIKCnNheSAibGVnIDYvNyBjcmVkZW50aWFscyBhbmQgc3lzdGVtZCB1bml0IgojIEdFTkVSQVRFRCwgbmV2ZXIgc3VwcGxpZWQgYnkgdGhlIGRlcGxveWVyIGFuZCBuZXZlciBlY2hvZWQgdG8gYSBzdGFjayBvdXRwdXQuCiMgVGhlIEZPVVIgTUNQIHN1cmZhY2VzIGNhcnJ5IFNFUEFSQVRFIHRva2VucyBieSBwcm9kdWN0IGRlc2lnbgojIChjcmF0ZXMvYXJnb25kYi1tY3Avc3JjL2xpYi5ycywgYFN1cmZhY2U6OnRva2VuX3ZhcmApOiBvbmUgdG9rZW4gZm9yIGFsbCBmb3VyCiMgd291bGQgaGFuZCBhbiBhbmFseXN0IGNsaWVudCB0aGUgYWRtaW4gbW91bnQg4oCUIGFuZCwgc2luY2UgdGhlIHJhdGlmaWVkIMKnMTIuMjAKIyBhbWVuZG1lbnQgYWRkZWQgYGFyZ29uZGItd3JpdGVgLCB0aGUgbW91bnQgdGhhdCBjYXJyaWVzIGV2ZXJ5IEFyZ29uREItb3duZWQKIyBkYXRhIHdyaXRlLgpnZW4oKSB7IGhlYWQgLWMgMzIgL2Rldi91cmFuZG9tIHwgb2QgLUFuIC12IC10eDEgfCB0ciAtZCAnIFxuJzsgfQppZiBbICEgLWYgIiRFVEMvYm94LmVudiIgXTsgdGhlbgogICMgMTI3LjAuMC4xIGlzIHRoZSBwcm9kdWN0IGRlZmF1bHQgKHNlcnZlLnJzOjU5OTcsIGByZXNvbHZlX2JpbmRgKSBhbmQgdGhpcwogICMgdGVtcGxhdGUncyBwb3N0dXJlLiAwLjAuMC4wIG9ubHkgd2hlbiB0aGUgZGVwbG95ZXIgbmFtZWQgYSBDSURSIOKAlCBhbmQgdGhlbgogICMgdGhlIHRva2VucyBrZWVwIHRoZSBhZ2VudCBzdXJmYWNlcyBmYWlsLWNsb3NlZCAobGliLnJzOjYxODUpLiBUaGUgd3JpdGUgYW5kCiAgIyBhZG1pbiBtb3VudHMgc3RheSBsb29wYmFjayBlaXRoZXIgd2F5IChsaWIucnM6NjMwNykuCiAgbGlzdGVuPSIxMjcuMC4wLjEiOyBbIC1uICIkQVJHT05EQl9WTV9EQl9DSURSIiBdICYmIGxpc3Rlbj0iMC4wLjAuMCIKICB1bWFzayAwMjcKICBjYXQgPiIkRVRDL2JveC5lbnYiIDw8RU5WRU9GCkFSR09OREJfU1RPUkFHRV9CSU5TPSRQUkVGSVgvc3RvcmFnZS10aWVyCkFSR09OREJfUEdfRElTVFJJQj0kUFJFRklYL3BnX2luc3RhbGwKQVJHT05EQl9MSVNURU5fQUREUkVTUz0kbGlzdGVuCkFSR09OREJfQVVUSF9UT0tFTj0kKGdlbikKQVJHT05EQl9EQkFfQVVUSF9UT0tFTj0kKGdlbikKQVJHT05EQl9BRE1JTl9BVVRIX1RPS0VOPSQoZ2VuKQpBUkdPTkRCX1dSSVRFX0FVVEhfVE9LRU49JChnZW4pCkVOVkVPRgogIGNob3duIHJvb3Q6YXJnb25kYiAiJEVUQy9ib3guZW52IjsgY2htb2QgMDY0MCAiJEVUQy9ib3guZW52IgpmaQplY2hvICJib3guZW52OiBsaXN0ZW49JChzZWQgLW4gJ3MvXkFSR09OREJfTElTVEVOX0FERFJFU1M9Ly9wJyAiJEVUQy9ib3guZW52IikgbW9kZT0kKHN0YXQgLWMgJWEgIiRFVEMvYm94LmVudiIpIgoKIyBFbnZpcm9ubWVudEZpbGUgaXMgcGxhaW4gS0VZPVZBTFVFIOKAlCBzeXN0ZW1kIGRvZXMgbm8gc2hlbGwgZXhwYW5zaW9uIGFuZCBkb2VzCiMgbm90IHdhbnQgYGV4cG9ydGAsIHNvICRQUkVGSVgvYXJnb25kYi1lbnYuc2ggKHdoaWNoIGhhcyBib3RoKSBpcyBOT1QgdXNlZC4KY2F0ID4iJFVOSVQiIDw8VU5JVEVPRgpbVW5pdF0KRGVzY3JpcHRpb249QXJnb25EQiAkVkVSU0lPTiBib3ggKGFyZ29uZGIgc2VydmUpCkRvY3VtZW50YXRpb249aHR0cHM6Ly9yZWxlYXNlcy5hcmdvbmRiLmFpCldhbnRzPW5ldHdvcmstb25saW5lLnRhcmdldApBZnRlcj1uZXR3b3JrLW9ubGluZS50YXJnZXQKIyBDaXJjdWl0IGJyZWFrZXIgKENMQVVERS5tZCk6IGEgcmVzdGFydCByZS1zcGF3bnMgYSB3aG9sZSBzdG9yYWdlIHRpZXIgYW5kIGEKIyBjb21wdXRlLiBUaHJlZSBpbnNpZGUgaGFsZiBhbiBob3VyIGlzIGEgYm94IHRoYXQgY2Fubm90IHN0YXkgdXAg4oCUIHN0b3AgYW5kCiMgbGVhdmUgaXQgZmFpbGVkIGZvciBhbiBvcGVyYXRvciByYXRoZXIgdGhhbiBoYW1tZXJpbmcgdGhlIFZNLgpTdGFydExpbWl0SW50ZXJ2YWxTZWM9MTgwMApTdGFydExpbWl0QnVyc3Q9MwoKW1NlcnZpY2VdClR5cGU9c2ltcGxlClVzZXI9YXJnb25kYgpHcm91cD1hcmdvbmRiCkVudmlyb25tZW50RmlsZT0kRVRDL2JveC5lbnYKRXhlY1N0YXJ0PSRQUkVGSVgvYmluL2FyZ29uZGIgc2VydmUgLS1kYXRhLWRpciAkREFUQQpSZXN0YXJ0PW9uLWZhaWx1cmUKUmVzdGFydFNlYz0zMApUaW1lb3V0U3RvcFNlYz0xODAKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldApVTklURU9GCmVjaG8gInVuaXQgd3JpdHRlbjogJFVOSVQiCgpzYXkgImxlZyA3Lzcgc3RhcnQgdGhlIGJveCBhbmQgcHJvdmUgaXQgYW5zd2VycyIKUFNRTD0iJFBSRUZJWC9wZ19pbnN0YWxsL3YxNy9iaW4vcHNxbCIKaWYgWyAiJHtBUkdPTkRCX0JPT1RTVFJBUF9TS0lQX1NZU1RFTUQ6LTB9IiA9ICIxIiBdOyB0aGVuCiAgIyBSZWhlYXJzYWwgcGF0aCBvbmx5IChhIGNvbnRhaW5lciBoYXMgbm8gc3lzdGVtZCkuIFNhbWUgdXNlciwgc2FtZSBlbnYsIHNhbWUKICAjIGFyZ3YgYXMgRXhlY1N0YXJ0OyB3aGF0IGRpZmZlcnMgaXMgdGhlIHN1cGVydmlzb3IsIHdoaWNoIGlzIGV4YWN0bHkgd2hhdCBhCiAgIyBjb250YWluZXIgcmVoZWFyc2FsIGNhbm5vdCBwcm92ZS4KICBlY2hvICJTS0lQX1NZU1RFTUQ9MSDigJQgc3RhcnRpbmcgZGlyZWN0bHkgYXMgdGhlIGFyZ29uZGIgdXNlciIKICBzZXQgLWE7IC4gIiRFVEMvYm94LmVudiI7IHNldCArYQogIHNldHByaXYgLS1yZXVpZD1hcmdvbmRiIC0tcmVnaWQ9YXJnb25kYiAtLWluaXQtZ3JvdXBzIFwKICAgICIkUFJFRklYL2Jpbi9hcmdvbmRiIiBzZXJ2ZSAtLWRhdGEtZGlyICIkREFUQSIgPi92YXIvbG9nL2FyZ29uZGItYm94LmxvZyAyPiYxICYKICBCT1hQSUQ9JCEKICBhbGl2ZSgpIHsga2lsbCAtMCAiJEJPWFBJRCIgMj4vZGV2L251bGw7IH0KICBsb2dzKCkgIHsgdGFpbCAtNDAgL3Zhci9sb2cvYXJnb25kYi1ib3gubG9nOyB9CmVsc2UKICBzeXN0ZW1jdGwgZGFlbW9uLXJlbG9hZAogIHN5c3RlbWN0bCBlbmFibGUgLS1ub3cgYXJnb25kYi1ib3guc2VydmljZSB8fCBkaWUgInN5c3RlbWN0bCBlbmFibGUgLS1ub3cgZmFpbGVkIgogIGFsaXZlKCkgeyBzeXN0ZW1jdGwgaXMtYWN0aXZlIC0tcXVpZXQgYXJnb25kYi1ib3guc2VydmljZTsgfQogIGxvZ3MoKSAgeyBqb3VybmFsY3RsIC11IGFyZ29uZGItYm94LnNlcnZpY2UgLW4gNDAgLS1uby1wYWdlcjsgfQpmaQoKIyBET1VCTEUtQk9VTkRFRCBXQUlUIChDTEFVREUubWQpOiBhIGRlYWRsaW5lIEFORCBhIGxpdmVuZXNzIHByb2JlIG9uIHRoZQojIFBST0RVQ0VSLCBsb3VkIG9uIGVpdGhlciB0cmlnZ2VyIHdpdGggdGhlIHByb2R1Y2VyJ3MgbG9nIHRhaWwuIFRoZSBwcm9iZSBpcwojIHRoZSBleGFjdCBxdWVyeSB0aGUgbmV4dCBzdGVwIHJ1bnMsIG5ldmVyIGEgcHJveHkuCmRlYWRsaW5lPSQoKCBTRUNPTkRTICsgOTAwICkpOyByZWFkeT0wCndoaWxlIFsgJFNFQ09ORFMgLWx0ICRkZWFkbGluZSBdOyBkbwogIGFsaXZlIHx8IHsgZWNobyAiLS0tIHByb2R1Y2VyIGxvZyAtLS0iOyBsb2dzOyBkaWUgInRoZSBib3ggZGllZCBiZWZvcmUgaXQgYW5zd2VyZWQiOyB9CiAgaWYgWyAtciAiJERBVEEvcGctcGFzc3dvcmQiIF0gJiYgUEdQQVNTV09SRD0iJChjYXQgIiREQVRBL3BnLXBhc3N3b3JkIikiICIkUFNRTCIgXAogICAgICAgInBvc3RncmVzcWw6Ly9jbG91ZF9hZG1pbkAxMjcuMC4wLjE6NTQzMi9wb3N0Z3JlcyIgLXRBYyAnc2VsZWN0IDEnIDI+L2Rldi9udWxsIHwgZ3JlcCAtcXggMTsgdGhlbgogICAgcmVhZHk9MTsgYnJlYWsKICBmaQogIHNsZWVwIDUKZG9uZQpbICIkcmVhZHkiID0gIjEiIF0gfHwgeyBlY2hvICItLS0gcHJvZHVjZXIgbG9nIC0tLSI7IGxvZ3M7IGRpZSAidGhlIGJveCBkaWQgbm90IGFuc3dlciBwc3FsIHdpdGhpbiA5MDAgcyI7IH0KCmVjaG8gInBzcWw6IHNlbGVjdCAxIGFuc3dlcmVkIgpwcmludGYgJyVzXG4nICIkVkVSU0lPTiIgPiIkRVRDL2Jvb3RzdHJhcC1jb21wbGV0ZSIKc2F5ICJBcmdvbkRCICRWRVJTSU9OIGlzIHVwLiBGcm9tIHRoaXMgVk06IgplY2hvICIgIFBHUEFTU1dPUkQ9XCQoc3VkbyBjYXQgJERBVEEvcGctcGFzc3dvcmQpICRQU1FMIHBvc3RncmVzcWw6Ly9jbG91ZF9hZG1pbkAxMjcuMC4wLjE6NTQzMi9wb3N0Z3JlcyIKZWNobyAiQVJHT05EQi1CT09UU1RSQVAtT0siCg==\nruncmd:\n  - /usr/local/sbin/argondb-bootstrap.sh >> /var/log/argondb-bootstrap.log 2>&1\n"
  },
  "resources": [
    {
      "type": "Microsoft.Network/networkSecurityGroups",
      "apiVersion": "2023-11-01",
      "name": "[variables('nsgName')]",
      "location": "[parameters('location')]",
      "properties": {
        "securityRules": "[variables('securityRules')]"
      }
    },
    {
      "type": "Microsoft.Network/virtualNetworks",
      "apiVersion": "2023-11-01",
      "name": "[variables('vnetName')]",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]"
      ],
      "properties": {
        "addressSpace": {
          "addressPrefixes": [
            "10.42.0.0/16"
          ]
        },
        "subnets": [
          {
            "name": "[variables('subnetName')]",
            "properties": {
              "addressPrefix": "10.42.0.0/24",
              "networkSecurityGroup": {
                "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]"
              }
            }
          }
        ]
      }
    },
    {
      "type": "Microsoft.Network/publicIPAddresses",
      "apiVersion": "2023-11-01",
      "name": "[variables('pipName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard"
      },
      "properties": {
        "publicIPAllocationMethod": "Static",
        "dnsSettings": {
          "domainNameLabel": "[variables('prefix')]"
        }
      }
    },
    {
      "type": "Microsoft.Network/networkInterfaces",
      "apiVersion": "2023-11-01",
      "name": "[variables('nicName')]",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/virtualNetworks', variables('vnetName'))]",
        "[resourceId('Microsoft.Network/publicIPAddresses', variables('pipName'))]"
      ],
      "properties": {
        "ipConfigurations": [
          {
            "name": "ipconfig1",
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "subnet": {
                "id": "[variables('subnetId')]"
              },
              "publicIPAddress": {
                "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('pipName'))]"
              }
            }
          }
        ]
      }
    },
    {
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2024-07-01",
      "name": "[variables('vmName')]",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"
      ],
      "properties": {
        "hardwareProfile": {
          "vmSize": "[parameters('vmSize')]"
        },
        "storageProfile": {
          "imageReference": {
            "publisher": "Canonical",
            "offer": "[parameters('imageOffer')]",
            "sku": "[parameters('imageSku')]",
            "version": "latest"
          },
          "osDisk": {
            "createOption": "FromImage",
            "diskSizeGB": "[parameters('osDiskSizeGb')]",
            "managedDisk": {
              "storageAccountType": "Premium_LRS"
            }
          }
        },
        "osProfile": {
          "computerName": "[variables('vmName')]",
          "adminUsername": "[parameters('adminUsername')]",
          "customData": "[base64(replace(variables('cloudConfig'), '__DB_CIDR__', parameters('databaseAllowedCidr')))]",
          "linuxConfiguration": {
            "disablePasswordAuthentication": true,
            "ssh": {
              "publicKeys": [
                {
                  "path": "[concat('/home/', parameters('adminUsername'), '/.ssh/authorized_keys')]",
                  "keyData": "[parameters('adminPublicKey')]"
                }
              ]
            }
          }
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"
            }
          ]
        }
      }
    },
    {
      "type": "Microsoft.DevTestLab/schedules",
      "apiVersion": "2018-09-15",
      "name": "[concat('shutdown-computevm-', variables('vmName'))]",
      "location": "[parameters('location')]",
      "condition": "[not(equals(parameters('autoShutdownTime'), ''))]",
      "dependsOn": [
        "[resourceId('Microsoft.Compute/virtualMachines', variables('vmName'))]"
      ],
      "properties": {
        "status": "Enabled",
        "taskType": "ComputeVmShutdownTask",
        "dailyRecurrence": {
          "time": "[parameters('autoShutdownTime')]"
        },
        "timeZoneId": "[parameters('autoShutdownTimeZone')]",
        "targetResourceId": "[resourceId('Microsoft.Compute/virtualMachines', variables('vmName'))]",
        "notificationSettings": {
          "status": "Disabled"
        }
      }
    }
  ],
  "outputs": {
    "fqdn": {
      "type": "string",
      "value": "[reference(resourceId('Microsoft.Network/publicIPAddresses', variables('pipName'))).dnsSettings.fqdn]"
    },
    "sshCommand": {
      "type": "string",
      "value": "[concat('ssh ', parameters('adminUsername'), '@', reference(resourceId('Microsoft.Network/publicIPAddresses', variables('pipName'))).dnsSettings.fqdn)]"
    },
    "watchTheInstall": {
      "type": "string",
      "value": "sudo tail -f /var/log/argondb-bootstrap.log"
    },
    "postDeploySteps": {
      "type": "string",
      "value": "[concat('Tunnel, then connect psql to 127.0.0.1:5432 -- ssh -N -L 5432:127.0.0.1:5432 ', parameters('adminUsername'), '@', reference(resourceId('Microsoft.Network/publicIPAddresses', variables('pipName'))).dnsSettings.fqdn, ' . Read the generated password ON THE VM with: sudo cat /var/lib/argondb/pg-password (deliberately not a template output).')]"
    }
  }
}
