frostmoln_application_gateway (Resource)
Manages a Frostmoln Application Gateway: one Public IP fronting many services in your VPC, routed by host and URL path, with TLS termination and a Web Application Firewall.
Listeners, routes, backend pools, backends and published WAF versions are all authored against this gateway and do not take effect until they are applied to the appliance. config_generation is what has been authored; config_revision is what the appliance has acknowledged. When they differ there is a change the gateway is not serving.
~> Terraform cannot see that an ATTACHED address depends on the VPC's gateway. This resource attaches one, and an address reaches the outside world only through a gateway — but nothing that attaches an address refers to frostmoln_gateway, so nothing orders the two. Terraform runs them concurrently and either can win.
On teardown the gateway can go first, and its delete is then refused ("Gateway is still in use", GATEWAY_IN_USE) because something in the VPC still depends on it — the failure that stops a terraform destroy half way through. On create the attachment can land first, and the platform then attaches a gateway ITSELF to carry it: a frostmoln_gateway that names a public_ip_id is refused after that ("VPC already has a gateway", GATEWAY_EXISTS), and one that names none is not refused at all — it quietly ADOPTS the gateway the platform made, leaving the VPC egressing from whatever address that gateway already had rather than one this configuration names, with origin reading implicit_public_ip.
Where the same configuration manages the gateway, state the ordering yourself: put depends_on = [frostmoln_gateway.<name>] on the resource that makes the ATTACHMENT — this one. Where the gateway is in another module, the dependency is on the module itself: depends_on = [module.<name>]. This resource is not the only one that needs it: frostmoln_apache_instance (public), frostmoln_load_balancer (public_ip_id), frostmoln_nginx_instance (public), frostmoln_public_ip_association and frostmoln_public_ip (instance_id) attach addresses too, and each takes the line on itself.
It works only where the gateway is a frostmoln_gateway RESOURCE in the same configuration. A data "frostmoln_gateway" cannot carry the order — a data source is read, never created or destroyed — so depending on one defers a read and sequences nothing.
Do not write it the other way about — on the gateway, listing what attaches. depends_on orders the resource it is written on, so that reverses both orders and turns a race that sometimes passed into a teardown that fails every time.
It changes ORDER only: nothing is created and nothing is released. It does not arm the gateway's own destroy either — without acknowledge_connectivity_loss the teardown stops at that refusal instead, and never reaches the ordering at all. And if a gateway was already adopted, nothing needs importing or rebuilding: it is in state already — add the ordering so it cannot recur, then give the gateway the address you meant with public_ip_id, which is applied in place.
Authoritative scope — who owns what on this resource, declared in internal/scopedecl and machine-checked against the schema.
Enacted and reconciled — every configurable attribute not listed below: the platform applies it, and a refresh reads the truth back.
Create-immutable — flavor_id, public_ip_id, public_ip_mode, subnet_id, vpc_id: the platform has no in-place migration for it — a change destroys and re-creates the gateway.
Observed, not enacted — public_ip: pool-allocated by the platform when the configuration names no public_ip_id. tags_all: keys set outside Terraform — in the portal, by the fm CLI, or stamped by the platform — appear only here and are kept on every apply, never removed. version: platform-managed: chosen by the server at create and upgraded by the platform, never by configuration.
Example Usage
# An Application Gateway: one Public IP fronting many services in your VPC.
#
# Nothing you attach to it is live until the gateway applies its configuration.
# `config_generation` is what has been authored; `config_revision` is what the
# appliance has acknowledged.
data "frostmoln_appgw_flavors" "available" {}
resource "frostmoln_application_gateway" "edge" {
name = "edge"
flavor_id = "agw.co1.medium"
vpc_id = frostmoln_vpc.main.id
subnet_id = frostmoln_subnet.public.id
# The default. The platform draws an address from the pool and RELEASES it
# when the gateway is destroyed.
public_ip_mode = "allocated"
# Resource tags: your own metadata for search and filtering. Merged with
# the provider's default_tags; changing them updates in place.
tags = {
env = "prod"
}
}
# Bring your own address instead. It is used as-is and is NEVER released when
# the gateway is destroyed.
resource "frostmoln_application_gateway" "byo" {
name = "edge-byo"
flavor_id = "agw.co1.large"
vpc_id = frostmoln_vpc.main.id
subnet_id = frostmoln_subnet.public.id
public_ip_mode = "selected"
public_ip_id = frostmoln_public_ip.edge.id
}Schema
Required
flavor_id(String) The flavor (size) of the Application Gateway, e.g.agw.co1.medium. Changing this forces a new resource. Available sizes and their structural limits are in thefrostmoln_appgw_flavorsdata source.name(String) The name of the Application Gateway.subnet_id(String) The subnet the gateway's appliance attaches to. Changing this forces a new resource.vpc_id(String) The VPC the gateway lives in. Changing this forces a new resource.
Optional
public_ip_id(String) The ID of a Public IP you already own, used whenpublic_ip_modeisselected. Changing this forces a new resource.This is not populated for a pool-allocated gateway: the allocated address is visible as
public_ipand has no id here, so that this attribute round-trips exactly what you configured.See the gateway ordering note on this resource: an Application Gateway attaches a public address in both
public_ip_modevalues, so that note applies whether or not you set this attribute.public_ip_mode(String) Where the gateway's public address comes from.
allocated(default) — the platform draws an address from the pool and releases it when the gateway is destroyed.selected— use an address you already hold, named bypublic_ip_id. It is used as-is and is never released when the gateway is destroyed.Changing this forces a new resource.
tags(Map of String) Resource tags on the gateway: your own key/value metadata for search and filtering (?tag=key=valuein the API,--tagin the fm CLI), stored by the platform only and never pushed to the appliance. Changing them updates the gateway in place: no config apply, noconfig_generationchange. The gateway's listeners, routes, pools and other children carry their own tags. At most 32 keys including the tenant's default tags, which the platform merges in at create; a key is 1-64 bytes matching^[a-zA-Z0-9]([a-zA-Z0-9._:/-]*[a-zA-Z0-9])?$, a value at most 256 bytes; keys beginningfrostmoln_orfrostmoln-(any case) are reserved. Merged with the provider'sdefault_tagson every write (a key set here wins). Holds only the keys this configuration sets; the full set is intags_all.timeouts(Block, Optional) (see below for nested schema)
Read-Only
config_detail(String) The appliance's own words when it refused a configuration.config_generation(Number) The configuration generation that has been AUTHORED.config_revision(Number) The configuration generation the appliance has ACKNOWLEDGED. Null until something has been applied. When it differs fromconfig_generationthere is a change the gateway is not yet serving.config_status(String) What happened to the last configuration apply:pending,applying,applied,failedorunknown. Distinct fromstatus, which is the appliance's lifecycle — a gateway can berunningwhile its last configuration change was refused.created_at(String) The creation timestamp.id(String) The unique identifier of the Application Gateway.private_ip(String) The appliance's address inside your VPC.public_ip(String) The gateway's public address.status(String) The gateway's lifecycle state.tags_all(Map of String) Every tag the platform holds on this resource: the provider'sdefault_tags, this resource's owntags(which win on a shared key), and any key set outside Terraform — in the portal, by the fm CLI, or stamped by the platform. Keys set outside Terraform appear only here and are kept on every apply, never removed.updated_at(String) The last update timestamp.version(String) The appliance version this gateway runs. Read-only: the version is platform-managed and chosen by the server at create. You author routes, backends and WAF rules, never the data-plane configuration, so there is no version contract to pin here. WAF ruleset versions, which you do control, are on the WAF policy.vpc_cidr(String) The gateway's VPC range. Backend addresses are validated against it.waf_policy_id(String) The WAF policy attached to this gateway, if any.
Nested Schema for timeouts
Optional:
create(String) How long the provider waits for the create operation to converge before giving up (e.g. "45m", "2h").delete(String) How long the provider waits for the delete to complete before giving up (e.g. "30m").update(String) How long the provider waits for an update (resize, in-place change) to converge before giving up (e.g. "30m").