You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitHub Actions+Terraform+GCP:Runner权限与服务账号集成问题

GitHub Actions + Terraform + GCP 权限问题排查与解决

背景

我正在用GitHub Actions搭建CI/CD流水线,已通过Terraform完成GCP基础设施部署,使用以下Action完成GCP认证:

- id: 'auth'
  name: 'Authenticate to Google Cloud'
  uses: 'google-github-actions/auth@v1'
  with:
    service_account: 'my-service-account@my-project.iam.gserviceaccount.com'

当前计划通过Terraform的local_file资源自动生成Ansible清单文件,配置如下:

resource "local_file" "hosts_cfg" {
  content = templatefile("${path.module}/templates/hosts.tpl",
    {
      target_hosts = module.target_hosts.external_ips
    }
  )
  filename = "/etc/ansible/hosts"
}

执行terraform apply时出现权限错误:

│ Error: Create local file error
│ 
│   with local_file.hosts_cfg,
│   on main.tf line 183, in resource "local_file" "hosts_cfg":
│  183: resource "local_file" "hosts_cfg" {
│ 
│ An unexpected error occurred while writing the file
│ 
│ +Original Error: open /etc/ansible/hosts: permission denied
╵
Error: Process completed with exit code 1.

改用sudo terraform apply后,又出现GCP认证错误:

╷
│ Error: storage.NewClient() failed: dialing: google: could not find default credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information.
│ 
│ 
╵
Error: Process completed with exit code 1.

疑问解答

1. 用google-github-actions/auth@v1认证后,为什么还是没法在/etc/目录创建文件?

google-github-actions/auth仅负责给Runner进程赋予GCP服务账号的云操作权限,这和Runner本身的系统权限是完全独立的两个概念。GitHub Runner默认以普通系统用户(比如Ubuntu runner中的runner用户)身份运行,而/etc/是系统级保护目录,普通用户没有写入权限,因此无论GCP认证是否成功,都无法直接写入该目录。

2. 用sudo为什么反而丢了GCP凭证?

sudo会切换到root用户的独立环境,而google-github-actions/auth是将GCP凭证注入到当前普通用户的环境变量或默认凭证路径中。切换到root后,这些环境变量不会被自动继承,且root用户的默认凭证路径与普通用户不同,导致Terraform无法找到GCP凭证,进而无法访问状态存储桶。

3. GitHub Runner的权限和Terraform用的服务账号权限是什么关系?

两者是完全独立的权限体系:

  • GitHub Runner的权限:指Runner进程在宿主机器上的系统操作权限(如读写文件、执行命令),由运行Runner的操作系统用户身份决定。
  • Terraform服务账号权限:指Terraform操作GCP资源时的云服务权限,由GCP服务账号绑定的IAM角色决定。
    GCP服务账号权限无法干预Runner的系统操作,Runner的系统权限也不影响GCP资源的访问(只要凭证有效)。

4. 怎么让Runner既能写系统目录,又能正常用GCP服务账号权限?

有两种可行方案:

  • 方案1:拆分Terraform输出与文件复制
    不要让Terraform直接写入/etc/ansible/hosts,改为输出到Runner有权限的目录(如当前工作目录),之后单独用sudo cp命令将文件复制到系统目录。这样Terraform无需sudo,GCP凭证可正常使用:

    1. 修改Terraform配置:
      resource "local_file" "hosts_cfg" {
        content = templatefile("${path.module}/templates/hosts.tpl",
          {
            target_hosts = module.target_hosts.external_ips
          }
        )
        filename = "${path.module}/ansible_hosts"
      }
      
    2. 在GitHub Actions中添加复制步骤:
      - name: Copy Ansible hosts file to system directory
        run: sudo cp ./ansible_hosts /etc/ansible/hosts
      
  • 方案2:用sudo传递环境变量
    如果必须让Terraform直接写入系统目录,可使用sudo -E terraform apply命令,-E参数会保留当前用户的环境变量,GCP凭证相关的环境变量(如GOOGLE_APPLICATION_CREDENTIALS)会被传递给root用户,Terraform就能找到凭证。但需注意,root环境下运行Terraform可能带来额外安全风险。


内容的提问来源于stack exchange,提问作者SkogensKonung

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 18:23:17