Google Cloud
terradart_google wraps the whole GA hashicorp/google catalog — every resource and data source — and terradart_google_beta adds the types that exist only in hashicorp/google-beta (Firebase app registration, preview services). A type that is also in GA stays in terradart_google. Both are generated from the provider schema and the Magic Modules definitions Google publishes, so enums, exactly-one-of groups and resource references carry over as Dart types.
Install
Section titled “Install”dependencies: terradart_core: ^0.35.0 terradart_google: ^0.35.0 terradart_google_beta: ^0.35.0 # only for beta-only typesCredentials
Section titled “Credentials”GoogleProvider takes no key, so credentials never enter the synthesized JSON, and synth needs none. terradart plan and terradart apply authenticate with Application Default Credentials (gcloud auth application-default login), or a service account in CI. With them in place, terradart apply synthesizes the Stack and applies it.
Imports
Section titled “Imports”Each Google service is its own barrel, so IDE completion stays scoped to what a file uses: package:terradart_google/cloud_run.dart, pubsub.dart, bigquery.dart, compute.dart, and so on, plus provider.dart for GoogleProvider. The Google Cloud coverage page lists every factory with its barrel and a runnable example. package:terradart_google/terradart_google.dart still re-exports everything.
Enabling APIs
Section titled “Enabling APIs”A fresh project has most APIs off. enableApis registers a google_project_service for every API the factories of the given barrels need, plus a propagation wait (TimeSleep from terradart_time) that resources depend on:
import 'package:terradart_google/project.dart';import 'package:terradart_google/provider.dart';import 'package:terradart_google/pubsub.dart';import 'package:terradart_time/terradart_time.dart';
final class EventsStack extends Stack { EventsStack({required String projectId}) : super(providers: [GoogleProvider(project: projectId), const TimeProvider()]) { final apis = enableApis( [.pubsub]); add(GooglePubsubTopic( 'events', name: .literal('events'), dependsOn: apis, )); }}IAM grants
Section titled “IAM grants”An IAM adjunct takes its parent as a reference (bucket: uploads.ref) and who the grant is for as an IamPrincipal. A service account, a service agent or a default service account data source hands out its own as principal; anyone else takes the constructor of their kind: .user(email), .group(email), .serviceAccount(email), .domain(domain), .allUsers, .allAuthenticatedUsers, or .principalSet(pool, attribute) for Workload Identity Federation.
final runtime = add( GoogleServiceAccount('runtime', accountId: .literal('runtime')),);final uploads = add( GoogleStorageBucket( 'uploads', name: .literal('uploads'), location: .literal('US'), ),);add( GoogleStorageBucketIamMember( 'runtime_writer', bucket: uploads.ref, role: .literal('roles/storage.objectCreator'), member: runtime.principal, ),);add( GoogleStorageBucketIamBinding( 'admins', bucket: uploads.ref, role: .literal('roles/storage.admin'), ),);GA and beta in one Stack (Firebase + Google Cloud)
Section titled “GA and beta in one Stack (Firebase + Google Cloud)”You can seamlessly combine Google Cloud GA resources (terradart_google) with beta-only resources (terradart_google_beta, such as Firebase project configuration and Web App registration) in a single Stack:
graph TB
subgraph Client["Firebase App (Beta)"]
WebApp["GoogleFirebaseWebApp<br/>(Frontend Client)"]
end
subgraph GCP["Google Cloud Infrastructure (GA)"]
CloudRun["GoogleCloudRunV2Service<br/>(Backend API)"]
Firestore["GoogleFirestoreDatabase<br/>(Native Mode / (default))"]
Storage["GoogleStorageBucket<br/>(User Uploads)"]
CloudRun -->|Read/Write Data| Firestore
CloudRun -->|Store Assets| Storage
end
WebApp -.REST API Calls.-> CloudRun
dependencies: terradart_core: ^0.35.0 terradart_google: ^0.35.0 terradart_google_beta: ^0.35.0// GA: Google Cloud backend infrastructureimport 'package:terradart_google/cloud_run.dart';import 'package:terradart_google/firestore.dart';import 'package:terradart_google/provider.dart';import 'package:terradart_google/storage.dart';// Beta: Firebase project and app registrationimport 'package:terradart_google_beta/firebase.dart';import 'package:terradart_google_beta/provider.dart';
final class MobileAppBackendStack extends Stack { MobileAppBackendStack({required String projectId}) : super( providers: [ GoogleProvider(project: projectId, region: 'asia-northeast1'), GoogleBetaProvider(project: projectId, region: 'asia-northeast1'), ], ) { // 1. [Beta] Enable Firebase on the project final fb = add(GoogleFirebaseProject( 'firebase', project: .literal(projectId), ));
// 2. [Beta] Register Firebase client app add(GoogleFirebaseWebApp( 'web_client', displayName: .literal('Web Client'), project: .literal(projectId), dependsOn: [fb], ));
// 3. [GA] Firestore Database (Native mode) final db = add(GoogleFirestoreDatabase( 'db', name: .literal('(default)'), locationId: .literal('asia-northeast1'), type: .firestoreNative, dependsOn: [fb], ));
// 4. [GA] Cloud Storage for user uploads final uploadsBucket = add(GoogleStorageBucket( 'uploads', name: .literal('$projectId-uploads'), location: .literal('ASIA-NORTHEAST1'), storageClass: .standard, uniformBucketLevelAccess: .literal(true), ));
// 5. [GA] Cloud Run v2 backend service add(GoogleCloudRunV2Service( 'api', name: .literal('api-server'), location: .literal('asia-northeast1'), template: CloudRunV2ServiceTemplate( containers: [ .new( name: .literal('server'), image: .literal( 'us-docker.pkg.dev/cloudrun/container/hello', ), env: [ .new( name: .literal('UPLOAD_BUCKET'), source: .value(uploadsBucket.name), ), ], ), ], ), dependsOn: [db], )); }}Wrappers from terradart_google_beta automatically attach provider = "google-beta" in the synthesized Terraform JSON. See the complete runnable recipe in cookbook/firebase-app-backend.
Several provider configurations
Section titled “Several provider configurations”Every factory also takes a provider: parameter — Terraform’s provider meta-argument. Register a second configuration of a provider with alias: through addProvider, which returns the instance, and pass that instance per resource; everything else keeps using the default configuration:
final class MultiRegionStack extends Stack { MultiRegionStack({required String projectId}) : super(providers: [ GoogleProvider(project: projectId, region: 'asia-northeast1'), ]) { final eu = addProvider( GoogleProvider(alias: 'eu', project: projectId, region: 'europe-west1'), ); add(GoogleStorageBucket( 'assets_eu', name: .literal('my-app-assets-eu'), location: .literal('EUROPE-WEST1'), provider: eu, // provider = google.eu )); }}Synth emits provider.google as a list when a name has more than one configuration, and rejects a provider: instance the Stack does not register (an equal-looking copy included, since its settings may differ). A registered GoogleBetaProvider passed as provider: on a GA-catalog factory puts that one resource on the beta provider.
Examples
Section titled “Examples”Every Google quickstart is synthesized and validated against the provider in CI:
- Foundational & IAM: Pub/Sub, Cloud Tasks, Secret Manager, IAM
- Compute & Networking: Compute & Firewall, GKE, Cloud DNS
- Data & Storage: Cloud Storage, BigQuery, Cloud Bigtable, KMS
- Application Platform: Cloud Run v2, Cloud Monitoring, Workflows, Eventarc
- AI & Agents: Vertex AI, Agentic Applications
Full applications, infrastructure and app together, are in the cookbook: single-project-app (Cloud Run + Cloud SQL), firebase-app-backend, lunch-concierge.
Reference
Section titled “Reference”- Coverage — every Google factory, its barrel and its example
terradart_googleAPI docs andterradart_google_betaAPI docs