# #google-cloud-platform #terraform #google-cloud-pubsub #terraform-provider-gcp
Вопрос:
У меня есть следующая настройка в облаке Google:
- приложение «генератор», которое публикует сообщения в теме Google Cloud PubSub.
- приложение «рабочий», которое использует уникальное сообщение.
- любые недопустимые сообщения PubSub должны заканчиваться в теме «мертвая буква».
В этой теме должна быть тема «мертвая буква», в которой заканчиваются недопустимые сообщения. Однако всякий раз, когда я настраиваю это с помощью Terraform, облачная консоль Google упоминает, что у меня нет ролей «подписчик» и «издатель», прикрепленных к моей учетной записи службы project pubsub:
У меня есть следующая конфигурация терраформы, которая кажется правильной AFAIK:
resource "google_project_service_identity" "pubsub_sa" {
provider = google-beta
project = var.project_id
service = "pubsub.googleapis.com"
}
/* ... topic and dead-letter topic config here ... */
data "google_iam_policy" "project_pubsub_publishers" {
binding {
role = "roles/pubsub.publisher"
members = [
"serviceAccount:${google_service_account.project_generator_serviceaccount.email}",
"serviceAccount:${google_service_account.project_worker_serviceaccount.email}",
"serviceAccount:${google_project_service_identity.pubsub_sa.email}",
]
}
}
resource "google_pubsub_topic_iam_policy" "project_request_publishers" {
project = var.project_id
topic = google_pubsub_topic.generator_request_pubsub.name
policy_data = data.google_iam_policy.project_pubsub_publishers.policy_data
}
data "google_iam_policy" "project_pubsub_subscribers" {
binding {
role = "roles/pubsub.subscriber"
members = [
"serviceAccount:${google_service_account.project_generator_serviceaccount.email}",
"serviceAccount:${google_service_account.project_worker_serviceaccount.email}",
"serviceAccount:${google_project_service_identity.pubsub_sa.email}",
]
}
}
resource "google_pubsub_topic_iam_policy" "project_request_subscribers" {
topic = google_pubsub_topic.generator_request_pubsub.name
project = var.project_id
policy_data = data.google_iam_policy.project_pubsub_subscribers.policy_data
}
Нажав «Добавить» в веб-интерфейсе, а затем выполнив terraform plan
следующие изменения:
Terraform will perform the following actions:
# module.gcloud.google_pubsub_topic_iam_policy.project_invalid_request_publishers will be updated in-place
~ resource "google_pubsub_topic_iam_policy" "project_invalid_request_publishers" {
id = "projects/MY-GCLOUD-PROJECTID/topics/generator-request-pubsub-invalid"
~ policy_data = jsonencode(
~ {
~ bindings = [
~ {
~ members = [
"serviceAccount:cicd-generator-sa@MY-GCLOUD-PROJECTID.iam.gserviceaccount.com",
"serviceAccount:cicd-worker-sa@MY-GCLOUD-PROJECTID.iam.gserviceaccount.com",
"serviceAccount:service-251572179467@gcp-sa-pubsub.iam.gserviceaccount.com",
]
# (1 unchanged element hidden)
},
- {
- members = [
- "serviceAccount:cicd-generator-sa@MY-GCLOUD-PROJECTID.iam.gserviceaccount.com",
- "serviceAccount:cicd-worker-sa@MY-GCLOUD-PROJECTID.iam.gserviceaccount.com",
- "serviceAccount:service-251572179467@gcp-sa-pubsub.iam.gserviceaccount.com",
]
- role = "roles/pubsub.subscriber"
},
]
}
)
# (3 unchanged attributes hidden)
}
# module.gcloud.google_pubsub_topic_iam_policy.project_invalid_request_subscribers will be updated in-place
~ resource "google_pubsub_topic_iam_policy" "project_invalid_request_subscribers" {
id = "projects/MY-GCLOUD-PROJECTID/topics/generator-request-pubsub-invalid"
~ policy_data = jsonencode(
~ {
~ bindings = [
- {
- members = [
- "serviceAccount:service-251572179467@gcp-sa-pubsub.iam.gserviceaccount.com",
]
- role = "roles/pubsub.publisher"
},
{
members = [
"serviceAccount:cicd-generator-sa@MY-GCLOUD-PROJECTID.iam.gserviceaccount.com",
"serviceAccount:cicd-worker-sa@MY-GCLOUD-PROJECTID.iam.gserviceaccount.com",
"serviceAccount:service-251572179467@gcp-sa-pubsub.iam.gserviceaccount.com",
]
role = "roles/pubsub.subscriber"
},
]
}
)
# (3 unchanged attributes hidden)
}
# module.gcloud.google_pubsub_topic_iam_policy.project_request_subscribers will be updated in-place
~ resource "google_pubsub_topic_iam_policy" "project_request_subscribers" {
id = "projects/MY-GCLOUD-PROJECTID/topics/generator-request-pubsub"
~ policy_data = jsonencode(
~ {
~ bindings = [
~ {
~ role = "roles/pubsub.publisher" -> "roles/pubsub.subscriber"
# (1 unchanged element hidden)
},
]
}
)
# (3 unchanged attributes hidden)
}
Но я не уверен, что я здесь делаю не так. Есть какие-нибудь идеи?
Ответ №1:
В соответствии с документацией, кажется, что вам нужно сначала фактически настроить конфигурацию для «мертвой темы» в GCP.
Установка темы с мертвой буквой
В котором (среди некоторой другой информации) говорится, что:
Чтобы создать подписку и задать тему с мертвой буквой, используйте команду создания подписок gcloud pubsub:
gcloud pubsub subscriptions create subscription-id
--topic=topic-id
--dead-letter-topic=dead-letter-topic-id
[--max-delivery-attempts=max-delivery-attempts]
[--dead-letter-topic-project=dead-letter-topic-project]
Чтобы обновить подписку и задать тему с мертвой буквой, используйте команду обновления подписок gcloud pubsub:
gcloud pubsub subscriptions update subscription-id
--dead-letter-topic=dead-letter-topic-id
[--max-delivery-attempts=max-delivery-attempts]
[--dead-letter-topic-project=dead-letter-topic-project]
Предоставление разрешений на пересылку
Чтобы пересылать недоставленные сообщения в тему с мертвыми буквами, Pub/Sub должен иметь разрешение на выполнение следующих действий:
Публикуйте сообщения в этой теме.
Подтвердите сообщения, что удалит их из подписки.
Pub/Sub создает и поддерживает учетную запись службы для каждого проекта: service-project-number@gcp-sa-pubsub.iam.gserviceaccount.com
. Вы можете предоставить разрешения на пересылку, назначив этой учетной записи службы роли издателя и подписчика. Если вы настроили подписку с помощью Облачной консоли, роли предоставляются автоматически.
Назначение Pub/Sub роли издателя
Чтобы предоставить Pub/Sub разрешение на публикацию сообщений в теме с мертвой буквой, выполните следующую команду:
PUBSUB_SERVICE_ACCOUNT="service-${project-number}@gcp-sa-pubsub.iam.gserviceaccount.com"
gcloud pubsub topics add-iam-policy-binding dead-letter-topic-id
--member="serviceAccount:$PUBSUB_SERVICE_ACCOUNT"
--role="roles/pubsub.publisher"
Назначение Pub/Sub роли подписчика
Чтобы предоставить Pub/Sub разрешение на подтверждение пересылаемых недоставленных сообщений, выполните следующую команду:
PUBSUB_SERVICE_ACCOUNT="service-${project-number}@gcp-sa-pubsub.iam.gserviceaccount.com"
gcloud pubsub subscriptions add-iam-policy-binding subscription-id
--member="serviceAccount:$PUBSUB_SERVICE_ACCOUNT"
--role="roles/pubsub.subscriber"
Надеюсь, это будет полезно для вас.
С уважением.
Комментарии:
1. Привет, Джейме, не уверен, как это поможет, так как мой вопрос касается конкретной формы, но спасибо, что вмешался! Интересно, что пользователь «pubsub_sa», который включен в обе роли, является учетной записью службы: « ресурс «google_project_service_identity» «pubsub_sa» { поставщик = проект google-бета = var.project_id службы = «pubsub.googleapis.com» } «
Ответ №2:
Хайме прав, вам нужно добавить эти политики IAM в
"service-${project-number}@gcp-sa-pubsub.iam.gserviceaccount.com"
Это специфический sa, скрытый от основных. Вы можете найти его в консоли в разделе >IAM и установить флажок в правом верхнем углу «>включить предоставленные Google роли».
Там также необходимо добавить a google_pubsub_topic_iam_policy
.
Вот рабочий пример терраформирования
data "google_project" "current" {}
data "google_iam_policy" "publisher" {
binding {
role = "roles/pubsub.publisher"
members = [
"serviceAccount:service-${data.google_project.current.number}@gcp-sa-pubsub.iam.gserviceaccount.com",
]
}
}
resource "google_pubsub_topic_iam_policy" "policy" {
project = var.project
topic = google_pubsub_topic.yourTopic.name
policy_data = data.google_iam_policy.publisher.policy_data
}
data "google_iam_policy" "subscriber" {
binding {
role = "roles/pubsub.subscriber"
members = [
"serviceAccount:service-${data.google_project.current.number}@gcp-sa-pubsub.iam.gserviceaccount.com",
]
}
}
resource "google_pubsub_subscription_iam_policy" "policy" {
subscription = google_pubsub_subscription.yourSubscription.name
policy_data = data.google_iam_policy.subscriber.policy_data
}