packer-plugin-ansible icon indicating copy to clipboard operation
packer-plugin-ansible copied to clipboard

Ansible playbook become: true not working when using with packer

Open jasonsun9406 opened this issue 1 year ago • 5 comments

Overview of the Issue

We are running a simple ansible playbook with ansible provisioner. When running the playbook without packer, the ansible playbook run just fine, but when running with packer, the ansible provisioner keep failing with the error message of msg: This command has to be run under the root user.

After some investigation, the ansible playbook trigger by packer doesn't seems to elevate to root even defining become: true. And we don't seems to be able to make ansible playbook to run as root user. Any help would be appreciated.

Here is the the simple ansible playbook I am trying to run

- name: 'Provision Image'
  become: true
  hosts: all
  tasks:
    - name: install Apache
      package:
        name: 'httpd'
        state: present

Here is the build block in the packer hcl file

build {
  sources = ["source.azure-arm.rhel"]

  provisioner "ansible" {
    playbook_file = "playbook.yml"
  }
...
}

Reproduction Steps

Using packer to provision a Red Hat image in Azure, and use the ansible provisioner to run the playbook in the overview

Plugin and Packer version

Packer version: v1.11.0 Ansible version: v2.10.7 Ansible provisioner version: v1.1.1

Operating system and Environment details

Source server (server runs packer command): Ubuntu Remote server: Red Hat

jasonsun9406 avatar Jun 11 '24 01:06 jasonsun9406

Hi @jasonsun9406,

In the linked issue on Packer, @tenthirtyam gave an example of a setup that worked for him, could you take a look and see what's different between your case and his? The response as to why this doesn't work may lie there.

Also I imagine that if Ansible cannot run the commands as root despite become = true being set in your playbook, there might be something in the logs that could help. Have you run your build with PACKER_LOG=1 in your environment? This might provide insight as to what failed so you can troubleshoot this problem

lbajolet-hashicorp avatar Jun 17 '24 20:06 lbajolet-hashicorp

Reposting here for continnuity.

I do this in my project with:

build {
  sources = ["source.vsphere-iso.linux-rhel"]

  provisioner "ansible" {
    user                   = var.build_username
    galaxy_file            = "${path.cwd}/ansible/linux-requirements.yml"
    galaxy_force_with_deps = true
    playbook_file          = "${path.cwd}/ansible/linux-playbook.yml"
    roles_path             = "${path.cwd}/ansible/roles"
    ansible_env_vars = [
      "ANSIBLE_CONFIG=${path.cwd}/ansible/ansible.cfg",
      "ANSIBLE_PYTHON_INTERPRETER=/usr/libexec/platform-python"
    ]
    extra_arguments = [
      "--extra-vars", "display_skipped_hosts=false",
      "--extra-vars", "build_username=${var.build_username}",
      "--extra-vars", "build_key='${var.build_key}'",
      "--extra-vars", "ansible_username=${var.ansible_username}",
      "--extra-vars", "ansible_key='${var.ansible_key}'",
      "--extra-vars", "enable_cloudinit=${var.vm_guest_os_cloudinit}",
    ]
  }
---
- become: true
  become_method: sudo
  debugger: never
  gather_facts: true
  hosts: all
  roles:
    - base
    - users
    - configure
    - clean

tenthirtyam avatar Jun 17 '24 20:06 tenthirtyam

Thanks @tenthirtyam @lbajolet-hashicorp

I tried making changes in the playbook similar with what you have, but I am still facing the same error msg: This command has to be run under the root user

I don't think this will matter much, but @tenthirtyam will you mind to share the following info with me?

  1. What's your packer and ansible version?
  2. ansible.cfg content

jasonsun9406 avatar Jun 19 '24 13:06 jasonsun9406

I also faced the same problem. It works fine on the following versions:

Packer version: 1.8.3
Ansible Version: 7.2.0 [core 2.14.3]

And does not work on the following version:

Packer version: 1.9.4
Ansible Version:  9.4.0 [core 2.16.6]

It looks like the "become" option simply stopped existing. I tried to specify this option at all levels: ansible.cfg, environment variables, packer extra_arguments and ansible_env_vars, ansible role and task level - all the same.

Both options, successful and not, use the same ansible.cfg. The packer is executed in a docker container (ie, from root).

UPDATE I seem to have solved the problem by adding the 'user = "Packer"' parameter to the provisioner:

...
  provisioner "ansible" {
    playbook_file           = var.playbook_path
    extra_arguments         = ["-v"]
    inventory_file_template = var.inventory_file_template
    user                    = "Packer"
  }
...

It turns out that without this parameter, ansible is launched from the user with which Packer itself is launched (which is root). And if the playbook is launched from root, the "become" option does not work. I don't know why it worked on the older version.

rkostyantyn avatar Aug 13 '24 06:08 rkostyantyn

Hello, I believe this stems from:

Become: yes We recommend against running Packer as root; if you do then you won't be able to successfully run your Ansible playbook as root; become: yes will fail.

https://developer.hashicorp.com/packer/integrations/hashicorp/ansible/latest/components/provisioner/ansible#become:-yes

I was facing a similar issue with tasks that required privileged escalation that were failing (Ubuntu image), I solved it by adding the following (in my context the ubuntu user had sudoer capabilities):

  provisioner "ansible" {
    user = "ubuntu"
...
  }

guillaumerenault avatar Dec 02 '24 12:12 guillaumerenault