ansible / ansible-builder

An Ansible execution environment builder
Other
291 stars 93 forks source link

build doesn't pick up `ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_TOKEN` #346

Closed cloin closed 1 year ago

cloin commented 2 years ago

I have an execution_environment.yml pointing to an ansible.cfg which contains automation hub configuration. Instead of specifying token in the file, I export ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_TOKEN as an environment variable so I can build in github actions. I receive:

#13 [galaxy 6/6] RUN ansible-galaxy collection install  -r requirements.yml --collections-path /usr/share/ansible/collections
#13 sha256:a3cd1134dd10254bd751e65cbfbb9b8f3315090d052e7bb73eaa0a1b5bda9923
#13 1.150 Starting galaxy collection install process
#13 1.150 Process install dependency map
#13 1.258 [WARNING]: Skipping Galaxy server https://console.redhat.com/api/automation-
#13 1.258 hub/. Got an unexpected error when getting available versions of collection
#13 1.258 ansible.utils: HTTP Error 400: Bad Request
#13 1.259 to see the full traceback, use -vvv
#13 1.259 ERROR! Unexpected Exception, this is probably a bug: HTTP Error 400: Bad Request
#13 ERROR: executor failed running [/bin/sh -c ansible-galaxy collection install $ANSIBLE_GALAXY_CLI_COLLECTION_OPTS -r requirements.yml --collections-path /usr/share/ansible/collections]: exit code: 250
------
 > [galaxy 6/6] RUN ansible-galaxy collection install  -r requirements.yml --collections-path /usr/share/ansible/collections:
------
executor failed running [/bin/sh -c ansible-galaxy collection install $ANSIBLE_GALAXY_CLI_COLLECTION_OPTS -r requirements.yml --collections-path /usr/share/ansible/collections]: exit code: 250

ansible-builder build fails with this configuration. ansible-galaxy collection install ansible.utils succeeds. If I add the token in ansible.cfg instead of setting ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_TOKEN, ansible-builder build succeeds.

execution-environment.yml:

---
version: 1

build_arg_defaults:
  EE_BASE_IMAGE: 'registry.redhat.io/ansible-automation-platform-21/ee-minimal-rhel8:latest'

ansible_config: '../ansible.cfg'

dependencies:
  galaxy: requirements.yml
  python: requirements.txt

additional_build_steps:
  prepend: |
    RUN pip3 install --upgrade pip setuptools

ansible.cfg

[galaxy]
server_list = automation_hub

[galaxy_server.automation_hub]
url=https://console.redhat.com/api/automation-hub/
auth_url=https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token
Shrews commented 2 years ago

I would expect this since ansible-builder doesn't pass along environment variables to the docker build or podman build command that it runs via subprocess (see https://github.com/ansible/ansible-builder/blob/devel/ansible_builder/utils.py#L68). I don't consider this a bug, but I think it would make a reasonable feature request, and may be rather simple to implement.

matthewdaclark commented 2 years ago

I also looked into this for awhile as I would like to store the execution environment code in source control without exposing secrets. So, from that aspect I find it perhaps not a bug but a security defect. At this point there is no way to save to source control a working copy without exposing a secret or doing some fancy githook

Akasurde commented 1 year ago

@cloin With Ansible Builder v3 you can now specify environment variables for different steps. For example, in your case you can use -

additional_build_steps:
  prepend_galaxy:
    - ENV ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_TOKEN=secret_token

Notice prepend_galaxy step will have this environment variable. Please give it a try and let us know if it works for you. You can check out more options here. Thanks,

laurent-indermuehle commented 1 year ago

Hi! I was having the same error 250 as @cloin. Then I tried @Akasurde solution to use the env vars in prepend_galaxy. This changed the error from 250 to 401 unauthorized.

I've tested all possible combination that I could think of:

prepend_galaxy:
    - ADD _build/configs/ansible.cfg ~/.ansible.cfg
    - ENV ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_URL=https://cloud.redhat.com/api/automation-hub/
    - ENV ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_AUTH_URL=https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token
    - ENV ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_TOKEN=eyJhbGci...
prepend_galaxy:
    - ENV ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_URL=https://cloud.redhat.com/api/automation-hub/
    - ENV ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_AUTH_URL=https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token
    - ENV ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_TOKEN=eyJhbGci...
prepend_galaxy:
    - ENV ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_URL=https://console.redhat.com/api/automation-hub/content/xxxxxx-synclist/
    - ENV ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_AUTH_URL=https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token
    - ENV ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_TOKEN=eyJhbGci...

Nothing works. Any idea? My token works when I use ansible-galaxy directly.

Shrews commented 1 year ago

@laurent-indermuehle A couple of things:

The last example (using xxxxxx-synclist in the URL) looks correct to me.

I'm having to make assumptions about your EE definition file, but try these things:

Shrews commented 1 year ago

So, I have verified that this works correctly with ansible-builder version 3.0. Below is the EE that I used:

---
version: 3

images:
  base_image:
    name: registry.redhat.io/ansible-automation-platform-23/ee-minimal-rhel8:latest

build_arg_defaults:
  ANSIBLE_GALAXY_CLI_COLLECTION_OPTS: '-vvv'

dependencies:
    ansible_core:
        package_pip: ansible-core==2.15.0
    ansible_runner:
        package_pip: ansible-runner==2.3.2
    galaxy:
        collections:
            - ansible.utils

additional_build_files:
    - src: files/ansible.cfg
      dest: configs

additional_build_steps:
    prepend_galaxy:
        - COPY _build/configs/ansible.cfg /etc/ansible/ansible.cfg
        - ENV ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_URL=https://console.redhat.com/api/automation-hub/content/xxxxxxx-synclist/
        - ENV ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_AUTH_URL=https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token
        - ENV ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_TOKEN=<token value>

options:
    package_manager_path: /usr/bin/microdnf

And the contents of files/ansible.cfg are:

[galaxy]
server_list = automation_hub

The verbose output of builder contains:

Collection 'ansible.utils:2.10.2' obtained from server automation_hub https://console.redhat.com/api/automation-hub/content/xxxxxxx-synclist/

Given the above, I'm going to close this issue. Since we do not usually see comments on closed issues, if any bugs are encountered, please open a new issue.

laurent-indermuehle commented 1 year ago

@Shrews For me the token is not read :(

From my workstation, running ansible-galaxy collection install -r ee/requirements.yml --collections-path "/tmp" install the collection from Automation Hub successfully.

But the same thing using ansible-builder returns 401 unauthorized.

Here's the execution-environment.yml:

---
version: 3

dependencies:
  galaxy: ee/requirements.yml
  python: ee/requirements.txt
  system: ee/bindep.txt

# https://catalog.redhat.com/software/containers/search
images:
  base_image:
    name:
      "registry.redhat.io/ansible-automation-platform-23\
      /ee-supported-rhel8:1.0.0-287"

additional_build_files:
  - src: ansible.cfg
    dest: configs

build_arg_defaults:
  ANSIBLE_GALAXY_CLI_COLLECTION_OPTS: '-vvv'

additional_build_steps:
  prepend_galaxy:
    - COPY _build/configs/ansible.cfg /etc/ansible/ansible.cfg
    - ENV ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_URL=https://console.redhat.com/api/automation-hub/content/xxxxx-synclist/
    - ENV ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_AUTH_URL=https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token
    - ENV ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_TOKEN=xxxx
  prepend_final: |
    RUN alternatives --set python /usr/bin/python3
    RUN python3 -m pip install --upgrade pip
  append_final: |
    RUN pip install --user --upgrade ansible-lint yamllint

The ee/requirements.yml:

---
collections:
  - name: redhat.rhel_system_roles
    version: '1.21.1'
    source:
      "https://console.redhat.com/api/automation-hub/content/xxxxxx-synclist/"

  - name: ansible.tower
    version: '3.8.6'
    source:
      "https://console.redhat.com/api/automation-hub/content/xxxxxx-synclist/"

  - name: prometheus.prometheus
     version: 0.5.0
     source: https://galaxy.ansible.com

ansible.cfg:

[defaults]
roles_path = ./roles:/usr/share/ansible/roles
collections_paths = ./local_collections:/usr/share/ansible/collections
forks = 100
callbacks_enabled = ansible.posix.timer, ansible.posix.profile_roles
stdout_callback = yaml
interpreter_python = auto_silent
use_persistent_connections = true

[connection]
pipelining = true

[galaxy]
server_list = galaxy, automation_hub

[galaxy_server.galaxy]
url=https://galaxy.ansible.com/

[galaxy_server.automation_hub]
url=https://console.redhat.com/api/automation-hub/content/xxxxxx-synclist/
auth_url=https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token
token=xxxxxx

The output of ansible-builder 3.0.0:

[2/4] STEP 15/15: RUN ANSIBLE_GALAXY_DISABLE_GPG_VERIFY=1 ansible-galaxy collection install $ANSIBLE_GALAXY_CLI_COLLECTION_OPTS -r requirements.yml --collections-path "/usr/share/ansible/collections"
ERROR! Error when finding available api versions from explicit_requirement_redhat.rhel_system_roles (https://console.redhat.com/api/automation-hub/content/xxxxxx-synclist/) (HTTP Code: 401, Message: Unauthorized)
ansible-galaxy [core 2.14.5]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/runner/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.9/site-packages/ansible
  ansible collection location = /home/runner/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible-galaxy
  python version = 3.9.13 (main, Nov  9 2022, 13:16:24) [GCC 8.5.0 20210514 (Red Hat 8.5.0-15)] (/usr/bin/python3.9)
  jinja version = 3.1.2
  libyaml = True
Using /etc/ansible/ansible.cfg as config file
Reading requirement file at '/build/requirements.yml'
Starting galaxy collection install process
Found installed collection amazon.aws:5.1.0 at '/usr/share/ansible/collections/ansible_collections/amazon/aws'
[...]
Error: building at STEP "RUN ANSIBLE_GALAXY_DISABLE_GPG_VERIFY=1 ansible-galaxy collection install $ANSIBLE_GALAXY_CLI_COLLECTION_OPTS -r requirements.yml --collections-path "/usr/share/ansible/collections"": while running runtime: exit status 1
laurent-indermuehle commented 1 year ago

Mmh, I don't get why we need to specify an ansible-core version different than the one in the base image, but when adding the following to execution_environment.yml, it works!:

dependencies:
  ansible_core:
      package_pip: ansible-core==2.15.0
  ansible_runner:
      package_pip: ansible-runner==2.3.2

options:
    package_manager_path: /usr/bin/microdnf

Thank you @Shrews. Can you explain what the difference between the ansible-core from the base image and the one we specify in package_pip?

Shrews commented 1 year ago

@laurent-indermuehle We don't build that base image so I can't tell you anything about it.

Considering that the error you showed in the previous comment mentions a explicit_requirement_redhat.rhel_system_roles collection that I do not see in your example (I do see redhat.rhel_system_roles), I'm wondering if your error was actually elsewhere. The version of ansible-core is likely a non-factor.

Also, you do not need to define AH data in both an ansible.cfg and with ENV values.

laurent-indermuehle commented 1 year ago

@Shrews Thanks for taking the time to reply.

2.14 failed to download the collection and 2.15 succeeded. I found in the changelog that they fixes related issues. I think ansible-runner will use the ansible-core embedded in the base image when I will use the EE. And the dependencies are used by ansible-builder to build the image. I guess. If I'm right, maybe we could clarify that in the documentation?

It makes sense that I don't need to set Automation Hub credentials in both locations. In doubt I prefered to put it everywhere ;) I'll clean that. Thanks for that too.