azure-linux example template (#3348)

* azure-linux example template

Signed-off-by: Spike Curtis <spike@coder.com>

* Use azurerm_linux_virtual_machine and wait for attachment

Signed-off-by: Spike Curtis <spike@coder.com>

* Use azure-instance-identity

Signed-off-by: Spike Curtis <spike@coder.com>
This commit is contained in:
Spike Curtis 2022-08-08 17:25:20 -05:00 committed by GitHub
parent a848e71f58
commit 049e7cb5df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 284 additions and 0 deletions

View File

@ -0,0 +1,17 @@
---
name: Develop in Linux on Azure
description: Get started with Linux development on Microsoft Azure.
tags: [cloud, azure, linux]
---
# azure-linux
To get started, run `coder templates init`. When prompted, select this template.
Follow the on-screen instructions to proceed.
## Authentication
This template assumes that coderd is run in an environment that is authenticated
with Azure. For example, run `az login` then `az account set --subscription=<id>`
to import credentials on the system and user running coderd. For other ways to
authenticate [consult the Terraform docs](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs#authenticating-to-azure).

View File

@ -0,0 +1,56 @@
#cloud-config
cloud_final_modules:
- [scripts-user, always]
bootcmd:
# work around https://github.com/hashicorp/terraform-provider-azurerm/issues/6117
- until [ -e /dev/disk/azure/scsi1/lun10 ]; do sleep 1; done
device_aliases:
homedir: /dev/disk/azure/scsi1/lun10
disk_setup:
homedir:
table_type: gpt
layout: true
fs_setup:
- label: coder_home
filesystem: ext4
device: homedir.1
mounts:
- ["LABEL=coder_home", "/home/${username}"]
hostname: ${hostname}
users:
- name: ${username}
sudo: ["ALL=(ALL) NOPASSWD:ALL"]
groups: sudo
shell: /bin/bash
packages:
- git
write_files:
- path: /opt/coder/init
permissions: "0755"
encoding: b64
content: ${init_script}
- path: /etc/systemd/system/coder-agent.service
permissions: "0644"
content: |
[Unit]
Description=Coder Agent
After=network-online.target
Wants=network-online.target
[Service]
User=${username}
ExecStart=/opt/coder/init
Restart=always
RestartSec=10
TimeoutStopSec=90
KillMode=process
OOMScoreAdjust=-900
SyslogIdentifier=coder-agent
[Install]
WantedBy=multi-user.target
runcmd:
- chown ${username}:${username} /home/${username}
- systemctl enable coder-agent
- systemctl start coder-agent

View File

@ -0,0 +1,211 @@
terraform {
required_providers {
coder = {
source = "coder/coder"
version = "0.4.3"
}
azurerm = {
source = "hashicorp/azurerm"
version = "=3.0.0"
}
}
}
variable "location" {
description = "What location should your workspace live in?"
default = "eastus"
validation {
condition = contains([
"eastus",
"southcentralus",
"westus2",
"australiaeast",
"southeastasia",
"northeurope",
"westeurope",
"centralindia",
"eastasia",
"japaneast",
"brazilsouth",
"asia",
"asiapacific",
"australia",
"brazil",
"india",
"japan",
"southafrica",
"switzerland",
"uae",
], var.location)
error_message = "Invalid location!"
}
}
variable "instance_type" {
description = "What instance type should your workspace use?"
default = "Standard_B4ms"
validation {
condition = contains([
"Standard_B1ms",
"Standard_B2ms",
"Standard_B4ms",
"Standard_B8ms",
"Standard_B12ms",
"Standard_B16ms",
"Standard_D2as_v5",
"Standard_D4as_v5",
"Standard_D8as_v5",
"Standard_D16as_v5",
"Standard_D32as_v5",
], var.instance_type)
error_message = "Invalid instance type!"
}
}
variable "home_size" {
type = number
description = "How large would you like your home volume to be (in GB)?"
default = 20
validation {
condition = var.home_size >= 1
error_message = "Value must be greater than or equal to 1."
}
}
provider "azurerm" {
features {}
}
data "coder_workspace" "me" {
}
resource "coder_agent" "main" {
arch = "amd64"
os = "linux"
auth = "azure-instance-identity"
}
locals {
prefix = "coder-${data.coder_workspace.me.owner}-${data.coder_workspace.me.name}"
userdata = templatefile("cloud-config.yaml.tftpl", {
username = lower(substr(data.coder_workspace.me.owner, 0, 32))
init_script = base64encode(coder_agent.main.init_script)
hostname = lower(data.coder_workspace.me.name)
})
}
resource "azurerm_resource_group" "main" {
name = "${local.prefix}-resources"
location = var.location
tags = {
Coder_Provisioned = "true"
}
}
// Uncomment here and in the azurerm_network_interface resource to obtain a public IP
#resource "azurerm_public_ip" "main" {
# name = "publicip"
# resource_group_name = azurerm_resource_group.main.name
# location = azurerm_resource_group.main.location
# allocation_method = "Static"
#
# tags = {
# Coder_Provisioned = "true"
# }
#}
resource "azurerm_virtual_network" "main" {
name = "network"
address_space = ["10.0.0.0/24"]
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
tags = {
Coder_Provisioned = "true"
}
}
resource "azurerm_subnet" "internal" {
name = "internal"
resource_group_name = azurerm_resource_group.main.name
virtual_network_name = azurerm_virtual_network.main.name
address_prefixes = ["10.0.0.0/29"]
}
resource "azurerm_network_interface" "main" {
name = "nic"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
ip_configuration {
name = "internal"
subnet_id = azurerm_subnet.internal.id
private_ip_address_allocation = "Dynamic"
// Uncomment for public IP address as well as azurerm_public_ip resource above
//public_ip_address_id = azurerm_public_ip.main.id
}
tags = {
Coder_Provisioned = "true"
}
}
resource "azurerm_managed_disk" "home" {
create_option = "Empty"
location = azurerm_resource_group.main.location
name = "home"
resource_group_name = azurerm_resource_group.main.name
storage_account_type = "StandardSSD_LRS"
disk_size_gb = var.home_size
}
// azurerm requires an SSH key (or password) for an admin user or it won't start a VM. However,
// cloud-init overwrites this anyway, so we'll just use a dummy SSH key.
resource "tls_private_key" "dummy" {
algorithm = "RSA"
rsa_bits = 4096
}
resource "azurerm_linux_virtual_machine" "main" {
count = data.coder_workspace.me.transition == "start" ? 1 : 0
name = "vm"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
size = var.instance_type
// cloud-init overwrites this, so the value here doesn't matter
admin_username = "adminuser"
admin_ssh_key {
public_key = tls_private_key.dummy.public_key_openssh
username = "adminuser"
}
network_interface_ids = [
azurerm_network_interface.main.id,
]
computer_name = lower(data.coder_workspace.me.name)
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
source_image_reference {
publisher = "Canonical"
offer = "0001-com-ubuntu-server-focal"
sku = "20_04-lts-gen2"
version = "latest"
}
user_data = base64encode(local.userdata)
tags = {
Coder_Provisioned = "true"
}
}
resource "azurerm_virtual_machine_data_disk_attachment" "home" {
count = data.coder_workspace.me.transition == "start" ? 1 : 0
managed_disk_id = azurerm_managed_disk.home.id
virtual_machine_id = azurerm_linux_virtual_machine.main[0].id
lun = "10"
caching = "ReadWrite"
}