hashicorp / packer-plugin-ansible

Packer plugin for Ansible Provisioner
https://www.packer.io/docs/provisioners/ansible
Mozilla Public License 2.0
50 stars 36 forks source link

Ansible playbook become: true not working when using with packer #190

Open jasonsun9406 opened 5 months ago

jasonsun9406 commented 5 months ago

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

lbajolet-hashicorp commented 5 months ago

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

tenthirtyam commented 5 months ago

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
jasonsun9406 commented 5 months ago

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
rkostyantyn commented 3 months ago

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.