In general when I'm uploading VM images to Azure, I've already configured a remote management user. OpenBSD makes this trivial by allowing you to add a user during autoinstall(8):
Setup a user = remoteadmin Full name for user = remoteadmin Password for user = ************* Public ssh key for user remoteadmin = ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILool4pwv0BHb25YZjzq36Wl4GgqRvdFfKuDHvcSm89I
My Ansible host has this SSH key, so it can manage any VM that is created from this image. Remember to create /etc/doas.conf if you need to elevate your permissions!
Azure VM deployments require a username and (usually) a password or else the deployment won't pass the validation step. (Microsoft really doesn't want you proverbially locking your keys in the car with your baby inside it.) I don't want to define another superuser for my VMs, but since I'm forced to do so, I am going to make it something no one is ever going to be able to use, not even me.
To accomplish this, I end up needing to randomly generate a username and a password — credentials I'm never going to use — just to make Azure happy. I discovered a neat way to make this happen:
bash-5.0$ cat credentials-new-fromshell.yml --- - hosts: localhost gather_facts: no tasks: - name: generate username run_once: yes local_action: shell: head -10 /dev/urandom | strings | tr -cd '[:lower:]' | tr -d 'aeiou' | fold -w12 | head -1 register: username - name: generate password run_once: yes local_action: shell: head -30 /dev/urandom | strings | tr -cd '[:punct:]''[:alnum:]' | tr -d "\\\//\#\'\"\`\$\[\]\{\}" | fold -w72 | head -1 register: password - name: print username debug: msg: "{{username.stdout}}" - name: print password debug: msg: "{{password.stdout}}" # END
The run_once part is also critical: if you deploy multiple VMs, you want to make sure they all get the same username and password values you generated.
This works, but it feels sloppy. You'd think that a machine management platform would have a builtin solution to the problem of generating passwords. Fortunately, Ansible can handle this with the password plugin, but it isn't nearly as well known as it should be:
bash-5.0$ cat credentials-new-frombuiltin.yml --- - hosts: localhost gather_facts: no tasks: - name: generate credential run_once: yes set_fact: username: "{{ lookup('password', '/dev/null length=15 chars=ascii_letters')|lower }}" password: "{{ lookup('password', '/dev/null length=64 chars=ascii_letters,digits,punctuation') }}" - name: print credential debug: msg: "username: {{username}} password: {{password}}" # END
This is how I recommend you generate your random usernames and passwords. So to put this into an example:
bash-5.0$ cat vm-randomusername-new.yml --- - hosts: localhost gather_facts: no vars: service_prefix: my-service rgroup_name: "{{service_prefix}}-rgroup" location: westus2 vm_size: Standard_A1 tasks: - name: generate credential run_once: yes set_fact: username: "{{ lookup('password', '/dev/null length=15 chars=ascii_letters')|lower }}" password: "{{ lookup('password', '/dev/null length=64 chars=ascii_letters,digits,punctuation') }}" # (vnet, network interface resources go here) - name: create vm azure_rm_virtualmachine: name: "{{service_prefix}}-ubuntu1" resource_group: "{{rgroup_name}}" location: "{{location}}" vm_size: "{{vm_size}}" admin_username: "{{username}}" admin_password: "{{password}}" os_type: Linux image: publisher: Canonical offer: UbuntuServer sku: 18.04-LTS version: latest os_disk_name: "{{service_prefix}}-osdisk" managed_disk_type: Standard_LRS network_interface_names: "{{service_prefix}}-nic" started: no state: present - name: print credential debug: msg: "username: {{username}} password: {{password}}" # END
This is the last problem I needed to solve in order to completely automate my OpenBSD VM deployment pipeline. I can provision a VM with a PowerShell script and an autoinstall(8) config file. I can set it up with an Ansible playbook and a bevy of assigned roles. I can upload the .VHD file with a wrapper script around blobxfer and now, finally, I can create an Azure image and deploy VMs with an Ansible playbook using Azure management modules.
Life is good.
No comments:
Post a Comment