""" Azure VPS — Pulumi infrastructure Creates a single Linux VM with Docker-ready networking. """ import pulumi from pulumi import Config, Output, export from pulumi_azure_native import resources, network, compute from pathlib import Path # --------------------------------------------------------------------------- # Config # --------------------------------------------------------------------------- config = Config("azure-vps") VM_SIZE = config.get("vm_size") or "Standard_B1ms" ADMIN_USERNAME = config.get("admin_username") or "papyrus" SSH_KEY_PATH = config.get("ssh_public_key_path") or "~/.ssh/id_ed25519.pub" ssh_public_key = Path(SSH_KEY_PATH).expanduser().read_text().strip() # --------------------------------------------------------------------------- # Resource Group # --------------------------------------------------------------------------- rg = resources.ResourceGroup( "rg", resource_group_name="papyrus-vm-rg", tags={"environment": "dev", "managed_by": "pulumi"}, ) # --------------------------------------------------------------------------- # Networking — VNet, Subnet, Public IP, NSG, NIC # --------------------------------------------------------------------------- vnet = network.VirtualNetwork( "vnet", virtual_network_name="papyrus-vnet", resource_group_name=rg.name, address_space=network.AddressSpaceArgs( address_prefixes=["10.0.0.0/16"], ), ) subnet = network.Subnet( "subnet", subnet_name="papyrus-subnet", resource_group_name=rg.name, virtual_network_name=vnet.name, address_prefix="10.0.1.0/24", ) public_ip = network.PublicIPAddress( "pip", public_ip_address_name="papyrus-pip", resource_group_name=rg.name, public_ip_allocation_method=network.IPAllocationMethod.STATIC, sku=network.PublicIPAddressSkuArgs( name=network.PublicIPAddressSkuName.STANDARD, ), ) nsg = network.NetworkSecurityGroup( "nsg", network_security_group_name="papyrus-nsg", resource_group_name=rg.name, security_rules=[ network.SecurityRuleArgs( name="SSH", priority=1000, direction=network.SecurityRuleDirection.INBOUND, access=network.SecurityRuleAccess.ALLOW, protocol=network.SecurityRuleProtocol.TCP, source_port_range="*", destination_port_range="22", source_address_prefix="*", destination_address_prefix="*", ), network.SecurityRuleArgs( name="HTTP", priority=1010, direction=network.SecurityRuleDirection.INBOUND, access=network.SecurityRuleAccess.ALLOW, protocol=network.SecurityRuleProtocol.TCP, source_port_range="*", destination_port_range="80", source_address_prefix="*", destination_address_prefix="*", ), network.SecurityRuleArgs( name="HTTPS", priority=1020, direction=network.SecurityRuleDirection.INBOUND, access=network.SecurityRuleAccess.ALLOW, protocol=network.SecurityRuleProtocol.TCP, source_port_range="*", destination_port_range="443", source_address_prefix="*", destination_address_prefix="*", ), ], ) nic = network.NetworkInterface( "nic", network_interface_name="papyrus-nic", resource_group_name=rg.name, ip_configurations=[ network.NetworkInterfaceIPConfigurationArgs( name="papyrus-ipconfig", subnet=network.SubnetArgs(id=subnet.id), public_ip_address=network.PublicIPAddressArgs(id=public_ip.id), private_ip_allocation_method=network.IPAllocationMethod.DYNAMIC, ), ], network_security_group=network.NetworkSecurityGroupArgs(id=nsg.id), ) # --------------------------------------------------------------------------- # Virtual Machine — Ubuntu 24.04 LTS # --------------------------------------------------------------------------- vm = compute.VirtualMachine( "vm", vm_name="papyrus-vm", resource_group_name=rg.name, hardware_profile=compute.HardwareProfileArgs( vm_size=VM_SIZE, ), os_profile=compute.OSProfileArgs( computer_name="papyrus-vm", admin_username=ADMIN_USERNAME, linux_configuration=compute.LinuxConfigurationArgs( disable_password_authentication=True, ssh=compute.SshConfigurationArgs( public_keys=[ compute.SshPublicKeyArgs( path=f"/home/{ADMIN_USERNAME}/.ssh/authorized_keys", key_data=ssh_public_key, ), ], ), ), ), network_profile=compute.NetworkProfileArgs( network_interfaces=[ compute.NetworkInterfaceReferenceArgs( id=nic.id, primary=True, ), ], ), storage_profile=compute.StorageProfileArgs( os_disk=compute.OSDiskArgs( create_option=compute.DiskCreateOptionTypes.FROM_IMAGE, managed_disk=compute.ManagedDiskParametersArgs( storage_account_type=compute.StorageAccountTypes.STANDARD_LRS, ), ), image_reference=compute.ImageReferenceArgs( publisher="Canonical", offer="ubuntu-24_04-lts", sku="server", version="latest", ), ), tags={"environment": "dev", "managed_by": "pulumi"}, ) # --------------------------------------------------------------------------- # Outputs # --------------------------------------------------------------------------- export("vm_public_ip", public_ip.ip_address) export("admin_username", ADMIN_USERNAME) export("ssh_command", Output.concat("ssh ", ADMIN_USERNAME, "@", public_ip.ip_address))