Nullstone app module that provisions a Google Cloud Composer (managed Apache Airflow) environment.
- Contract:
app:serverless/gcp/composer - Tool: OpenTofu
- A Cloud Composer 3 environment (
google_composer_environment), private by default, with configurable size, Airflow image version, PyPI packages, and Airflow config overrides. - An app runtime service account that the environment runs as. Capability
bindings (e.g.
secretmanager.secretAccessor,bigquery.dataEditor) target this SA so DAGs inherit those grants. Grantedroles/composer.worker. - A deployer service account (impersonated by the Nullstone agent) with
roles/composer.environmentAndStorageObjectAdminto manage the environment and read its config. - A pusher service account (impersonated by the Nullstone agent) with
roles/storage.objectAdminon the environment's DAG bucket, used to sync DAG files togs://<bucket>/dags. - A log reader service account with
roles/logging.viewer. - IAM for the Cloud Composer service agent (
roles/composer.ServiceAgentV2Ext), required for environments that run as a user-managed service account.
The environment is private by default (enable_private_environment = true)
and reaches the connected VPC through a Composer 3 Private Service Connect
network attachment, auto-created from the network connection's VPC and private
subnetwork. Because the environment sits on the private network, DAGs can reach:
- Internal Kubernetes services on the cluster — via internal load balancers / internal ingress published on the same VPC.
- A Cloud SQL Postgres instance — via its private IP / the network's Private
Service Access range. The app runtime SA is granted
roles/cloudsql.clientso DAGs can open connections through the Cloud SQL connector / IAM auth; database credentials are injected by an attachedgcp-postgres-accesscapability.
Internet egress (e.g. for pip installs of pypi_packages) flows through the
network's Cloud NAT.
Note: this gives DAGs network access to internal service endpoints. Driving the Kubernetes API itself (e.g.
KubernetesPodOperatoragainst the cluster) additionally requires a cluster connection andcontainer-level IAM — open an issue / extend the module if you need that.
env_varsare injected as Airflow environment variables (software_config.env_variables).secrets(and capability secrets) are stored in GCP Secret Manager and the Airflow Secret Manager backend is configured automatically. A secret namedKEYis stored as<environment_name>-KEY; a DAG resolves it withVariable.get("KEY").- Standard
NULLSTONE_*andGOOGLE_CLOUD_*variables are injected automatically.
Composer apps are deployed by syncing DAG files to the environment's GCS bucket
(dag_gcs_prefix, e.g. gs://<bucket>/dags). The pusher service account has
storage.objectAdmin on that bucket to perform the sync, and the deployer
service account manages the environment itself.
| Name | Contract | Purpose |
|---|---|---|
| network | network/gcp/vpc |
VPC + private subnetwork for the environment |