Rebooting an Azure VM within an ansible playbook

88 Views Asked by At

I've an inventory that looks like this:

virtualmachines:
   hosts:
      Name-Of-My-Azure-VM-Here:
         ansible_host: 1.2.3.4
         ansible_port: 22
      Name-Of-My-Other-Azure-VM-Here:
         ansible_host: 2.3.4.5
         ansible_port: 22

I'm trying to reboot the machine when I'm done with the setup. The built in reboot command throws an error:

Reboot command failed. Error was: 'Failed to set wall message, ignoring: Interactive authentication required.\r\nFailed to call ScheduleShutdown in logind, no action will be taken: Interactive authentication required., Shared connection to 1.2.3.4 closed

... so I'm attempting to use the shell command which does work if I launch it locally:

az vm restart --resource-group "My-RG-Name" --name <my VM name here>

Of course, this command needs to execute on the machine that is executing the playbook, not the remote. Let's say my playbook looks like this attempt:

# This part run on N remote hosts
- name: Setup Middleware
  hosts: virtualmachines
  tasks:
    - name: Edit the config file to tell the software its own name
      ansible.builtin.lineinfile:
         path: /home/some/file.txt
         regexp: '^MyOwnName='
         line: MyOwnName="{{ inventory_hostname }}"  # in this portion of the playbook {{inventory_hostname}} resolves to 'Name-Of-My-VM-Here'

# This part run locally
- name: Restart Azure VM locally using Azure CLI
  hosts: localhost
  gather_facts: false
  tasks:
    - name: Restart Azure VM
      command: az vm restart --resource-group "My-RG-Name" --name ... # this needs to be 'Name-Of-My-VM-here' but I don't know how to get it - in this portion of the playbook {{inventory_hostname}} resolves to 'localhost'

I'm stuck on the part where I need to tell az the name(s) of the machine(s) to reboot. In the "remote part" of the playbook this can easily come from the inventory file and I would ordinarily access it with {{ inventory_hostname }} in that "remote part" of the playbook..

But how can I run a command in a "host: local" section, that uses whatever {{ inventory_hostname }} value was active in the remote part of the playbook?

Alternatively if there is a way to get the builtin reboot command to work, that would seem to be the simplest option..

2

There are 2 best solutions below

0
flackoverstow On

I was convinced that I'd tried adding become: true to my original attempt to reboot the machine using the built-in reboot: command, but perhaps not. Using the following in the playbook worked to reboot the machine:

    - name: Reboot (re-prompt for the SSH key passphrase means server is done rebooting)
      become: true
      ansible.builtin.reboot: 
2
saviour123 On

There are many ways to do this. Like mentioned in the comments. This can also be done this way.

Remember to add **become: true**

- name: Reboot the server
  become: true
  ansible.builtin.shell: shutdown -r now

- name: Reboot with Command
  become: true
  command: shutdown -r now

- name: Reboot with BuiltIn
  reboot:

---> from Ansible Docs

- name: Unconditionally reboot the machine with all defaults
  ansible.builtin.reboot:

- name: Reboot a slow machine that might have lots of updates to apply
  ansible.builtin.reboot:
    reboot_timeout: 3600

- name: Reboot a machine with shutdown command in unusual place
  ansible.builtin.reboot:
    search_paths:
     - '/lib/molly-guard'

- name: Reboot machine using a custom reboot command
  ansible.builtin.reboot:
    reboot_command: launchctl reboot userspace
    boot_time_command: uptime | cut -d ' ' -f 5

- name: Reboot machine and send a message
  ansible.builtin.reboot:
    msg: "Rebooting machine in 5 seconds"