Date: 2026-05-11
Time: 15:50
This is a GCP infrastructure provisioning example demonstrating FTL2's cloud provisioning workflow end-to-end: creating networking resources (VPC, subnet, firewall rules), provisioning a Compute Engine instance, dynamically registering it as a managed host, and then configuring it remotely — all in a single async Python script. It showcases FTL2's ability to bridge infrastructure provisioning and configuration management in one unified flow.
The script follows FTL2's standard async automation pattern:
async with automation(
secret_bindings=bindings,
state_file=".ftl2-gcp-state.json",
verbose=True,
) as ftl:
# Provision infrastructure via collection modules
network = await ftl.google.cloud.gcp_compute_network(name="...", state="present")
# Chain outputs between resources
subnet = await ftl.google.cloud.gcp_compute_subnetwork(
network=network.output["selfLink"], ...
)
# Register provisioned host dynamically
ftl.add_host(hostname="web01", ansible_host=external_ip, ...)
# Configure the host using the same ftl context
await ftl.web01.apt(name="nginx", state="present", update_cache=True)
Key pattern: provision-then-configure — infrastructure modules return result objects with .output dicts, whose values feed into subsequent module calls and add_host for seamless transition from provisioning to configuration.
Environment variables required:
GCP_PROJECT — GCP project IDGCPAUTHKIND — serviceaccount or applicationGCPSERVICEACCOUNT_FILE — path to service account JSON (when using serviceaccount auth)Secret bindings map environment variables to module parameters using glob patterns:
bindings = {
"google.cloud.*": {
"project": "GCP_PROJECT",
"auth_kind": "GCP_AUTH_KIND",
"service_account_file": "GCP_SERVICE_ACCOUNT_FILE",
},
}
This automatically injects project, authkind, and serviceaccount_file into every google.cloud.* module call without repeating them.
Prerequisites: google.cloud Ansible collection, plus google-auth, google-cloud-compute, google-api-python-client Python packages.
.output with provider-specific data (e.g., selfLink, networkInterfaces). These are used to wire resources together — the subnet references the network's selfLink, the instance references both.ftl.add_host() creates a host at runtime that is immediately addressable as ftl.web01 for subsequent configuration calls. The groups parameter assigns it to inventory groups.ftl.google.cloud.gcpcompute*() — the dotted path maps to the Ansible collection FQCN.add_host, modules are called on the host directly (ftl.web01.apt(...)) rather than on the top-level ftl object.state_file=".ftl2-gcp-state.json" enables idempotent re-runs.ftl.results collects all module results; ftl.failed indicates whether any call failed.ftl2.automation.automation — the core async context manager entry point.google.cloud (Ansible collection providing gcpcomputenetwork, gcpcomputesubnetwork, gcpcomputefirewall, gcpcomputeinstance).apt, service, copy — standard configuration modules called on the dynamically-added host.ansiblehost/ansibleuser).add_host + host-scoped calls pattern used in dynamic provisioning workflows.