繁体   English   中英

Ansible GCP IAP隧道

[英]Ansible GCP IAP tunnel

我正在尝试通过 IAP 连接到 GCP 计算实例。 我有一个具有权限的服务帐户。

我试过以下

  1. 基本 ansible ping, ansible -vvvv GCP -m ping ,这是因为找不到主机名 bc 我没有外部 ip
  2. 我在这里设置ssh_executeable=wrapper.sh

2 号几乎可以工作,但正则表达式命令很麻烦。

有没有原生的ansible解决方案?

编辑: gcp_compute 动态清单确实适用于 ping 实例,但不适用于管理实例。

Ansible 在通过 IAP 隧道时不支持 package 或系统管理。

除非所有库存都可以公开访问,否则 gce 动态库存不起作用。 对于私有 ip,执行 ansible 命令时不会调用隧道。 gce 动态库存将返回库存,但如果仅在隧道和私有 IP 后面,您实际上无法发送命令。 我能找到的唯一解决方法是将 ssh 二进制点放在调用 gcloud 包装器的自定义脚本中。

对于那些仍在寻找在内部 IP 上使用 IAP SSH 和 Ansible 的解决方案的人。 我对此处列出的脚本进行了一些更改

我的主要问题是我必须添加 --zone 作为选项,因为gcloud在通过 Ansible 运行时不会自动检测到这一点。 因为我不想调用 CLI,增加更多等待时间,所以我选择使用 group_vars 来设置我的 ssh 选项。 这也允许我为gcloud compute ssh命令指定其他选项。

以下是设置所需文件的内容:

ansible.cfg

[inventory]
enable_plugins = gcp_compute

[defaults]
inventory = misc/inventory.gcp.yml
interpreter_python = /usr/bin/python

[ssh_connection]
# Enabling pipelining reduces the number of SSH operations required
# to execute a module on the remote server.
# This can result in a significant performance improvement 
# when enabled.
pipelining = True
scp_if_ssh = False
ssh_executable = misc/gcp-ssh-wrapper.sh
ssh_args = None

杂项/gcp-ssh-wrapper.sh

#!/bin/bash
# This is a wrapper script allowing to use GCP's IAP SSH option to connect
# to our servers.

# Ansible passes a large number of SSH parameters along with the hostname as the
# second to last argument and the command as the last. We will pop the last two
# arguments off of the list and then pass all of the other SSH flags through
# without modification:
host="${@: -2: 1}"
cmd="${@: -1: 1}"

# Unfortunately ansible has hardcoded ssh options, so we need to filter these out
# It's an ugly hack, but for now we'll only accept the options starting with '--'
declare -a opts
for ssh_arg in "${@: 1: $# -3}" ; do
        if [[ "${ssh_arg}" == --* ]] ; then
                opts+="${ssh_arg} "
        fi
done

exec gcloud compute ssh $opts "${host}" -- -C "${cmd}"

group_vars/all.yml

---
ansible_ssh_args: --tunnel-through-iap --zone={{ zone }} --no-user-output-enabled --quiet

如您所见,通过使用 group_vars 中的 ansible_ssh_args,我们现在可以通过清单中已知的区域。

如果您还希望能够通过 gcloud 命令复制文件,可以使用以下配置:

ansible.cfg

[ssh_connection]
# Enabling pipelining reduces the number of SSH operations required to
# execute a module on the remote server. This can result in a significant
# performance improvement when enabled.
pipelining = True
ssh_executable = misc/gcp-ssh-wrapper.sh
ssh_args = None
# Tell ansible to use SCP for file transfers when connection is set to SSH
scp_if_ssh = True
scp_executable = misc/gcp-scp-wrapper.sh

杂项/gcp-scp-wrapper.sh

#!/bin/bash
# This is a wrapper script allowing to use GCP's IAP option to connect
# to our servers.

# Ansible passes a large number of SSH parameters along with the hostname as the
# second to last argument and the command as the last. We will pop the last two
# arguments off of the list and then pass all of the other SSH flags through
# without modification:
host="${@: -2: 1}"
cmd="${@: -1: 1}"

# Unfortunately ansible has hardcoded scp options, so we need to filter these out
# It's an ugly hack, but for now we'll only accept the options starting with '--'
declare -a opts
for scp_arg in "${@: 1: $# -3}" ; do
        if [[ "${scp_arg}" == --* ]] ; then
                opts+="${scp_arg} "
        fi
done

# Remove [] around our host, as gcloud scp doesn't understand this syntax
cmd=`echo "${cmd}" | tr -d []`

exec gcloud compute scp $opts "${host}" "${cmd}"

group_vars/all.yml

---
ansible_ssh_args: --tunnel-through-iap --zone={{ zone }} --no-user-output-enabled --quiet
ansible_scp_extra_args: --tunnel-through-iap --zone={{ zone }} --quiet

不是对 OP 的直接回答,但是在我对如何保证我的项目安全(通过 IAP)并让 ansible 以合理的速度工作之后,我最终得到了 IAP 和操作系统登录的混合。 如果需要,这将继续使用动态库存。

我在我的虚拟机上使用 IAP 并且没有公共 IP,然后我在项目范围内启用了 OS Login 并且我在项目内部创建了一个小型“ansible-server”虚拟机(这是一个 WIP,因为最后是配对的 VPC项目应该 CI/CD ansible 但这是另一个故事)。

  • 在虚拟机内部,我通过以下方式设置了专用服务帐户的身份

gcloud auth activate-service-account name@project.iam.gserviceaccount.com --key-file=/path/to/sa/json/key

  • 然后我创建了一对 ssh 键
  • 我已经通过导出公钥启用 SA 登录

gcloud compute os-login ssh-keys add --key-file ~/.ssh/my-sa-public-key

  • 我从 VM 中运行我的所有剧本,将 -u 开关传递给 ansible。 这非常快,让我通过 IAM 撤销任何权限,避免浮动 ssh 密钥被遗弃到项目或 VM 元数据中。

所以现在的流程是:

  • 我使用 IAP 从我的工作站登录到项目内的 ansible VM
  • 我在 VM 中克隆 ansible 存储库
  • 我冒充 SA 运行 ansible

注意事项:

  • 获取正确的用户名以传递给 ansible(通过 -u)记录上一个 os-login 命令提供的用户名(它出现在添加密钥的 output 中,在我的情况下是类似 sa_[0-9]* )
  • 确保 SA 具有服务帐户用户和操作系统管理员登录 IAM 角色,否则 ssh 将失败
  • 当然,这意味着您必须在专用于 ansible 的项目中保留一个 VM,并且您还需要将 ansible 代码克隆到 VM 中。 就我而言,我缓解了“问题”,只需按需打开/关闭虚拟机,并使用相同的公钥授予对 ansible 存储库的只读访问权限(在我的情况下是 bitbucket)

(按照 OP 的要求将我的评论转换为答案)

Ansible 有一个本地 gce 动态清单插件,您应该使用它来连接到您的实例。

为了使 lotjuh 的答案起作用,我还必须更新我的 inventory.gcp.yml 文件以具有以下内容

plugin: gcp_compute
projects:
  - myproject
auth_kind: application
hostnames:
  - name

没有hostnames: - name我收到 gcloud ssh 错误,因为它尝试使用其主机 IP 将 ssh 插入实例。

这种方法还需要在 gcloud config 中使用gcloud config set project myproject

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM