Migrating Google Cloud Terraform to Frostmoln
To run a conversion, see the migration guide.
This matrix lists how the converter handles each supported resource type and attribute.
google_compute_address → frostmoln_public_ip — partially supported
External addresses map to frostmoln_public_ip; a specific address cannot be requested — the platform allocates one.
Only an EXTERNAL address maps to a public IP; an INTERNAL address has no equivalent and BLOCKS the conversion (mapping it to an external public IP would be silently wrong). A specific reserved address (the address argument) cannot be requested. GCP labels become frostmoln tags.
| Attribute | Outcome | Notes |
|---|---|---|
| address_type | Converted | EXTERNAL (or unset) becomes a public IP; INTERNAL blocks the conversion. |
| labels | Converted to tags | GCP labels become frostmoln tags. |
| address | Manual action required | |
| region | Converted | Frostmoln is single-region today; the platform default region applies. |
| network_tier | Not carried over | |
| purpose | Not carried over | |
| subnetwork | Not needed on Frostmoln | |
| prefix_length | Manual action required | |
| ip_version | Manual action required | |
| name | Not carried over | |
| description | Not carried over | |
| project | Not needed on Frostmoln |
google_compute_attached_disk → frostmoln_volume_attachment — supported
Attached disks map directly to frostmoln_volume_attachment; the disk becomes volume_id and the instance becomes instance_id.
device_name becomes device_path. The attachment mode (READ_ONLY / READ_WRITE) is platform-managed and dropped.
| Attribute | Outcome | Notes |
|---|---|---|
| disk | Mapped to volume_id | |
| instance | Mapped to instance_id | |
| device_name | Mapped to device_path | |
| mode | Not carried over | |
| zone | Not needed on Frostmoln | |
| project | Not needed on Frostmoln |
google_compute_disk → frostmoln_volume — partially supported
Persistent disks map to frostmoln_volume; the disk type (pd-ssd/pd-balanced) is dropped (the platform's volume tier applies) and IOPS/throughput are set by the tier.
Volume tiers are platform-defined — pick a volume_type from the volume tiers catalog (frostmoln_volume_tiers data source) after the conversion. A disk created from a snapshot keeps snapshot as snapshot_id (a direct google_compute_snapshot reference is rewritten). A disk created from an image has no equivalent — boot instances from a frostmoln_image instead. A required volume name is the disk name.
| Attribute | Outcome | Notes |
|---|---|---|
| name | Mapped to name | |
| description | Mapped to description | |
| size | Mapped to size_gb | |
| type | Not carried over | |
| zone | Converted | The platform picks the zone; set zone to a zone id to pin one. |
| snapshot | Converted to snapshot_id | A direct google_compute_snapshot reference is rewritten to the converted frostmoln_snapshot id; otherwise set snapshot_id manually. |
| image | Manual action required | |
| labels | Converted to tags | GCP labels become frostmoln tags. |
| physical_block_size_bytes | Not carried over | |
| provisioned_iops | Not carried over | |
| provisioned_throughput | Not carried over | |
| disk_encryption_key | Manual action required | |
| source_snapshot_encryption_key | Manual action required | |
| source_image_encryption_key | Manual action required | |
| guest_os_features | Not carried over | |
| interface (retired by the provider) | Not carried over | |
| project | Not needed on Frostmoln |
google_compute_firewall → frostmoln_security_group — partially supported
Firewall rules become a frostmoln_security_group plus one frostmoln_security_group_rule per allow protocol × port × remote CIDR. This is the key GCP semantic mismatch: GCP firewalls are network-scoped and select instances by target_tags, whereas Frostmoln security groups attach to instances directly.
A DENY rule has no equivalent and BLOCKS the whole firewall — the platform is allow-only, so a converted deny would OPEN the traffic it denied. A DISABLED firewall also blocks (converting an inactive allow to active rules would widen access). A dynamic "allow" block cannot be enumerated — its contents are unreadable at conversion time, so NO rule is generated for anything it declares, and the refusal is reported as a blocker. The firewall's STATIC allow blocks still convert; if a dynamic block is the only source of allow rules the whole firewall blocks. A dynamic "deny" blocks the firewall exactly as a static deny does. source_ranges (ingress) / destination_ranges (egress) become remote_cidr; a firewall must use static CIDR ranges to convert. target_tags/target_service_accounts select instances by tag — the converter does NOT guess instance membership; it emits a review action telling you to attach the generated security group to those instances (frostmoln_instance.security_groups). NOTE THE SEVERITY: that loss is reported as a WARNING review action and the conversion still succeeds, so fm terraform convert exits 0 — the generated security group is attached to NOTHING until you attach it, and no blocker stops you applying it. The same holds for a tag-scoped SOURCE alongside explicit ranges. A firewall that declares its allow rules in ATTRIBUTE form (allow = [...]) blocks, because the converter reads the block form only. Tag-scoped SOURCES (source_tags/source_service_accounts) with no source_ranges block (dropping them would open the rule to all sources). Priority is dropped (allow-only rules are additive and order-independent). EGRESS DEFAULTS MATCH THE SOURCE - DO NOT "FIX" THEM: every Frostmoln security group is created with allow-all egress (Neutron adds one IPv4 and one IPv6 allow-any egress rule to every new group, and Frostmoln removes neither), and converted egress rules ADD to those defaults rather than replacing them, but GCP already permits all egress through an implied rule at priority 65535 and narrows it only with a DENY egress rule - a deny firewall, which blocks this conversion outright, or a firewall-policy rule (google_compute_firewall_policy_rule and friends), which this converter does not convert at all. An ALLOW EGRESS firewall with destination_ranges narrows nothing on its own, so for every firewall that converts, allow-all egress MATCHES the posture the source had. If the source configuration did contain a deny-egress firewall or a firewall-policy egress rule, its restriction is absent from the output entirely - re-express it as the allow-list the converted group needs, then delete the two defaults. Otherwise do NOT delete the two default egress rules unless you are deliberately tightening beyond the source: the group's egress would then be exactly the egress rules converted from this firewall, and where it declared none that denies ALL outbound traffic. ADDRESS FAMILY: a frostmoln_security_group_rule has no ether_type field, so every rule the platform creates is IPv4 and no converted rule can be IPv6. A source_ranges or destination_ranges entry that is an IPv6 CIDR is REFUSED - no rule is generated for it, and the refusal is reported as a blocker naming the exact range, because a rule emitted with an IPv6 remote is rejected when it is applied. Do NOT translate an IPv6 range to an IPv4 one, it selects different hosts. The firewall's IPv4 ranges still convert; if every range is IPv6 the whole firewall blocks, because the group it would produce allows nothing.
| Attribute | Outcome | Notes |
|---|---|---|
| name | Converted | becomes the generated frostmoln_security_group name. |
| network | Converted | a direct google_compute_network reference becomes vpc_id on the generated security group. |
| direction | Converted | INGRESS/EGRESS becomes the direction of each generated rule. |
| source_ranges | Converted | the ingress source CIDRs become remote_cidr on the generated rules (fanned out). |
| destination_ranges | Converted | the egress destination CIDRs become remote_cidr on the generated rules (fanned out). |
| allow | Converted | each allow protocol/port becomes one or more frostmoln_security_group_rule resources. |
| deny | Manual action required | |
| target_tags | Manual action required | |
| target_service_accounts | Manual action required | |
| source_tags | Manual action required | |
| source_service_accounts | Manual action required | |
| priority | Not carried over | |
| disabled | Manual action required | |
| log_config | Not carried over | |
| description | Not carried over | |
| project | Not needed on Frostmoln |
google_compute_forwarding_rule → frostmoln_load_balancer — partially supported
Forwarding rules map to the frontend of a frostmoln_load_balancer (an L4 network load balancer, provider_type ovn); the port and backend become a frostmoln_lb_listener and frostmoln_lb_pool you must create from the target_pool.
This is a PARTIAL L4 decomposition. A GCP forwarding rule is only the load-balancer frontend — the port(s) become a frostmoln_lb_listener and the target_pool becomes a frostmoln_lb_pool with frostmoln_lb_member resources, which you must wire up (set load_balancer_id on them to this load balancer). load_balancing_scheme EXTERNAL becomes scheme public (which requires a public_ip_id), INTERNAL becomes internal. A public load balancer needs a frostmoln_public_ip. L7 (HTTP(S)) forwarding rules that target a backend_service / URL map are not supported.
| Attribute | Outcome | Notes |
|---|---|---|
| name | Mapped to name | |
| load_balancing_scheme | Converted to scheme | A public scheme requires a public_ip_id — create a frostmoln_public_ip for the load balancer. |
| network | Converted to vpc_id | A direct google_compute_network reference is rewritten to the converted frostmoln_vpc id; otherwise set vpc_id manually. |
| subnetwork | Converted to subnet_id | A direct google_compute_subnetwork reference is rewritten to the converted frostmoln_subnet id; otherwise set subnet_id manually. |
| ip_protocol | Not carried over | |
| port_range | Not carried over | |
| ports | Not carried over | |
| all_ports | Manual action required | |
| target | Manual action required | |
| backend_service | Manual action required | |
| ip_address | Manual action required | |
| labels | Converted to tags | GCP labels become frostmoln tags. |
| region | Converted | Frostmoln is single-region today; the platform default region applies. |
| allow_global_access | Not carried over | |
| network_tier | Not carried over | |
| service_label | Not carried over | |
| description | Not carried over | |
| project | Not needed on Frostmoln |
- The converter adds
provider_typeautomatically. a network forwarding rule is an L4 load balancer (provider_type ovn); change it to amphora for an L7 load balancer. - The converter adds
vpc_idautomatically. frostmoln_load_balancer requires a VPC; set vpc_id to the converted frostmoln_vpc id. - The converter adds
subnet_idautomatically. frostmoln_load_balancer requires a subnet; set subnet_id to the converted frostmoln_subnet id.
google_compute_health_check → frostmoln_lb_health_monitor — partially supported
Health checks map to frostmoln_lb_health_monitor; the protocol block (tcp/http/https) becomes type, and the interval/timeout/thresholds carry over.
The required load_balancer_id and pool_id are FM-TODO placeholders — set them to the converted load balancer and the pool this monitor checks. tcp_health_check becomes type tcp, http_health_check becomes type http (with url_path from request_path), https_health_check becomes type https. SSL, HTTP/2, and gRPC health checks have no equivalent. Health checks run against each member's port, so the per-check port is dropped.
| Attribute | Outcome | Notes |
|---|---|---|
| check_interval_sec | Mapped to delay | |
| timeout_sec | Mapped to timeout | |
| healthy_threshold | Mapped to max_retries | |
| unhealthy_threshold | Not carried over | |
| tcp_health_check | Converted to type | becomes type = "tcp"; the port is set per member. |
| http_health_check | Converted to type | becomes type = "http" with url_path from request_path; the port is set per member. |
| https_health_check | Converted to type | becomes type = "https" with url_path from request_path; the port is set per member. |
| ssl_health_check | Manual action required | |
| http2_health_check | Manual action required | |
| grpc_health_check | Manual action required | |
| name | Not carried over | |
| description | Not carried over | |
| log_config | Not carried over | |
| project | Not needed on Frostmoln |
- The converter adds
typeautomatically. frostmoln_lb_health_monitor requires a type; set it to tcp, http, or https (the protocol block sets it when present). - The converter adds
load_balancer_idautomatically. frostmoln_lb_health_monitor requires load_balancer_id; set it to the converted load balancer. - The converter adds
pool_idautomatically. frostmoln_lb_health_monitor requires pool_id; set it to the converted frostmoln_lb_pool.
google_compute_instance → frostmoln_instance — partially supported
Compute Engine instances map to frostmoln_instance: the machine type is capability-matched to a flavor, the boot disk image becomes a frostmoln_image lookup, the network interface becomes subnet_id/vpc_id (an access_config becomes a frostmoln_public_ip), and metadata SSH keys become frostmoln_ssh_key resources.
machine_type is parsed algorithmically (predefined families by their class ratio, custom-N-M directly, shared-core types by their listed size) and capability-matched against the platform flavor catalog — offline a reviewed placeholder is emitted. boot_disk.initialize_params.image becomes a frostmoln_image lookup whose name needs review. GCP NETWORK tags (the tags argument) are firewall selectors, NOT frostmoln tags — they are DROPPED (mapping them to tags would be silently wrong); the firewall→security_group conversion notes which instances need the group. labels become frostmoln tags. A service_account block is BLOCKED (there is no IAM; grant access with scoped API credentials). Preemptible/spot scheduling and shielded-VM settings are dropped.
| Attribute | Outcome | Notes |
|---|---|---|
| name | Mapped to name | |
| machine_type | Converted to flavor_id | Parsed algorithmically into vCPUs/RAM and capability-matched against the platform flavor catalog, emitted as a frostmoln_flavor data source lookup. |
| zone | Converted | The platform picks the zone; set zone to a zone id to pin one. |
| boot_disk | Converted to image_id | initialize_params.image becomes image_id (a frostmoln_image lookup); the disk size and type are dropped (the flavor and platform tier determine them). |
| network_interface | Converted | subnetwork becomes subnet_id, network becomes vpc_id, and an access_config (external IP) becomes a generated frostmoln_public_ip bound to the instance. |
| metadata | Converted to ssh_key_names | SSH keys in metadata.ssh-keys become generated frostmoln_ssh_key resources; a startup-script/user-data key is flagged (move it to user_data). |
| metadata_startup_script | Mapped to user_data | The startup script becomes plain-text user_data. |
| labels | Converted to tags | GCP labels become frostmoln tags. |
| tags | Not carried over | |
| service_account | Manual action required | |
| scheduling | Not carried over | |
| shielded_instance_config | Not carried over | |
| confidential_instance_config | Not carried over | |
| can_ip_forward | Not carried over | |
| deletion_protection | Not carried over | |
| allow_stopping_for_update | Not needed on Frostmoln | |
| attached_disk | Manual action required | |
| guest_accelerator | Manual action required | |
| min_cpu_platform | Not carried over | |
| resource_policies | Manual action required | |
| advanced_machine_features | Not carried over | |
| reservation_affinity | Not carried over | |
| enable_display | Not carried over | |
| hostname | Not carried over | |
| description | Not carried over | |
| desired_status | Not carried over | |
| project | Not needed on Frostmoln |
- The converter adds
flavor_idautomatically. frostmoln_instance requires a flavor; set flavor_id to a platform flavor (seefm compute flavor list). - The converter adds
image_idautomatically. frostmoln_instance requires an image; set image_id to a platform image (seefm compute image list).
data.google_compute_network → frostmoln_vpc — partially supported
The google_compute_network data source maps to the frostmoln_vpc data source, which selects a VPC by id or name.
frostmoln_vpc looks up a VPC by id or name. A GCP network has no CIDR, so references to the exported subnetworks / gateway attributes have no equivalent; use the VPC id.
| Attribute | Outcome | Notes |
|---|---|---|
| name | Mapped to name | |
| project | Manual action required |
google_compute_network → frostmoln_vpc — partially supported
VPC networks map to frostmoln_vpc; because a GCP network carries no CIDR (subnets define their own ranges), a required cidr is synthesized as an FM-TODO placeholder to set to your VPC supernet.
GCP networks are global and have NO address range of their own — each subnetwork defines its ip_cidr_range. frostmoln_vpc requires a single cidr (a supernet the subnets fall within), so an FM-TODO placeholder is emitted: set it to the supernet that contains your subnets. Auto-mode networks (auto_create_subnetworks) create per-region subnets automatically — those subnets have no Terraform resource and are not converted; recreate them as frostmoln_subnet. routing_mode and mtu are platform-managed. The converted VPC has NO outbound internet access on its own: outbound is an explicit frostmoln_gateway (one per VPC, egressing from an address the platform draws for it; name a Public IP of your own with public_ip_id where a partner allow-lists your source address, and that address is billed as a Public IP), and without it the VPC also has no DNS resolution and no managed-service connectivity, because those are reached over routes that exist only while the egress path does. A google_compute_router_nat in the source configuration does not convert into one — see its entry.
| Attribute | Outcome | Notes |
|---|---|---|
| name | Mapped to name | |
| description | Mapped to description | |
| auto_create_subnetworks | Not carried over | |
| routing_mode | Not carried over | |
| mtu | Not carried over | |
| delete_default_routes_on_create | Not carried over | |
| network_firewall_policy_enforcement_order | Not carried over | |
| project | Not needed on Frostmoln |
- The converter adds
cidrautomatically. frostmoln_vpc requires a cidr but a GCP network has none — set this to the supernet that contains your subnets (the placeholder must be replaced).
google_compute_snapshot → frostmoln_snapshot — partially supported
Disk snapshots map to frostmoln_snapshot; the source disk becomes volume_id.
source_disk references the disk the snapshot was taken from — a direct google_compute_disk reference is rewritten to the converted frostmoln_volume id. Snapshot encryption keys are customer-managed on GCP and have no equivalent (snapshots are encrypted with platform-managed keys).
| Attribute | Outcome | Notes |
|---|---|---|
| name | Mapped to name | |
| description | Mapped to description | |
| source_disk | Converted to volume_id | A direct google_compute_disk reference is rewritten to the converted frostmoln_volume id; otherwise set volume_id manually. |
| labels | Converted to tags | GCP labels become frostmoln tags. |
| zone | Not needed on Frostmoln | |
| storage_locations | Not carried over | |
| snapshot_encryption_key | Manual action required | |
| source_disk_encryption_key | Manual action required | |
| chain_name | Not carried over | |
| project | Not needed on Frostmoln |
- The converter adds
volume_idautomatically. frostmoln_snapshot requires a source volume; set volume_id to the converted frostmoln_volume id.
data.google_compute_subnetwork → frostmoln_subnet — partially supported
The google_compute_subnetwork data source maps to the frostmoln_subnet data source, which selects a subnet by id or name.
frostmoln_subnet looks up a subnet by id or name. The region is platform-managed, and secondary IP ranges have no equivalent; use ip_cidr_range (cidr).
| Attribute | Outcome | Notes |
|---|---|---|
| name | Mapped to name | |
| region | Manual action required | |
| project | Manual action required |
google_compute_subnetwork → frostmoln_subnet — partially supported
Subnetworks map to frostmoln_subnet; ip_cidr_range becomes cidr, the parent network becomes vpc_id, and the region becomes the platform zone.
network references the parent network — a direct google_compute_network reference is rewritten to the converted frostmoln_vpc id. Secondary IP ranges (alias-IP ranges) are dropped — recreate them manually if needed. Private Google Access, flow logs, and purpose/role (for proxy-only or PSC subnets) are dropped (platform-managed).
| Attribute | Outcome | Notes |
|---|---|---|
| name | Mapped to name | |
| description | Mapped to description | |
| ip_cidr_range | Mapped to cidr | |
| network | Converted to vpc_id | A direct google_compute_network reference is rewritten to the converted frostmoln_vpc id; otherwise set vpc_id manually. |
| region | Converted | The platform picks the zone; set zone to a zone id to pin one. |
| secondary_ip_range | Not carried over | |
| private_ip_google_access | Not carried over | |
| private_ipv6_google_access | Not carried over | |
| purpose | Not carried over | |
| role | Not carried over | |
| log_config | Not carried over | |
| stack_type | Not carried over | |
| ipv6_access_type | Manual action required | |
| project | Not needed on Frostmoln |
- The converter adds
vpc_idautomatically. frostmoln_subnet requires a VPC; set vpc_id to the converted frostmoln_vpc id.
google_compute_target_pool → frostmoln_lb_pool — partially supported
Target pools map to frostmoln_lb_pool; the required load_balancer_id is an FM-TODO placeholder (set it to the converted forwarding rule's load balancer), and pool instances become frostmoln_lb_member resources you must create.
A required lb_algorithm defaults to round_robin — note that a network load balancer (provider_type ovn) supports only source_ip_port, so change lb_algorithm when attaching this pool to an ovn load balancer. Pool instances become frostmoln_lb_member resources: recreate one per backend, using the instance's private IP as address (members are addresses, not instance references). The health_check reference becomes a frostmoln_lb_health_monitor.
| Attribute | Outcome | Notes |
|---|---|---|
| name | Mapped to name | |
| instances | Manual action required | |
| health_checks | Manual action required | |
| session_affinity | Not carried over | |
| backup_pool | Manual action required | |
| failover_ratio | Not carried over | |
| region | Converted | Frostmoln is single-region today; the platform default region applies. |
| description | Not carried over | |
| project | Not needed on Frostmoln |
- The converter adds
protocolautomatically. frostmoln_lb_pool requires a protocol; a target pool is TCP-based — verify tcp or set it (tcp/udp/http/https). - The converter adds
lb_algorithmautomatically. frostmoln_lb_pool requires lb_algorithm; a network load balancer (ovn) supports only source_ip_port — change it when attaching to an ovn load balancer. - The converter adds
load_balancer_idautomatically. frostmoln_lb_pool requires load_balancer_id; set it to the converted load balancer (from the forwarding rule).
google_container_cluster → frostmoln_kubernetes_cluster — partially supported
GKE clusters map to frostmoln_kubernetes_cluster; the default node_config becomes the required initial_node_pool (machine_type reported as a size, with flavor_id left for you to set from fm kubernetes flavor list), and the API endpoint's exposure does not carry over (it is not a per-cluster setting on the platform).
The API endpoint's exposure does NOT carry over — it is not a per-cluster setting on the platform (see private_cluster_config), and nothing is made public by the conversion. Public WORKLOAD traffic has no cluster-level equivalent either: a managed cluster is NOT given an ingress load balancer, so there is no attribute for a GKE public entrypoint to convert into and none is emitted. Expose a workload the standard Kubernetes way instead — a Service of type=LoadBalancer inside the cluster, which the platform provisions a load balancer for. That is an in-cluster step (kubectl/Helm), not Terraform, so this conversion cannot do it for you. And it is only half a replacement today: such a Service can be given an INTERNAL address only, because a per-Service PUBLIC address is not built yet, so a publicly reachable workload entrypoint is an open GAP. Do not assume the converted configuration exposes anything — carry the source's public entrypoint forward on your migration checklist and plan it by hand. network/subnetwork become vpc_id/subnet_id. When the default node pool is removed (remove_default_node_pool) and real pools are defined as google_container_node_pool, the initial_node_pool is an FM-TODO placeholder (the separate node pools convert to frostmoln_kubernetes_node_pool). Autopilot, network policy, master authorized networks, and add-on configs have no equivalent and are dropped or blocked. Workload Identity IS supported on managed Kubernetes — it is switched on for the tenant rather than per cluster, so workload_identity_config carries nothing over. The tenant must hold the workload-identity entitlement BEFORE the cluster is created; it cannot be enabled on an existing one. Each google_service_account_iam_member that federated a Kubernetes service account has to be rewritten by hand as a frostmoln_workload_identity_binding (the converter has no mapping for that type yet); grant the binding with a frostmoln_iam_policy attached by frostmoln_iam_policy_attachment (its flat scopes list is optional and coarser). Note also that GKE's per-pool node_config.workload_metadata_config is not carried over.
| Attribute | Outcome | Notes |
|---|---|---|
| name | Mapped to name | |
| min_master_version | Mapped to version | Verify the version is offered on the platform (fm kubernetes version list). |
| network | Converted to vpc_id | A direct google_compute_network reference is rewritten to the converted frostmoln_vpc id; otherwise set vpc_id manually. |
| subnetwork | Converted to subnet_id | A direct google_compute_subnetwork reference is rewritten to the converted frostmoln_subnet id; otherwise set subnet_id manually. |
| node_config | Converted to initial_node_pool | The default node_config (with initial_node_count) becomes the required initial_node_pool object. machine_type is parsed for its vCPUs and RAM and reported; flavor_id is left as an FM-TODO to set from fm kubernetes flavor list. |
| private_cluster_config | Not carried over | The Kubernetes API endpoint's exposure is not configurable on the platform, so there is nothing to set here. enable_private_endpoint = true carries over faithfully — the managed control plane's API endpoint is private and reached from inside your VPC. A cluster with a PUBLIC endpoint does not: plan for kubectl from inside the VPC, or through the platform's authenticated access path. If what you exposed publicly was your WORKLOAD traffic, that has no setting on the converted cluster either: a managed cluster is not given an ingress load balancer, and a workload is exposed with a Kubernetes Service of type=LoadBalancer inside the cluster. Only INTERNAL addresses are available for such a Service today, so a PUBLIC workload entrypoint is an open GAP — plan it as manual work rather than expecting the converted configuration to provide one. |
| initial_node_count | Not needed on Frostmoln | |
| remove_default_node_pool | Not needed on Frostmoln | |
| master_authorized_networks_config | Not carried over | |
| workload_identity_config | Not carried over | Workload identity is available on managed Kubernetes, but it is switched on for your tenant rather than per cluster, so there is nothing to configure here. Your tenant must hold the workload-identity entitlement BEFORE the cluster is created — it cannot be turned on for a cluster that already exists. Bind each Kubernetes service account with frostmoln_workload_identity_binding, granted by a frostmoln_iam_policy attached with frostmoln_iam_policy_attachment (its flat scopes list is optional and coarser). |
| release_channel | Not carried over | |
| addons_config | Not carried over | |
| network_policy | Not carried over | |
| ip_allocation_policy | Not carried over | |
| enable_autopilot | Manual action required | |
| cluster_autoscaling | Manual action required | |
| logging_service | Not carried over | |
| monitoring_service | Not carried over | |
| logging_config | Not carried over | |
| monitoring_config | Not carried over | |
| maintenance_policy | Not carried over | |
| location | Not needed on Frostmoln | |
| node_locations | Not carried over | |
| resource_labels | Not carried over | |
| deletion_protection | Not carried over | |
| datapath_provider | Not carried over | |
| project | Not needed on Frostmoln |
- The converter adds
initial_node_poolautomatically. frostmoln_kubernetes_cluster requires an initial node pool; set flavor_id to a platform flavor (seefm kubernetes flavor list) — the real pools convert to frostmoln_kubernetes_node_pool. - The converter adds
versionautomatically. frostmoln_kubernetes_cluster requires a version; set it to an offered version (fm kubernetes version list). - The converter adds
vpc_idautomatically. frostmoln_kubernetes_cluster requires a VPC; set vpc_id to the converted frostmoln_vpc id. - The converter adds
subnet_idautomatically. frostmoln_kubernetes_cluster requires a subnet; set subnet_id to the converted frostmoln_subnet id.
google_container_node_pool → frostmoln_kubernetes_node_pool — partially supported
GKE node pools map to frostmoln_kubernetes_node_pool; node_config.machine_type's size is reported and flavor_id is left for you to set, and node_count carries over.
A node pool draws flavor_id from the Kubernetes node-flavor catalog, which is separate from the compute one — so the converter reports the source machine_type's vCPUs and RAM and leaves flavor_id as an FM-TODO for you to set from fm kubernetes flavor list. cluster references the parent cluster — a direct google_container_cluster reference is rewritten to the converted cluster id. Autoscaling has no equivalent (set a fixed node_count). The pool name must be a lowercase DNS label of at most 18 characters. Node labels, taints, and per-pool locations are dropped or blocked.
| Attribute | Outcome | Notes |
|---|---|---|
| name | Mapped to name | The pool name must be a lowercase DNS label of at most 18 characters. |
| cluster | Converted to cluster_id | A direct google_container_cluster reference is rewritten to the converted frostmoln_kubernetes_cluster id. |
| node_config | Converted to flavor_id | node_config.machine_type is parsed for its vCPUs and RAM and reported; flavor_id is left as an FM-TODO to set from fm kubernetes flavor list. |
| node_count | Mapped to node_count | |
| autoscaling | Manual action required | |
| initial_node_count | Not needed on Frostmoln | |
| management | Not carried over | |
| upgrade_settings | Not carried over | |
| max_pods_per_node | Not carried over | |
| node_locations | Not carried over | |
| location | Not needed on Frostmoln | |
| version | Not carried over | |
| network_config | Not carried over | |
| project | Not needed on Frostmoln |
- The converter adds
flavor_idautomatically. frostmoln_kubernetes_node_pool requires a flavor; set flavor_id to a platform flavor (seefm kubernetes flavor list).
google_dns_managed_zone → frostmoln_dns_zone — partially supported
Public DNS zones map to frostmoln_dns_zone; dns_name becomes the zone name (normalized to a lowercase FQDN) and a required SOA email is synthesized as a placeholder.
Only PUBLIC zones convert — a PRIVATE zone has no equivalent and BLOCKS the conversion (converting it to a public zone would expose it). The GCP resource name (the name argument) is dropped: the zone name IS the domain on Frostmoln. The required SOA admin email cannot come from GCP — an FM-TODO placeholder is emitted. DNSSEC and split-horizon (peering/forwarding) configs are dropped or blocked.
| Attribute | Outcome | Notes |
|---|---|---|
| dns_name | Converted to name | Normalized to a lowercase fully qualified domain with a trailing dot, e.g. "example.com." |
| name | Not carried over | |
| description | Mapped to description | |
| visibility | Converted | public zones convert; a private zone blocks the conversion. |
| labels | Converted to tags | GCP labels become frostmoln tags. |
| dnssec_config | Not carried over | |
| private_visibility_config | Manual action required | |
| forwarding_config | Manual action required | |
| peering_config | Manual action required | |
| cloud_logging_config | Not carried over | |
| force_destroy | Not needed on Frostmoln | |
| project | Not needed on Frostmoln |
- The converter adds
emailautomatically. the SOA admin email is required; replace the placeholder with a real contact address.
google_dns_record_set → frostmoln_dns_record — partially supported
DNS record sets map to frostmoln_dns_record; rrdatas becomes records and the record name becomes zone-relative.
Record names are zone-relative on Frostmoln (the zone name is appended automatically). When the managed_zone references an in-config google_dns_managed_zone with a static dns_name, the fully qualified record name has that suffix stripped automatically; otherwise a fully qualified name blocks — strip the zone suffix, or use "@" for the apex. Supported types: A, AAAA, CNAME, MX, TXT, NS, SRV, CAA, PTR. Weighted/geo/failover routing_policy has no equivalent.
| Attribute | Outcome | Notes |
|---|---|---|
| name | Converted | Record names are zone-relative; a name referencing an in-config zone's dns_name is stripped automatically. |
| managed_zone | Converted to zone_id | A direct google_dns_managed_zone reference is rewritten to the converted frostmoln_dns_zone id. |
| type | Converted | Supported types carry over; SOA and other types have no equivalent (SOA is platform-managed). |
| rrdatas | Mapped to records | The record data list becomes the records set. |
| ttl | Mapped to ttl | |
| routing_policy | Manual action required | |
| project | Not needed on Frostmoln |
google_redis_instance → frostmoln_redis_instance — partially supported
Memorystore Redis instances map to frostmoln_redis_instance; the version carries over and the memory size does not map to a platform flavor, so flavor_id is a placeholder.
The managed cache serves the cache protocol in PLAINTEXT on port 6379 at its private address in your VPC and has no TLS listener, whatever the source configuration asked for — the AUTH password therefore also crosses the wire in cleartext, as do the keys and values themselves; and with no TLS there is no integrity protection either, so anything on the network path inside your VPC can read and modify the traffic. A transit_encryption_mode of SERVER_AUTHENTICATION BLOCKS the conversion for that reason; DISABLED converts. GCP sizes Redis by memory_size_gb rather than vCPU/RAM, so flavor_id, vpc_id, and subnet_id are FM-TODO placeholders — set flavor_id to the platform flavor whose memory tier matches. The tier (BASIC / STANDARD_HA) has no direct equivalent: STANDARD_HA is high-availability, which frostmoln_redis_instance does not expose. redis_configs are dropped — set eviction_policy and persistence_mode on the instance manually.
| Attribute | Outcome | Notes |
|---|---|---|
| name | Mapped to name | |
| redis_version | Converted to version | REDIS_7_0 becomes "7"; verify the version is offered (fm cache redis version list). |
| authorized_network | Converted to vpc_id | A direct google_compute_network reference is rewritten to the converted frostmoln_vpc id; otherwise set vpc_id manually. |
| memory_size_gb | Not carried over | |
| tier | Not carried over | |
| redis_configs | Not carried over | |
| reserved_ip_range | Manual action required | |
| connect_mode | Not carried over | |
| transit_encryption_mode | Converted | DISABLED converts and the flag is dropped; SERVER_AUTHENTICATION blocks the whole resource — the managed cache has no TLS listener, so converting the instance without the attribute would silently turn a TLS-encrypted cache into a plaintext one. |
| auth_enabled | Not needed on Frostmoln | |
| replica_count | Not carried over | |
| read_replicas_mode | Not carried over | |
| labels | Not carried over | |
| region | Not needed on Frostmoln | |
| location_id | Not carried over | |
| alternative_location_id | Not carried over | |
| maintenance_policy | Not carried over | |
| project | Not needed on Frostmoln |
- The converter adds
versionautomatically. frostmoln_redis_instance requires a version; set it to an offered version (fm cache redis version list). - The converter adds
flavor_idautomatically. frostmoln_redis_instance requires a flavor; the GCP memory size does not map — set flavor_id (seefm cache flavor list). - The converter adds
vpc_idautomatically. frostmoln_redis_instance requires a VPC; set vpc_id to the converted frostmoln_vpc id. - The converter adds
subnet_idautomatically. frostmoln_redis_instance requires a subnet; set subnet_id to the converted frostmoln_subnet id.
google_secret_manager_secret → frostmoln_secret — partially supported
Secret Manager secrets map to frostmoln_secret; the secret_id becomes the name and the secret value is set on the frostmoln_secret directly.
On GCP the secret value lives in a separate google_secret_manager_secret_version — Frostmoln stores the value on the secret itself, so a required secret_value is an FM-TODO placeholder: set it from the corresponding secret version's secret_data. Replication is not applicable (data is stored in the single EU region). GCP labels become frostmoln tags.
| Attribute | Outcome | Notes |
|---|---|---|
| secret_id | Mapped to name | |
| labels | Converted to tags | GCP labels become frostmoln tags. |
| replication | Not needed on Frostmoln | |
| rotation | Not carried over | |
| topics | Not carried over | |
| ttl | Not carried over | |
| expire_time | Not carried over | |
| version_aliases | Not carried over | |
| annotations | Not carried over | |
| project | Not needed on Frostmoln |
- The converter adds
secret_valueautomatically. frostmoln_secret requires the value inline; set secret_value from the corresponding google_secret_manager_secret_version's secret_data.
google_sql_database_instance → frostmoln_postgres_instance — partially supported
Cloud SQL PostgreSQL instances map to frostmoln_postgres_instance; the settings block becomes storage_gb/ha_enabled with flavor_id left for you to set, and database_version becomes the engine version.
This converter maps google_sql_database_instance to frostmoln_postgres_instance — a MYSQL_* database_version BLOCKS the conversion (recreate MySQL instances as frostmoln_mysql_instance). A read replica (master_instance_name) also blocks (recreate as frostmoln_postgres_read_replica). settings.disk_size becomes storage_gb, and settings.availability_type = REGIONAL becomes ha_enabled. A managed database draws flavor_id from the managed-database flavor catalog, which is separate from the compute one — so the converter reports settings.tier's vCPUs and RAM and leaves flavor_id as an FM-TODO for you to set from fm database flavor list. frostmoln_postgres_instance requires a VPC and subnet — vpc_id and subnet_id are FM-TODO placeholders (set them to the converted network). Administrator credentials are platform-issued and dropped.
| Attribute | Outcome | Notes |
|---|---|---|
| name | Mapped to name | |
| database_version | Converted to version | POSTGRES_16 becomes "16"; a MYSQL_* version blocks (use frostmoln_mysql_instance). |
| settings | Converted | disk_size becomes storage_gb and availability_type REGIONAL becomes ha_enabled; tier is parsed for its vCPUs and RAM and reported, with flavor_id left as an FM-TODO to set from fm database flavor list. |
| master_instance_name | Manual action required | |
| replica_configuration | Manual action required | |
| root_password | Not carried over | |
| region | Not needed on Frostmoln | |
| deletion_protection | Not carried over | |
| encryption_key_name | Manual action required | |
| instance_type | Not carried over | |
| maintenance_version | Not carried over | |
| project | Not needed on Frostmoln |
- The converter adds
versionautomatically. frostmoln_postgres_instance requires a version; set it to an offered version (fm database postgres version list). - The converter adds
vpc_idautomatically. frostmoln_postgres_instance requires a VPC; Cloud SQL instances have no VPC concept — set vpc_id to the converted frostmoln_vpc id. - The converter adds
subnet_idautomatically. frostmoln_postgres_instance requires a subnet; set subnet_id to the converted frostmoln_subnet id.
google_storage_bucket → frostmoln_bucket — partially supported
Storage buckets map to frostmoln_bucket (name, versioning, tags); the location becomes the platform region, and IAM, lifecycle, CORS, and website hosting have no equivalent.
The bucket versioning block (enabled = true/false) becomes the versioning string (enabled/suspended). GCP labels become frostmoln tags. Buckets are private — re-grant access with S3 credentials (frostmoln_s3_credential) scoped to the bucket. uniform_bucket_level_access and public_access_prevention are the platform default (private) and are dropped. Lifecycle rules, CORS, website hosting, and retention policies have no equivalent yet.
| Attribute | Outcome | Notes |
|---|---|---|
| name | Mapped to name | |
| location | Converted | Frostmoln is single-region today; the platform default region applies. |
| versioning | Converted | versioning.enabled = true becomes versioning = "enabled"; false becomes "suspended". |
| storage_class | Not carried over | |
| labels | Converted to tags | GCP labels become frostmoln tags. |
| uniform_bucket_level_access | Not needed on Frostmoln | |
| public_access_prevention | Not carried over | |
| lifecycle_rule | Manual action required | |
| cors | Manual action required | |
| website | Manual action required | |
| encryption | Not needed on Frostmoln | |
| logging | Not carried over | |
| retention_policy | Manual action required | |
| autoclass | Not carried over | |
| requester_pays | Not needed on Frostmoln | |
| force_destroy | Not needed on Frostmoln | |
| default_event_based_hold | Manual action required | |
| project | Not needed on Frostmoln |
google_storage_hmac_key → frostmoln_s3_credential — partially supported
HMAC keys map to frostmoln_s3_credential (S3-compatible access keys); the service-account scoping is dropped.
A GCP HMAC key is scoped to a service account — Frostmoln S3 credentials are scoped to buckets/actions instead, so the service_account_email is dropped. A required credential name is synthesized from the resource address. Scope the credential with allowed_buckets / allowed_actions after the conversion.
| Attribute | Outcome | Notes |
|---|---|---|
| service_account_email | Not carried over | |
| state | Not carried over | |
| project | Not needed on Frostmoln |
- The converter adds
nameautomatically. frostmoln_s3_credential requires a name; it is taken from the resource address.
Resources without an equivalent
| Resource | What happens |
|---|---|
| google_bigquery_dataset | BigQuery has no equivalent; run analytics on a managed PostgreSQL/MySQL instance or self-hosted engine. |
| google_cloud_run_service | Managed container serverless (Cloud Run) has no equivalent; deploy containers on frostmoln_kubernetes_cluster. |
| google_cloudfunctions_function | Serverless functions have no equivalent; run code on a frostmoln_instance or in frostmoln_kubernetes_cluster. |
| google_compute_backend_service | L7 (HTTP(S)) load-balancer backend services have no equivalent yet; recreate the load balancer from its L4 forwarding rule and target pool. |
| google_compute_network_peering | VPC network peering has no equivalent; connect workloads within a single VPC. |
| google_compute_route | Routing inside a VPC is platform-managed and custom routes are removed; a default route to the internet is not one of them — outbound comes from the VPC's gateway, a separate resource you must add. |
| google_compute_router | Routing inside a VPC is platform-managed and Cloud Routers are removed; if this router hosted a Cloud NAT, that outbound path is NOT removed with it — see google_compute_router_nat for the gateway to add. |
| google_compute_router_nat | A Frostmoln VPC reaches the internet only while a frostmoln_gateway is attached to it, and the converter must not decide for you whether that path egresses from a platform-drawn address or from a Public IP you own. A VPC may have at most ONE, so several Cloud NATs serving one network collapse into a single gateway. |
| google_compute_router_nat_address | A frostmoln_gateway carries a single source address — the platform's, or one Public IP you own and name on the gateway — not a list of addresses you reserved and assigned. |
| google_compute_url_map | URL maps (L7 path-based routing) have no equivalent; terminate HTTP routing in your own reverse proxy. |
| google_compute_vpn_gateway | Cloud VPN gateways have no equivalent; terminate site-to-site VPNs on a customer-managed instance. |
| google_kms_crypto_key | Customer-managed encryption keys have no equivalent; resources are encrypted with platform-managed keys. |
| google_project_iam_member | There are no project-level IAM bindings; attach a frostmoln_iam_policy to the principal instead. |
| google_pubsub_subscription | Pub/Sub has no equivalent; Frostmoln's managed message broker speaks AMQP (LavinMQ), not Pub/Sub. |
| google_pubsub_topic | Pub/Sub has no equivalent; Frostmoln's managed message broker speaks AMQP (LavinMQ), not Pub/Sub. |
| google_secret_manager_secret_version | Secret versions have no standalone equivalent; the value is set on the frostmoln_secret directly. |
| google_service_account | There is no standalone service-account resource; a Kubernetes workload gets its identity from frostmoln_workload_identity_binding, and anything else uses a frostmoln_api_key. |
| google_sql_database | Databases are created inside the managed instance; a standalone database resource has no equivalent. |
| google_sql_user | Database users are managed inside the instance; a standalone user resource has no equivalent. |
| google_storage_bucket_object | Individual bucket objects are not managed as Terraform resources; upload objects with the S3 API or fm CLI. |
google_bigquery_dataset
Frostmoln has no serverless data warehouse — recreate analytical workloads on frostmoln_postgres_instance or a self-hosted engine on compute.
google_cloud_run_service
Frostmoln offers managed Kubernetes rather than Cloud Run — deploy the container image to a frostmoln_kubernetes_cluster (or run it on a VM).
google_cloudfunctions_function
Frostmoln offers no function-as-a-service — repackage Cloud Functions as a container on Kubernetes or a service on a VM.
google_compute_backend_service
Frostmoln load balancers do not yet support URL-map/path-based routing. Convert the L4 network load balancer (google_compute_forwarding_rule + google_compute_target_pool) instead, or terminate HTTP routing in your own reverse proxy.
google_compute_network_peering
Frostmoln does not support inter-VPC peering — place workloads that must communicate in the same frostmoln_vpc, or route between them at the application layer.
google_compute_route
Subnet-to-subnet routing within a Frostmoln VPC is automatic, so a static route describing it has nothing to convert to.
A route with next_hop_gateway = "default-internet-gateway" is a different matter: nothing the platform does replaces it. A Frostmoln VPC has no outbound path until a frostmoln_gateway is attached to it, and a VPC without one is an isolated network — no outbound internet, and, because the platform DNS resolver and the managed-service control plane are reached over routes that exist only while that path does, no name resolution and no managed-service connectivity either. See the google_compute_router_nat entry for what to add, and how to give it a source address you can publish.
google_compute_router
Frostmoln has no Cloud Router: subnet-to-subnet routing within a VPC is automatic, and there are no BGP sessions to advertise into.
Read the summary before deleting anything, though: a Cloud Router is also where a Cloud NAT hangs. Removing the router does not remove the need for outbound connectivity, and nothing replaces it implicitly. A Frostmoln VPC has no outbound path until a frostmoln_gateway is attached to it, and a VPC without one is an isolated network — no outbound internet, and, because the platform DNS resolver and the managed-service control plane are reached over routes that exist only while that path does, no name resolution and no managed-service connectivity either. See google_compute_router_nat in this report for what to add, and how to give it a source address you can publish.
google_compute_router_nat
This is not a resource the platform makes unnecessary — it is one you have to replace. A Frostmoln VPC's outbound path is an explicit resource, and a VPC without one is an isolated network: no outbound internet, and — because the platform DNS resolver and the managed-service control plane are reached over routes that exist only while that path does — no name resolution and no managed-service connectivity either. Attach one to the converted VPC (the frostmoln_vpc this NAT's router referenced through its network):
resource "frostmoln_gateway" "main" {
vpc_id = frostmoln_vpc.main.id
mode = "public_ip"
}
That gateway IS the translation Cloud NAT performed: every instance in the VPC egresses through it. Its source address is drawn by the platform, and you do not choose which one you get, so it is not an address to publish. That matters if this Cloud NAT used nat_ip_allocate_option = "MANUAL_ONLY" with reserved nat_ips: to keep a source address you can hand out, allocate it yourself and name it:
resource "frostmoln_public_ip" "egress" {}
resource "frostmoln_gateway" "main" {
vpc_id = frostmoln_vpc.main.id
mode = "public_ip"
public_ip_id = frostmoln_public_ip.egress.id
}
That address is one of yours: listed among your Public IPs, drawn from the same public IPv4 quota your customer-facing addresses use, and billed as a Public IP. There is no shared-outbound-address option — a VPC egresses through its own gateway, never through an address held in common with other tenants.
The converter does not write the gateway for you, deliberately: connectivity is a stated choice, so that a VPC cannot acquire an outbound path — or a billable public address — because a field was omitted.
Two shapes do not carry over. A VPC has AT MOST ONE gateway, while this configuration may hold one Cloud NAT per region for what becomes a single VPC; a single frostmoln_gateway replaces all of them, and that many-to-one collapse is left to you to make rather than performed quietly. And source_subnetwork_ip_ranges_to_nat = "LIST_OF_SUBNETWORKS" has no equivalent: the gateway serves the whole VPC, so a per-subnet NAT selection must be reshaped as separate VPCs or handled with security groups.
The same gateway can be created outside Terraform with fm network gateway create.
It adopts rather than duplicates. If the VPC already has a gateway — one the platform attached implicitly because a public IP was associated with an instance in it, or one created outside Terraform later — import that one rather than creating a second; the platform refuses the second with GATEWAY_EXISTS. The resource is one-to-one with its VPC, so the VPC's own id is the import id:
terraform import frostmoln_gateway.main <vpc-id>
google_compute_router_nat_address
This resource manages the reserved external addresses a Cloud NAT translates to. Frostmoln has no equivalent assignment: the VPC's gateway carries exactly ONE source address, named on the gateway itself. Left unnamed, the gateway egresses from an address the platform draws — one you do not choose and should not publish. Naming a Public IP you own is the analogue, and the answer when a remote peer allow-lists your source IP:
resource "frostmoln_public_ip" "egress" {}
resource "frostmoln_gateway" "main" {
vpc_id = frostmoln_vpc.main.id
mode = "public_ip"
public_ip_id = frostmoln_public_ip.egress.id
}
That address is one of yours: listed among your Public IPs, drawn from the same public IPv4 quota your customer-facing addresses use, and billed as a Public IP. You still cannot ask for a PARTICULAR address — the platform allocates it — so an allow-list entry has to be updated once to the address you are given.
A list of addresses — the reason this resource exists, usually port headroom or a published allow-list range — has no counterpart: one gateway, one address. If a partner allow-lists several addresses today, that expectation has to be renegotiated before this configuration will work.
The gateway itself is not created for you; see google_compute_router_nat, and add it with or without the public_ip_id above:
resource "frostmoln_gateway" "main" {
vpc_id = frostmoln_vpc.main.id
mode = "public_ip"
}
The same gateway can be created outside Terraform with fm network gateway create.
It adopts rather than duplicates. If the VPC already has a gateway — one the platform attached implicitly because a public IP was associated with an instance in it, or one created outside Terraform later — import that one rather than creating a second; the platform refuses the second with GATEWAY_EXISTS. The resource is one-to-one with its VPC, so the VPC's own id is the import id:
terraform import frostmoln_gateway.main <vpc-id>
google_compute_url_map
Frostmoln load balancers route at L4 (and L7 without path rules); URL-map path/host routing has no equivalent — run a reverse proxy (nginx/Traefik) behind the load balancer for path routing.
google_compute_vpn_gateway
Frostmoln does not offer a managed VPN gateway — run a VPN endpoint (WireGuard/IPsec) on a frostmoln_instance if site-to-site connectivity is required.
google_kms_crypto_key
Frostmoln encrypts volumes, snapshots, and objects with platform-managed keys — there is no Cloud KMS equivalent. Store application secrets in frostmoln_secret.
google_project_iam_member
Frostmoln grants access from the principal side: a frostmoln_iam_policy (document composed with the frostmoln_iam_policy_document data source) attached with frostmoln_iam_policy_attachment to an api_key, workload_identity, or group. The roles themselves do not carry over - a GCP role has no mechanical translation to Frostmoln operations and FRNs - so review every dropped binding and re-express what it allowed.
google_pubsub_subscription
Pub/Sub subscriptions have no protocol overlap with the managed AMQP broker — recreate consumers/queues on the broker manually.
google_pubsub_topic
Pub/Sub is a proprietary push/pull messaging service with no protocol overlap with the managed AMQP broker — recreate the messaging topology on the broker manually.
google_secret_manager_secret_version
Frostmoln stores the secret value on the frostmoln_secret (secret_value) and manages versioning internally — take the secret_data from this version and set it as secret_value on the converted secret.
google_service_account
GKE Workload Identity - a service account impersonated by a Kubernetes service account - has a counterpart: frostmoln_workload_identity_binding binds a namespace and service account in a Frostmoln-managed Kubernetes cluster, with no long-lived credential, and a frostmoln_iam_policy attached to that workload_identity carries the permissions - the preferred grant, and the counterpart of the IAM bindings you attached to the service account. The binding's own flat scopes list is OPTIONAL and coarser (a scope grants across a whole service). A binding created before its grant exists is INERT rather than open, and removing its LAST grant is rejected - delete the binding to remove a workload's access. As on GKE, the Kubernetes ServiceAccount must be annotated (frostmoln.cloud/workload-identity=true) before a pod running as it gets a credential. There is no account OBJECT to create first, so this resource disappears rather than converting. A service account used OUTSIDE a Frostmoln-managed cluster, or one whose key was exported, becomes a frostmoln_api_key (or frostmoln_s3_credential for bucket access) held as a secret.
google_sql_database
Create databases inside the frostmoln_postgres_instance / frostmoln_mysql_instance after it is provisioned; there is no per-database Terraform resource.
google_sql_user
Create database users inside the frostmoln_postgres_instance / frostmoln_mysql_instance after it is provisioned; the admin account is platform-issued.
google_storage_bucket_object
Frostmoln manages buckets, not their contents — upload objects to the frostmoln_bucket using S3-compatible tooling after the conversion.
Trademarks. Frostmoln is an independent cloud provider and a competing alternative to Amazon Web Services, Microsoft Azure, Google Cloud, and Oracle Cloud. Frostmoln is not affiliated with, endorsed by, or sponsored by any of them. AWS, Azure, Google Cloud, and Oracle Cloud are trademarks of their respective owners; all references are nominative and for interoperability only.