# Delegate\_to: localhost is not working as expected

**URL:** <https://forum.ansible.com/t/delegate-to-localhost-is-not-working-as-expected/41995>\
**Category:** Get Help\
**Tags:** gcp, ansible, playbook, awx\
**Created:** [April 24, 2025, 2:30pm UTC](https://forum.ansible.com/t/delegate-to-localhost-is-not-working-as-expected/41995 "2025-04-24T14:30:12Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![SaravanaSelvaraj](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/saravanaselvaraj/32/2841_2.png) [@SaravanaSelvaraj](https://forum.ansible.com/u/SaravanaSelvaraj)\
**Post date:** [April 24, 2025, 2:30pm UTC](https://forum.ansible.com/t/delegate-to-localhost-is-not-working-as-expected/41995/1 "2025-04-24T14:30:12Z")

</div>

**delegate\_to: localhost is not working as expected.**.  
Dear community,

Looks like I am stuck in a loop.So I have a project which has the main playbook which calls a role for the GCP connection using IAP.

My project is

```auto
- name: Establish GCVE connectivity and run remote command on all hosts
  hosts: all
  gather_facts: false
  vars:
    gcp_project: "{{ hostvars[inventory_hostname]['project'] }}"
    gcp_zone: "{{ hostvars[inventory_hostname]['zone'] }}"
    gcp_instance_name: "{{ hostvars[inventory_hostname]['name'] }}"
  tasks:
    - name: Importing task for GCP Auth on localhost
      include_role:
        name: gcp_connectivity_role
    - name: Run remote command via SSH through IAP tunnel
      ansible.builtin.command: "uname -a"
      delegate_to: localhost

```

And my role gcp\_connectivity\_role

```auto
---
- name: Run GCP tasks via gcloud
  block:
    - name: Set facts from credential and vars
      ansible.builtin.set_fact:
        gcp_sa_json_file: "{{ lookup('env', 'gcp_sa_json') }}"
        gcp_impersonate_sa: "{{ lookup('env', 'gcp_sa_user_id') }}"

    - name: Check current authenticated service account
      shell: gcloud auth list --filter=status:ACTIVE --format="value(account)"
      register: current_auth
      delegate_to: localhost 

    - name: Authenticate only if not already authenticated
      shell: gcloud auth activate-service-account --key-file={{ gcp_sa_json_file }}
      when: current_auth.stdout.strip() != gcp_impersonate_sa
      register: auth_result
      failed_when: auth_result.rc != 0
     delegate_to: localhost 

    - name: Set the GCP project
      shell: gcloud config set project {{ gcp_project }}
      register: project_result
      failed_when: project_result.rc != 0
     delegate_to: localhost 

    - name: Connect to GCP instance via SSH
      shell: >
        gcloud compute ssh {{ gcp_instance_name }}
        --zone={{ gcp_zone }}
        --impersonate-service-account={{ gcp_impersonate_sa }}
        --command="hostname"
      register: ssh_result
      failed_when: ssh_result.rc != 0
     delegate_to: localhost 

```

So here I have couple of issues/challenges which I am facing.

1. delegate\_to: localhost is not working as expected. It should be executed in my custom execution pod but it is running on the target host, Not sure why.
2. I want to set the hostvars first being in target host, then switch to local for gcloud connection and then switch back to the target host to execute commands, How can we achieve this ? I tried several methods like connection: local , delegate\_to: localhost or 127.0.0.1 , nothing works. Please suggest how can we achieve this?

Thanks and Regards  
Saravana Selvaraj

---

<div class="post-metadata">

**Author:** ![SaravanaSelvaraj](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/saravanaselvaraj/32/2841_2.png) [@SaravanaSelvaraj](https://forum.ansible.com/u/SaravanaSelvaraj)\
**Post date:** [April 24, 2025, 2:33pm UTC](https://forum.ansible.com/t/delegate-to-localhost-is-not-working-as-expected/41995/2 "2025-04-24T14:33:37Z")

</div>

@kurokobo , Please help here as well if you can. I am really stuck with this

---

<div class="post-metadata">

**Author:** ![bcoca](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/bcoca/32/9269_2.png) [@bcoca](https://forum.ansible.com/u/bcoca)\
**Post date:** [April 24, 2025, 3:53pm UTC](https://forum.ansible.com/t/delegate-to-localhost-is-not-working-as-expected/41995/3 "2025-04-24T15:53:21Z")

</div>

What is the output of ` ansible-inventory --host localhost`?

---

<div class="post-metadata">

**Author:** ![SaravanaSelvaraj](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/saravanaselvaraj/32/2841_2.png) [@SaravanaSelvaraj](https://forum.ansible.com/u/SaravanaSelvaraj)\
**Post date:** [April 24, 2025, 4:07pm UTC](https://forum.ansible.com/t/delegate-to-localhost-is-not-working-as-expected/41995/4 "2025-04-24T16:07:50Z")

</div>

Hello @bcoca , thanks for the response , and this is the output

```auto
ansible-inventory --host localhost
[WARNING]: No inventory was parsed, only implicit localhost is available
{
    "ansible_connection": "local",
    "ansible_python_interpreter": "/usr/bin/python3"
}

```

And looks like this is working as expected and getting executed in the localhost. But Can you please help me with the below because it is a blocker as of now for me.

> [@Discrepancy Between Custom Image and AWX Execution Environment](https://forum.ansible.com/t/discrepancy-between-custom-image-and-awx-execution-environment/41993):
>
> Unusual behavior with custom EE. Dear Community, As part of AWX to gcloud connectivity I have built an image which has gcloud utility and set the PATH for the same. Below lines are responsible for the same in my dockerfile. RUN curl -O https://XXX.io/artifactory/ansible-store/google-cloud-sdk-470.0.0-linux-x86\_64.tar.gz && \ tar -xzf google-cloud-sdk-470.0.0-linux-x86\_64.tar.gz && \ ./google-cloud-sdk/install.sh --quiet && \ rm google-cloud-sdk-470.0.0-linux-x86\_64.tar.gz # Add …

---

<div class="post-metadata">

**Author:** ![bcoca](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/bcoca/32/9269_2.png) [@bcoca](https://forum.ansible.com/u/bcoca)\
**Post date:** [April 24, 2025, 4:25pm UTC](https://forum.ansible.com/t/delegate-to-localhost-is-not-working-as-expected/41995/5 "2025-04-24T16:25:47Z")

</div>

I’m sorry, i forgot to ask you to add the inventory you are using with `-i `

---

<div class="post-metadata">

**Author:** ![wayt](https://avatars.discourse-cdn.com/v4/letter/w/3be4f8/32.png) [@wayt](https://forum.ansible.com/u/wayt)\
**Post date:** [April 25, 2025, 5:25am UTC](https://forum.ansible.com/t/delegate-to-localhost-is-not-working-as-expected/41995/6 "2025-04-25T05:25:21Z")

</div>

An avenue I think may work for you is to use the `ProxyCommand` SSH configuration option. You should be able to siphon enough information from the [Putty documentation](https://cloud.google.com/compute/docs/connect/ssh-using-iap#putty-app) and `man 5 ssh_config` (search for `ProxyCommand`).

Pair this with a definition of the Ansible variable for each VM of of `ansible_ssh_args` for something like:

```yml
---
ansible_ssh_args: -o ProxyCommand='gcloud.cmd compute start-iap-tunnel VM_NAME PORT_NUMBER --listen-on-stdin --project=PROJECT_ID --zone=ZONE'

```

You’ll of course want to ensure the `gcloud CLI` is initialized / authenticated on the control node (pod in AWX) first. I’m not sure if delegating to `localhost` in `pre_tasks` will be enough in the case of AWX. You have have to do something first in the pod specification.

---

<div class="post-metadata">

**Author:** ![SaravanaSelvaraj](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/saravanaselvaraj/32/2841_2.png) [@SaravanaSelvaraj](https://forum.ansible.com/u/SaravanaSelvaraj)\
**Post date:** [April 25, 2025, 5:57am UTC](https://forum.ansible.com/t/delegate-to-localhost-is-not-working-as-expected/41995/7 "2025-04-25T05:57:30Z")

</div>

Sure @wayt , Thanks for the response and I will try it out. I am using dynamic inventory. My source is

```auto
---
projects:
  - XXX
  - XXXX 
hostnames:
  - name
compose:
  ansible_host: networkInterfaces[0].networkIP
  ansible_ssh_args: -o ProxyCommand='gcloud.cmd compute start-iap-tunnel VM_NAME PORT_NUMBER --listen-on-stdin --project=PROJECT_ID --zone=ZONE'
#use_extra_vars: true
# extra_vars.yml 
#extra_vars:
# foo: bar
keyed_groups:
  - key: labels
    prefix: label
  - key: zone
    prefix: zone
  - key: (tags.items|list)
    prefix: tag

```

After the sync I cannot see the ansible\_ssh\_args is added to all the hosts in the inventory. I tried to use extra\_vars and place it in a seperate line as well but it doesn’t work. Can you please let me know what I am missing here ?

---

<div class="post-metadata">

**Author:** ![wayt](https://avatars.discourse-cdn.com/v4/letter/w/3be4f8/32.png) [@wayt](https://forum.ansible.com/u/wayt)\
**Post date:** [April 25, 2025, 6:06am UTC](https://forum.ansible.com/t/delegate-to-localhost-is-not-working-as-expected/41995/8 "2025-04-25T06:06:00Z")

</div>

You’ll need to turn the parts of the `ProxyCommand` into variables that need to be like VM\_NAME might be:

```yaml
compose:
  ansible_ssh_args: >-
    “-o ProxyCommand=‘gcloud.cmd compute start-iap-tunnel {{ inventory_hostname }} 22 —listen-on-stdin —project={{ gcloud_project }} —zone={{ gcloud_zone }}”

```

You may have to do some fiddling with the compose syntax to get it to do the string substitution (maybe the `~` or `+` to combine the literal string sections with the variable parts.

You may also end up needing to look at a constructed inventory to define some parts or variables in a separate more static inventory that is merged with the data coming out of GCP if it gets to crazy with Jinja conditionals in your dynamic inventory.

---

<div class="post-metadata">

**Author:** ![wayt](https://avatars.discourse-cdn.com/v4/letter/w/3be4f8/32.png) [@wayt](https://forum.ansible.com/u/wayt)\
**Post date:** [April 25, 2025, 6:07am UTC](https://forum.ansible.com/t/delegate-to-localhost-is-not-working-as-expected/41995/9 "2025-04-25T06:07:05Z")

</div>

I would also advocate for starting with a simple pedantic case like an inventory in AWX directory or just a basic INI hosts file where you can confirm the pattern of `ProxyCommand` ends up working for your use case before spinning on a dynamic inventory.

---

<div class="post-metadata">

**Author:** ![SaravanaSelvaraj](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/saravanaselvaraj/32/2841_2.png) [@SaravanaSelvaraj](https://forum.ansible.com/u/SaravanaSelvaraj)\
**Post date:** [April 25, 2025, 6:58am UTC](https://forum.ansible.com/t/delegate-to-localhost-is-not-working-as-expected/41995/10 "2025-04-25T06:58:36Z")

</div>

> [@wayt](#):
>
> ```auto
> ansible_ssh_args: >-
> “-o ProxyCommand=‘gcloud.cmd compute start-iap-tunnel {{ inventory_hostname }} 22 —listen-on-stdin —project={{ gcloud_project }} —zone={{ gcloud_zone }}”
> 
> ```

Got it , I will explore the options. Thanks a lot !!

---

<div class="post-metadata">

**Author:** ![SaravanaSelvaraj](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/saravanaselvaraj/32/2841_2.png) [@SaravanaSelvaraj](https://forum.ansible.com/u/SaravanaSelvaraj)\
**Post date:** [April 25, 2025, 11:36am UTC](https://forum.ansible.com/t/delegate-to-localhost-is-not-working-as-expected/41995/11 "2025-04-25T11:36:15Z")

</div>

@wayt , I tried several ways to connect using ssh -o ProxyCommand but it does not work. Is this really works ?  
FYI, I am trying the below command

```auto
ssh -o ProxyCommand="gcloud compute start-iap-tunnel XXX-d-ubuntu24-usea1-1 22 --listen-on-stdin --project=XXX-b2b-d-XXXXX-us-1 --zone=us-east1-b --impersonate-service-account='XXXX@XXXXXXX.iam.gserviceaccount.com'" "XXXX@XXXXXXX.iam.gserviceaccount.com'"@10.XXX.XX.X

```

---

<div class="post-metadata">

**Author:** ![bartowl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/bartowl/32/7029_2.png) [@bartowl](https://forum.ansible.com/u/bartowl)\
**Post date:** [April 30, 2025, 7:36am UTC](https://forum.ansible.com/t/delegate-to-localhost-is-not-working-as-expected/41995/12 "2025-04-30T07:36:35Z")

</div>

> [@SaravanaSelvaraj](#):
>
> …  
> tasks:  
> - name: Importing task for GCP Auth on localhost  
> include\_role:  
> name: gcp\_connectivity\_role  
> - name: Run remote command via SSH through IAP tunnel  
> ansible.builtin.command: “uname -a”  
> delegate\_to: localhost  
> …

As for the initial post - the role prepares localhost environment to go to a single inventory\_host. This is partially correct. However, then from the playbook you issue `uname -a` on the localhost not on the remote host. In order to run the command on the remote host you would have to use `gcloud compute ssh ...` instead at every single step.

There is also another problem with your approach - typically ansible runs with 5 forks, meaning for 5 hosts commands are executed in parallel. So when each host tries to adjust the configuration on ansible controller to point to his own project, the same time it breaks the config for other hosts which may have just done that. So in order for your approach to work you would HAVE to either set serial 1 on the entire play or run the playbook with a single fork only. In both cases, this dramatically decreases performance and increases runtime especially with large inventories.

At the end - I would recommend to use the ProxyCommand approach, maybe set a dedicated script not to always put all the commands there. Call that script with only the required parameters that change and keep in mind, that ansible is by nature a parallel beast, where multiple hosts are processed in parallel, so when storing some state files make sure paths don’t collide among hosts.

---

<div class="post-metadata">

**Author:** ![SaravanaSelvaraj](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/saravanaselvaraj/32/2841_2.png) [@SaravanaSelvaraj](https://forum.ansible.com/u/SaravanaSelvaraj)\
**Post date:** [April 30, 2025, 8:33am UTC](https://forum.ansible.com/t/delegate-to-localhost-is-not-working-as-expected/41995/13 "2025-04-30T08:33:39Z")

</div>

Thank you for the response . These points are noted.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/ansible/original/1X/1882d9a01da5d8996a862359b0913cc568a39b84.svg) [@system](https://forum.ansible.com/u/system)\
**Post date:** [May 30, 2025, 8:34am UTC](https://forum.ansible.com/t/delegate-to-localhost-is-not-working-as-expected/41995/14 "2025-05-30T08:34:38Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
