繁体   English   中英

如何通过 terraform 使用服务帐户创建谷歌云 pubsub 拉取订阅?

[英]How to create a google cloud pubsub pull subscriptions with service account by terraform?

google_pubsub_subscription的 terraform 文档中,它提到在push_configuration下有一个oidc_token属性允许推送订阅使用服务帐户,但没有提到如何使用服务帐户进行请求订阅

如何明确设置在创建pull pubsub 订阅期间要使用的服务帐户?

我尝试添加oidc_token块,但它没有工作,因为它不直接期望该块。

设想:

  1. 我有一个服务帐户可以访问Project_A中的 pubsub 主题(以及附加订阅的必要权限)
  2. 我想在 terraform 的Project_B中创建对这些主题的订阅。
  3. 我需要在 terraform 中明确使用此服务帐户,因此我可以在Project_B 上创建对 Project_A主题的订阅

例如, google_cloudfunctions_function资源有一个名为 service_account_email 的字段,用于设置服务帐户。 但是没有用于google_pubsub_subscription资源,用于文档中的请求订阅

实际上,服务帐户 ( service_account_email ) 将在oidc_token部分内指定(您必须在文档中进一步指定 go :)

下面是带有服务帐户和受众(可选)的推送订阅的工作示例

variable "project" {
  type = string
  default = "<YOUR_PROJECT_ID>"
}

resource "google_pubsub_topic" "example" {
  project = var.project
  name = "example-topic"
}

resource "google_pubsub_subscription" "example" {
  project = var.project
  name  = "example-push-subscription-with-auth"
  topic = google_pubsub_topic.example.name

  push_config {
    push_endpoint = "https://example.com/push"
    oidc_token {
      service_account_email = "${var.project}@appspot.gserviceaccount.com"
      audience = "https://example.com/push"
    }

  }
}

我正在添加另一个答案,因为在不同的评论之后问题发生了很大变化。

这是假设主题topic-sof已经在与订阅项目不同的项目中创建的解决方案。

  1. 我在订阅项目上创建了一个服务帐户 (SA),我将其命名为stackoverflow-playground-sa并只赋予它Pub/Sub Editor角色,如下面的屏幕截图所示。 在此处输入图像描述

  2. 我为 SA 授予了主题topic-sof上的Pub/Sub Subscriber角色,如下面的屏幕截图所示。 如果您不执行此步骤:您将在 terraform apply 收到此错误

 Error: Error creating Subscription: googleapi: Error 403: User not authorized to perform this action

在此处输入图像描述

当然,我与一个对两个项目都有足够权限的用户一起完成了角色分配的前两个步骤

  1. 我为我的 SA 创建了一个 json 密钥文件并下载到/path/to/my/key/stackoverflow-playground-sa.json

  2. 我使用身份验证为我的 SA

export GOOGLE_APPLICATION_CREDENTIALS=/path/to/my/key/stackoverflow-playground-sa.json

因此 terraform 可以使用它来创建订阅。

  1. 这是创建订阅的 terraform 配置
variable "subscription_project" {
  type = string
  default = "<YOUR_SUBSCRIPTION_PROJECT>"
}

variable "topic_project" {
  type = string
  default = "<YOUR_TOPIC_PROJECT>"
}

resource "google_pubsub_subscription" "pull-subscription-of-topic-in-another-project" {
  project = var.subscription_project
  name  = "pull-subscription-of-topic-in-another-project"
  topic = "projects/${var.topic_project}/topics/topic-sof"
}
  1. 运行 ( apply ) my terraform 并创建订阅pull-subscription-of-topic-in-another-project并附加到另一个项目中的主题topic-sof

  2. 我使用 web ui 向topic-sof发布了一条消息。

  3. 由于第 4 步,我仍然被认证为stackoverflow-playground-sa ,我拉取消息(在我的 treminal 中使用 gcloud)et voilà 消息收到: 在此处输入图像描述

总而言之:在您的 terraform 配置中没有要为此要求指定的服务帐户。 服务帐户及其密钥设置在 terraform 之外(步骤 1 到 4),以便 terraform 进程可以通过身份验证和授权来创建配置的资源(在我们的例子中是订阅)。 除了在第 4 步中使用服务帐户密钥之外,出于安全考虑,这是一种不好的做法。 另一种方法是使用

gcloud auth application-default login

这将使您可以设置您选择的用户的默认凭据。 鉴于该用户具有我为 SA 设置的角色。

暂无
暂无

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

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