Skip to content

Migrating AWS Terraform to Frostmoln ​

To run a conversion, see the migration guide.

This matrix lists how the converter handles each supported resource type and attribute.

Provider configuration and tags ​

Provider block ​

Each provider "aws" block becomes a provider "frostmoln" block, and an aliased block keeps a literal alias. Region, credentials, role assumption, service endpoints and ignore_tags are not carried. The converted configuration declares frostmoln/frostmoln with version ~> 0.82 and requires frostmoln provider 0.82.0 or newer, so a private registry mirror must carry that version.

Default tags ​

The provider's default_tags carry onto the frostmoln provider's default_tags, which adds them to every taggable resource the configuration manages. They carry as written, except that: keys in the platform's own namespace (frostmoln_, frostmoln-, __) are removed; keys the frostmoln provider refuses as defaults — the prefixes os_, instance_ and nova_, and the keys request-id, customer-id, project-id, tenant-id, created-at, acl, storage-class, quota-bytes and cors-config, in any letter case — are commented out with a warning, to be set in the tags of the resources that need them; a key or value outside the accepted shape (keys of 1 to 64 bytes made of letters, digits and . _ : -, starting and ending with a letter or digit; values of at most 255 bytes made of letters, digits, spaces and + - . _ : / @ =) is commented out as a blocker; more than 10 tags comments out the whole set as a blocker; a dynamic "default_tags" block, or more than one default_tags block, is not carried (warning); and a provider block removed because another block becomes the same frostmoln configuration does not bring its default_tags (warning when the two differ). A key or value that is not a literal is carried as written, and the frostmoln provider checks it when the configuration is planned.

References to the merged tag set ​

A reference to a resource's tags_all maps to the converted resource's tags_all where the converted resource type has tags, and stays a blocker where it has none. tags_all holds the resource's own tags and the provider's default tags, plus any tag set outside Terraform. The frostmoln provider does not know tags_all while Terraform plans creating or updating the resource, so such a reference in for_each or count, or in a local value one of them reads, is reported as a blocker.

Tenant default tags ​

Frostmoln also has tenant default tags, a per-tenant setting of the platform. No source provider setting is tenant-scoped: default_tags apply to the resources of one configuration, and carry onto the frostmoln provider's default_tags, which are configuration-scoped as well. The converter never turns them into tenant default tags. AWS Organizations tag policies (aws_organizations_policy with type TAG_POLICY) are an organisational control with no converter mapping.

Tag colours ​

AWS tags have no colour. Frostmoln tag colours (set per organization, for display) have no source equivalent: set them after migration with frostmoln_tag_color or in the portal.

data.aws_ami → frostmoln_image — partially supported ​

The aws_ami data source maps to the frostmoln_image data source: images resolve by exact name, so a name is derived from the AMI name filter (or a reviewed placeholder is emitted) and the filter machinery disappears.

Platform images are selected by exact name. The converter derives a name guess from a filter { name = "name" } value (path segments and wildcards stripped) and upgrades it to an exact catalog name when the catalog knows it; verify the result against fm compute image list. Owner and recency selection have no equivalent.

AttributeOutcomeNotes
most_recentNot needed on Frostmolnimages resolve by exact name; recency selection does not apply.
ownersNot needed on Frostmolnthere is no account-id concept; the platform image catalog is shared.
executable_usersNot needed on Frostmolnthere is no account-id concept; the platform image catalog is shared.
filterNot needed on Frostmolnimage filters have no equivalent; the image name is derived from the name filter (see the synthesized name).
name_regexNot carried overregex image selection is not supported; set name to the exact image name.
include_deprecatedNot carried overnon-active images are hidden from the platform catalog.
  • The converter adds name automatically. frostmoln_image resolves by name; it is derived from the AMI name filter and needs review unless the catalog confirms it.

aws_autoscaling_group → frostmoln_scale_group — partially supported ​

Auto Scaling groups map to frostmoln_scale_group (sizes, subnets, health checks, cooldown, target pools); the launch_template block flattens to launch_template_id.

launch_template blocks flatten to launch_template_id, with the reference rewritten to the converted frostmoln_launch_template (name-based references still need manual work). target_group_arns become load_balancer_pool_ids with references rewritten to the converted pools.

AttributeOutcomeNotes
nameMapped to name
name_prefixManual action requiredgenerated names are not supported; set an explicit name.
min_sizeMapped to min_size
max_sizeMapped to max_size
desired_capacityMapped to desired_capacity
vpc_zone_identifierMapped to subnet_ids
launch_templateConverted to launch_template_idThe launch_template block flattens to launch_template_id referencing the converted frostmoln_launch_template; version pinning is dropped (launch templates are not versioned).
launch_configurationManual action requiredlaunch configurations have no equivalent; recreate the template as a frostmoln_launch_template and set launch_template_id.
mixed_instances_policyManual action requiredmixed-instance policies are not supported; a scale group uses a single launch template.
target_group_arnsMapped to load_balancer_pool_idsReferences are rewritten to the converted frostmoln_lb_pool resources.
health_check_typeConverted
health_check_grace_periodMapped to health_check_grace_period
default_cooldownMapped to cooldown_seconds
default_instance_warmupMapped to warmup_seconds
termination_policiesConverted to termination_policya scale group holds a single termination policy (oldest_first, newest_first, or closest_to_next_hour).
tag (also matches tags)Manual action requiredconvert tag blocks (or the tags list) to the tags map manually; per-tag propagation flags are not supported.
availability_zonesNot carried overthe platform picks zones; attach subnets via subnet_ids instead.
load_balancersManual action requiredclassic load balancers have no equivalent; attach pools via load_balancer_pool_ids.
capacity_rebalanceNot carried overcapacity rebalancing has no equivalent.
instance_refreshNot carried overinstance refresh is not supported; roll instances by updating the launch template.
warm_poolNot carried overwarm pools are not supported.
suspended_processesNot carried overscaling processes cannot be suspended individually.
enabled_metricsNot carried overgroup metrics are platform-managed.
metrics_granularityNot carried overgroup metrics are platform-managed.
placement_groupManual action requiredplacement groups have no equivalent.
service_linked_role_arnNot needed on FrostmolnFrostmoln has no assumable roles, so there is no service-linked role to name; the platform manages a scale group's own service access.
max_instance_lifetimeNot carried overinstance lifetime limits are not supported.
instance_maintenance_policyNot carried overmaintenance policies are not supported.
protect_from_scale_inNot carried overscale-in protection is not supported.
desired_capacity_typeNot carried overcapacity is always an instance count.
wait_for_capacity_timeoutNot needed on Frostmolncreation waits are platform-managed.
wait_for_elb_capacityNot needed on Frostmolncreation waits are platform-managed.
min_elb_capacityNot needed on Frostmolncreation waits are platform-managed.
force_deleteNot needed on Frostmolndeletion behavior is platform-defined.
force_delete_warm_poolNot needed on Frostmolnwarm pools are not supported.
ignore_failed_scaling_activitiesNot needed on Frostmolnscaling activity handling is platform-managed.
  • The converter adds launch_template_id automatically. the group carried no launch_template block; create a frostmoln_launch_template and reference it here.
  • The converter adds desired_capacity automatically. frostmoln_scale_group requires desired_capacity; when the source omits it, the min_size expression is copied verbatim. A group with neither desired_capacity nor min_size blocks - set desired_capacity manually.

aws_ebs_snapshot → frostmoln_snapshot — supported ​

EBS snapshots map to frostmoln_snapshot; a required snapshot name is synthesized from the Name tag or the resource address.

Snapshot archiving/restore tiers have no equivalent.

AttributeOutcomeNotes
volume_idMapped to volume_id
descriptionMapped to description
tagsConverted
tags_allNot carried overtags_all is computed, not configured: tags carry in tags, the provider-level default_tags carry onto the frostmoln provider's default_tags where the frostmoln provider accepts them as defaults, and the converted resource's tags_all holds the merged set plus any tag set outside Terraform.
storage_tierNot carried oversnapshot storage tiers have no equivalent.
permanent_restoreNot carried oversnapshot archiving has no equivalent.
temporary_restore_daysNot carried oversnapshot archiving has no equivalent.
outpost_arnManual action requiredOutposts have no equivalent.
  • The converter adds name automatically. frostmoln_snapshot requires a name; it is taken from the Name tag or the resource address.

aws_ebs_volume → frostmoln_volume — partially supported ​

EBS volumes map to frostmoln_volume; the EBS volume type is dropped (the platform's default tier applies) and IOPS/throughput are set by the volume tier.

Volume tiers are platform-defined — pick a volume_type from the volume tiers catalog (frostmoln_volume_tiers data source) after the conversion; a catalog-driven tier mapping arrives in a later release. A required volume name is synthesized from the Name tag or the resource address.

AttributeOutcomeNotes
sizeMapped to size_gb
availability_zoneConvertedThe zone is omitted - the platform picks it; set zone to a zone id to pin one (the frostmoln_regions data source exposes both zone ids and names).
typeNot carried overA catalog-driven tier mapping arrives in a later release.
encryptedMapped to encrypted
snapshot_idMapped to snapshot_id
iopsNot carried overIOPS are set by the volume tier.
throughputNot carried overthroughput is set by the volume tier.
kms_key_idManual action requiredencryption keys are platform-managed.
multi_attach_enabledManual action requiredmulti-attach volumes are not supported.
final_snapshotNot carried overfinal snapshots on delete are not supported; create a frostmoln_snapshot explicitly.
outpost_arnManual action requiredOutposts have no equivalent.
tagsConverted
tags_allNot carried overtags_all is computed, not configured: tags carry in tags, the provider-level default_tags carry onto the frostmoln provider's default_tags where the frostmoln provider accepts them as defaults, and the converted resource's tags_all holds the merged set plus any tag set outside Terraform.
  • The converter adds name automatically. frostmoln_volume requires a name; it is taken from the Name tag or the resource address.

aws_eip → frostmoln_public_ip — partially supported ​

Elastic IPs map to frostmoln_public_ip; a specific address cannot be requested — the platform allocates one.

An aws_eip_association referencing the EIP merges into the public IP as instance_id. public_ip references become the public IP's address.

AttributeOutcomeNotes
instanceMapped to instance_id
domain (also matches vpc)Not needed on Frostmolnall public IPs live in the tenant VPC scope; there is no EC2-classic/VPC split.
tagsConverted
tags_allNot carried overtags_all is computed, not configured: tags carry in tags, the provider-level default_tags carry onto the frostmoln provider's default_tags where the frostmoln provider accepts them as defaults, and the converted resource's tags_all holds the merged set plus any tag set outside Terraform.
addressManual action requiredspecific address selection is not supported; the platform allocates the address.
public_ipv4_poolManual action requiredspecific address selection is not supported; the platform allocates the address.
customer_owned_ipv4_poolManual action requiredcustomer-owned IP pools have no equivalent.
associate_with_private_ipManual action requiredassociating with a specific private IP is not supported; associate by instance.
network_border_groupNot carried overnetwork border groups have no equivalent.
network_interfaceManual action requirednetwork interfaces have no equivalent; associate by instance.

aws_eip_association → frostmoln_public_ip — partially supported ​

EIP associations merge into the frostmoln_public_ip they reference: the association resource disappears and the public IP gains instance_id.

Only associations that reference a same-module aws_eip by allocation_id and target an instance can merge. Network-interface and private-IP associations have no equivalent.

AttributeOutcomeNotes
allocation_idConvertedSelects the public IP that receives the association.
instance_idConvertedBecomes instance_id on the merged frostmoln_public_ip.
allow_reassociationNot needed on Frostmolnpublic IPs re-associate freely.
network_interface_idManual action requirednetwork interfaces have no equivalent; associations must target an instance.
private_ip_addressManual action requiredassociating with a specific private IP is not supported.
public_ipManual action requiredreference the EIP resource by allocation_id, not by address.

aws_instance → frostmoln_instance — partially supported ​

EC2 instances map to frostmoln_instance: the AMI becomes a frostmoln_image lookup, the instance type is capability-matched to a flavor, and a public IP becomes a generated frostmoln_public_ip; block devices and IAM instance profiles need manual work.

instance_type is matched against the platform flavor catalog (smallest active flavor with at least the source vCPUs and RAM) and emitted as a data "frostmoln_flavor" lookup — offline without a populated catalog a reviewed placeholder is emitted instead. The AMI becomes a data "frostmoln_image" lookup whose name needs review (fm compute image list). availability_zone is omitted (the platform picks the zone; set zone to pin one). Inline block devices are blocked — recreate them as frostmoln_volume + frostmoln_volume_attachment. A required instance name is synthesized from the Name tag or the resource address.

AttributeOutcomeNotes
amiConverted to image_idA literal AMI id becomes a frostmoln_image data source with a reviewed placeholder name; a data.aws_ami reference is rewritten to the converted image data source.
instance_typeConverted to flavor_idCapability-matched against the platform flavor catalog and emitted as a frostmoln_flavor data source lookup by name.
availability_zoneConvertedThe platform picks the zone; set zone to pin one.
subnet_idMapped to subnet_id
vpc_security_group_idsMapped to security_groups
security_groupsManual action requiredsecurity groups are referenced by id, not by name; reference the converted frostmoln_security_group ids in security_groups.
key_nameConverted to ssh_key_namesfrostmoln_instance takes a set of SSH key names.
user_dataMapped to user_data
user_data_base64Converted to user_datafrostmoln_instance takes plain-text user data.
user_data_replace_on_changeNot needed on Frostmolnuser_data changes always recreate the instance.
associate_public_ip_addressConvertedA true value becomes a generated frostmoln_public_ip bound to the instance.
tagsConverted
tags_allNot carried overtags_all is computed, not configured: tags carry in tags, the provider-level default_tags carry onto the frostmoln provider's default_tags where the frostmoln provider accepts them as defaults, and the converted resource's tags_all holds the merged set plus any tag set outside Terraform.
volume_tagsNot carried overvolume tags belong on the frostmoln_volume resources.
private_ipNot carried overstatic private IPs are not supported; the platform assigns one.
secondary_private_ipsManual action requiredsecondary private IPs are not supported.
iam_instance_profileManual action requiredinstances carry no ambient cloud identity — there is no instance profile to attach. Give the instance a frostmoln_api_key (or a frostmoln_s3_credential for bucket access), delivered like any other secret, and grant it what the role granted with a frostmoln_iam_policy attached via frostmoln_iam_policy_attachment.
root_block_deviceManual action requiredA volume split arrives in a later release.
ebs_block_deviceManual action requiredA volume split arrives in a later release.
ephemeral_block_deviceManual action requiredephemeral instance-store devices have no equivalent; recreate persistent disks as frostmoln_volume + frostmoln_volume_attachment.
network_interfaceManual action requiredcustom network interfaces are not supported; attach the instance via subnet_id.
ipv6_address_countManual action requiredIPv6 addressing is not supported yet.
ipv6_addressesManual action requiredIPv6 addressing is not supported yet.
monitoringNot needed on Frostmolninstance monitoring is always on; there is no detailed-monitoring toggle.
ebs_optimizedNot needed on Frostmolnstorage connectivity is platform-managed.
metadata_optionsNot needed on FrostmolnFrostmoln serves no instance metadata service, so there is nothing to tune.
credit_specificationNot needed on Frostmolnthere are no burstable CPU credits; the flavor defines CPU allocation.
source_dest_checkNot carried overNot carried over: there is no per-instance source/destination check. An instance forwards only while a frostmoln_vpc_route names its address as the next hop, and writing that route also lets it source addresses it does not own. Read the cost in the VPC routes documentation first.
tenancyNot carried overdedicated tenancy is not supported; instances share the platform fleet.
host_idManual action requireddedicated hosts have no equivalent.
host_resource_group_arnManual action requireddedicated hosts have no equivalent.
placement_groupManual action requiredplacement groups have no equivalent.
placement_partition_numberManual action requiredplacement groups have no equivalent.
cpu_options (also matches cpu_core_count, cpu_threads_per_core)Not carried overCPU topology is defined by the flavor.
hibernationNot carried overhibernation is not supported.
disable_api_terminationNot carried overtermination protection is not supported.
disable_api_stopNot carried overstop protection is not supported.
instance_initiated_shutdown_behaviorNot carried overshutdown behavior is platform-defined.
instance_market_optionsManual action requiredspot/market instances have no equivalent; instances are always on-demand.
capacity_reservation_specificationNot carried overcapacity reservations are not supported.
get_password_dataNot carried overpassword data retrieval is not supported; use SSH keys.
launch_templateManual action requiredlaunch-template-driven instances are not supported; set the instance attributes directly (frostmoln_launch_template pairs with scale groups).
maintenance_optionsNot carried overmaintenance windows are platform-managed.
private_dns_name_optionsNot carried overinstance DNS records are platform-managed.
enclave_optionsManual action requiredNitro enclaves have no equivalent.
  • The converter adds name automatically. frostmoln_instance requires a name; it is taken from the Name tag or the resource address.
  • The converter adds flavor_id automatically. frostmoln_instance requires a flavor; this instance pinned no instance_type (a launch-template-driven instance), so set flavor_id to a platform flavor (see fm compute flavor list).
  • The converter adds image_id automatically. frostmoln_instance requires an image; this instance pinned no ami (a launch-template-driven instance), so set image_id to a platform image (see fm compute image list).

aws_key_pair → frostmoln_ssh_key — supported ​

EC2 key pairs map directly to frostmoln_ssh_key.

The key name becomes the resource id; tags are not supported on SSH keys.

AttributeOutcomeNotes
key_nameMapped to name
key_name_prefixManual action requiredGenerated key names are not supported; set an explicit name.
public_keyMapped to public_key
tagsNot carried overfrostmoln_ssh_key has no tags.

aws_launch_template → frostmoln_launch_template — partially supported ​

Launch templates map to frostmoln_launch_template: the image becomes a frostmoln_image lookup, the instance type is capability-matched to a flavor, and user data is decoded from base64; the required vpc_id must be set manually.

instance_type is matched against the platform flavor catalog and emitted as a data "frostmoln_flavor" lookup; image_id becomes a data "frostmoln_image" lookup whose name needs review. key_name carries a key NAME but frostmoln_launch_template takes ssh_key_ids — replace the wrapped name with the frostmoln_ssh_key id. frostmoln_launch_template requires vpc_id, which AWS launch templates do not carry: a placeholder is synthesized. Launch templates are not versioned on Frostmoln.

AttributeOutcomeNotes
nameMapped to name
name_prefixManual action requiredgenerated names are not supported; set an explicit name.
descriptionNot carried overlaunch templates have no description.
image_idConvertedA literal AMI id becomes a frostmoln_image data source with a reviewed placeholder name; a data.aws_ami reference is rewritten to the converted image data source.
instance_typeConverted to flavor_idCapability-matched against the platform flavor catalog and emitted as a frostmoln_flavor data source lookup by name.
key_nameConverted to ssh_key_idsThe key NAME is wrapped into a set, but ssh_key_ids takes key IDs — replace it with the frostmoln_ssh_key id.
vpc_security_group_idsMapped to security_group_ids
security_group_namesManual action requiredsecurity groups are referenced by id, not by name; reference the converted frostmoln_security_group ids in security_group_ids.
user_dataConvertedAWS launch-template user data is base64; frostmoln_launch_template takes plain text.
tagsConverted
tags_allNot carried overtags_all is computed, not configured: tags carry in tags, the provider-level default_tags carry onto the frostmoln provider's default_tags where the frostmoln provider accepts them as defaults, and the converted resource's tags_all holds the merged set plus any tag set outside Terraform.
tag_specificationsManual action requiredper-resource tag propagation is not supported; set tags on the created resources.
default_versionNot needed on Frostmolnlaunch templates are not versioned.
update_default_versionNot needed on Frostmolnlaunch templates are not versioned.
block_device_mappingsManual action requiredA volume split arrives in a later release.
network_interfacesManual action requiredcustom network interfaces are not supported; scale groups attach instances via subnet_ids.
iam_instance_profileManual action requiredinstances carry no ambient cloud identity — there is no instance profile to attach. Give the instance a frostmoln_api_key (or a frostmoln_s3_credential for bucket access), delivered like any other secret, and grant it what the role granted with a frostmoln_iam_policy attached via frostmoln_iam_policy_attachment.
instance_market_optionsManual action requiredspot/market instances have no equivalent; instances are always on-demand.
instance_requirementsManual action requiredattribute-based instance selection is not supported; set an explicit flavor.
placementManual action requiredplacement groups have no equivalent.
monitoringNot needed on Frostmolninstance monitoring is always on; there is no detailed-monitoring toggle.
ebs_optimizedNot needed on Frostmolnstorage connectivity is platform-managed.
metadata_optionsNot needed on FrostmolnFrostmoln serves no instance metadata service, so there is nothing to tune.
credit_specificationNot needed on Frostmolnthere are no burstable CPU credits; the flavor defines CPU allocation.
cpu_optionsNot carried overCPU topology is defined by the flavor.
kernel_idNot carried overcustom kernels are not supported.
ram_disk_idNot carried overcustom RAM disks are not supported.
disable_api_stopNot carried overstop protection is not supported.
disable_api_terminationNot carried overtermination protection is not supported.
instance_initiated_shutdown_behaviorNot carried overshutdown behavior is platform-defined.
hibernation_optionsNot carried overhibernation is not supported.
elastic_gpu_specifications (retired by the provider)Manual action requiredGPU accelerators have no equivalent yet.
elastic_inference_accelerator (retired by the provider)Manual action requiredinference accelerators have no equivalent.
enclave_optionsManual action requiredNitro enclaves have no equivalent.
license_specificationNot carried overlicense configurations have no equivalent.
maintenance_optionsNot carried overmaintenance windows are platform-managed.
private_dns_name_optionsNot carried overinstance DNS records are platform-managed.
capacity_reservation_specificationNot carried overcapacity reservations are not supported.
  • The converter adds name automatically. frostmoln_launch_template requires a name; it is taken from the Name tag or the resource address.
  • The converter adds vpc_id automatically. frostmoln_launch_template requires the target VPC; set vpc_id to the converted frostmoln_vpc id.
  • The converter adds flavor_id automatically. frostmoln_launch_template requires a flavor; the source template did not pin an instance type.
  • The converter adds image_id automatically. frostmoln_launch_template requires an image; the source template did not pin one.

aws_lb → frostmoln_load_balancer — partially supported ​

Application and network load balancers map to frostmoln_load_balancer; Frostmoln LBs attach to a single subnet, and security groups move to listener allowed_cidrs.

internal = true/false becomes scheme = "internal"/"public" — note that aws_lb defaults to internet-facing while frostmoln_load_balancer defaults to internal, and a public scheme requires a public_ip_id. The required vpc_id cannot be derived from the source and is emitted as an FM-TODO placeholder. load_balancer_type application/network becomes type l7/l4.

AttributeOutcomeNotes
nameMapped to name
name_prefixManual action requiredgenerated names are not supported; set an explicit name.
internalConverted to schemeA public scheme requires a public_ip_id — create a frostmoln_public_ip for the load balancer.
load_balancer_typeConverted to type
subnetsConverted to subnet_idFrostmoln load balancers attach to a single subnet - keep one subnet and recreate the rest as separate load balancers.
subnet_mappingManual action requiredstatic address mappings are not supported; use public_ip_id for a public address.
security_groupsNot carried overaccess control moves to listener allowed_cidrs.
tagsConverted
tags_allNot carried overtags_all is computed, not configured: tags carry in tags, the provider-level default_tags carry onto the frostmoln provider's default_tags where the frostmoln provider accepts them as defaults, and the converted resource's tags_all holds the merged set plus any tag set outside Terraform.
enable_deletion_protectionNot carried overdeletion protection is not supported.
access_logsManual action requiredload-balancer access logs are not available.
connection_logsManual action requiredload-balancer connection logs are not available.
idle_timeoutNot carried overidle timeouts are platform-managed.
enable_http2Not carried overHTTP/2 negotiation is platform-managed.
enable_cross_zone_load_balancingNot needed on Frostmolnthe platform runs a single zone per load balancer.
ip_address_typeNot carried overload balancers are IPv4 today.
drop_invalid_header_fieldsNot carried overheader handling is platform-managed.
preserve_host_headerNot carried overheader handling is platform-managed.
xff_header_processing_modeNot carried overheader handling is platform-managed.
desync_mitigation_modeNot carried overdesync mitigation is platform-managed.
enable_waf_fail_openNot carried overFrostmoln's Web Application Firewall belongs to the Application Gateway, a separate offer from the load balancer — set fail_mode on a gateway-scoped frostmoln_appgw_waf_policy and publish it with a frostmoln_appgw_waf_policy_publication, because the setting is authored rather than enforced until it is published.
dns_record_client_routing_policyNot carried overDNS routing policies are not supported.
enable_tls_version_and_cipher_suite_headersNot carried overheader handling is platform-managed.
enable_zonal_shiftNot carried overzonal shift has no equivalent.
client_keep_aliveNot carried overkeep-alive tuning is platform-managed.
customer_owned_ipv4_poolManual action requiredcustomer-owned IP pools have no equivalent.
enforce_security_group_inbound_rules_on_private_link_trafficNot carried overthere is no PrivateLink concept.
  • The converter adds scheme automatically. aws_lb defaults to internet-facing, so an absent internal flag becomes scheme public; a public scheme requires a public_ip_id - create a frostmoln_public_ip or set scheme to "internal".
  • The converter adds vpc_id automatically. frostmoln_load_balancer requires vpc_id; set it to the VPC of the load balancer's subnet.

aws_lb_listener → frostmoln_lb_listener — partially supported ​

Load-balancer listeners map to frostmoln_lb_listener; a single forward default action becomes default_pool_id, and TLS certificates must be re-uploaded.

Frostmoln listeners are deny-by-default: a required allowed_cidrs list is synthesized as ["0.0.0.0/0"] with an FM-TODO — review it. HTTPS becomes terminated_https; upload the certificate and set tls_certificate_id manually. Redirect and fixed-response actions have no equivalent.

AttributeOutcomeNotes
load_balancer_arnMapped to load_balancer_id
portMapped to protocol_port
protocolConverted
default_actionConvertedA single forward action becomes default_pool_id referencing the converted pool; other action types must be recreated manually.
ssl_policyNot carried overTLS policies are platform-managed.
certificate_arnManual action requiredupload the certificate to the platform and set tls_certificate_id.
alpn_policyNot carried overALPN negotiation is platform-managed.
mutual_authenticationManual action requiredmutual TLS is not supported.
tcp_idle_timeout_secondsNot carried overidle timeouts are platform-managed.
tagsNot carried overfrostmoln_lb_listener carries no tags; tag the load balancer instead.
  • The converter adds name automatically. frostmoln_lb_listener requires a name; it is taken from the Name tag or the resource address.

aws_lb_target_group → frostmoln_lb_pool — partially supported ​

Target groups map to frostmoln_lb_pool; the inline health_check block splits into a frostmoln_lb_health_monitor, and stickiness becomes session_persistence.

frostmoln_lb_pool requires load_balancer_id, which a target group does not carry — an FM-TODO placeholder is emitted; set it to the converted load balancer. A required lb_algorithm defaults to round_robin unless load_balancing_algorithm_type maps one - note that an l4 load balancer only supports source_ip_port, so change lb_algorithm when attaching this pool to an l4 load balancer. Member ports are set per frostmoln_lb_member, so the port attribute is dropped.

AttributeOutcomeNotes
nameMapped to name
name_prefixManual action requiredgenerated names are not supported; set an explicit name.
protocolConverted
portNot carried overmember ports are set per frostmoln_lb_member protocol_port.
vpc_idNot needed on Frostmolnthe pool inherits networking from its load balancer.
target_typeNot needed on Frostmolnpool members are addresses; there is no target-type concept.
stickinessConvertedlb_cookie becomes HTTP_COOKIE, app_cookie becomes APP_COOKIE, source_ip becomes SOURCE_IP; cookie durations are platform-managed.
load_balancing_algorithm_typeConverted to lb_algorithm
load_balancing_anomaly_mitigationNot carried overanomaly mitigation has no equivalent.
load_balancing_cross_zone_enabledNot needed on Frostmolnthe platform runs a single zone per load balancer.
proxy_protocol_v2Converted to proxy_protocol
deregistration_delayNot carried overmember draining is platform-managed.
slow_startNot carried overslow start is not supported.
preserve_client_ipNot carried overclient-IP preservation is platform-managed.
connection_terminationNot carried overconnection termination on deregister is platform-managed.
lambda_multi_value_headers_enabledManual action requiredLambda targets have no equivalent.
ip_address_typeNot carried overpools are IPv4 today.
target_failoverNot carried overtarget failover has no equivalent.
target_health_stateNot carried overhealth-state handling is platform-managed.
target_group_healthNot carried overgroup-health thresholds have no equivalent.
tagsConverted
tags_allNot carried overtags_all is computed, not configured: tags carry in tags, the provider-level default_tags carry onto the frostmoln provider's default_tags where the frostmoln provider accepts them as defaults, and the converted resource's tags_all holds the merged set plus any tag set outside Terraform.

Inline health_check blocks are split into frostmoln_lb_health_monitor resources:

Block attributeOutcomeNotes
protocolConverted to type
pathMapped to url_path
intervalMapped to delay
timeoutMapped to timeout
healthy_thresholdMapped to max_retries
unhealthy_thresholdNot carried overmax_retries covers the retry count; a separate unhealthy threshold is not supported.
matcherMapped to expected_codes
portNot carried overhealth checks run against each member's protocol_port.
enabledNot carried overmonitors are always enabled; remove the monitor resource to disable checks.
  • The converter adds lb_algorithm automatically. frostmoln_lb_pool requires lb_algorithm; round_robin matches the AWS default.
  • The converter adds load_balancer_id automatically. frostmoln_lb_pool requires load_balancer_id; set it to the converted load balancer.
  • The converter adds name automatically. frostmoln_lb_pool requires a name; when the source omits one it is taken from the Name tag or the resource address.

aws_lb_target_group_attachment → frostmoln_lb_member — partially supported ​

Target-group attachments map to frostmoln_lb_member; the member address must be an IP, so instance-id targets need review.

target_id becomes address, which must be an IP address — instance references should use the instance's private IP attribute. The required load_balancer_id is emitted as an FM-TODO placeholder.

AttributeOutcomeNotes
target_group_arnMapped to pool_id
target_idConverted to addressIP targets carry over directly; instance-id targets must be changed to the instance's private IP.
portMapped to protocol_port
availability_zoneNot carried overthe platform picks zones.
  • The converter adds load_balancer_id automatically. frostmoln_lb_member requires load_balancer_id; set it to the converted load balancer.

aws_route → frostmoln_vpc_route — partially supported ​

a route to an appliance in the VPC becomes a frostmoln_vpc_route with its destination carried over and vpc_id plus the next-hop ADDRESS left as placeholders to fill in; a route to a gateway, NAT gateway, transit gateway, peering connection or endpoint is left unconverted (a specific destination out the internet gateway is rewritten by hand as next_hop = internet), a prefix-list destination is left unconverted, and an IPv6 destination converts like an IPv4 one except for an IPv6 default route, which does not.

A Frostmoln VPC has ONE route set and it belongs to the VPC, not to a table you associate with subnets — so a converted route applies to every instance in the VPC, whichever subnets its source table was associated with. Check for a route whose reach that WIDENS before you apply.

Subnet-to-subnet routing within the VPC is automatic and cannot be overridden: a destination that is, or falls inside, a subnet attached to the VPC is REFUSED, because that subnet already delivers it directly. An east-west route that sends one subnet's traffic to a firewall or inspection appliance therefore has no counterpart here and cannot be recreated — do not read it as redundant. Enforce east-west policy with security groups instead.

Two values cannot be carried over and are emitted as FM-TODO placeholders:

  • vpc_id, because route_table_id names a route table and the platform has none. Set it to the converted frostmoln_vpc.
  • next_hop, because a Frostmoln next hop is an IP ADDRESS on a subnet attached to the VPC (or the reserved token internet), never a resource id. An appliance route — network_interface_id or instance_id — therefore converts with its destination intact and its next hop left for you: set it to the appliance's address on a subnet in the VPC. The route is refused at apply time if that address is not reachable from one.

A route pointing at a gateway, a transit gateway, a peering connection, a VPC endpoint, or a carrier or local gateway is left UNCONVERTED rather than converted with a placeholder: a route that quietly sends the same traffic somewhere else is worse than no route, and the converter cannot always tell from the source which of them a gateway_id names.

ONE OF THEM DOES HAVE A COUNTERPART, and it is the one a forced tunnel needs. A route sending a SPECIFIC destination out the internet gateway is written here as a frostmoln_vpc_route with next_hop = "internet" — a reserved token meaning "out this VPC's own gateway", not an address. That is how you keep a VPN appliance's own tunnel working underneath a default route: without a more specific route for the appliance's remote peer, its encrypted packets match the default route and loop back to it. Because a route is matched on its destination only, that exception takes every instance in the VPC off the tunnel for the peer's address, not just the appliance. Rewrite such a route by hand; the converter will not guess it for you.

A DEFAULT route out the internet gateway is different: there is nothing to write, because the VPC's own gateway already provides it, and writing one is refused. But the gateway itself is not implied — 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 reach to that control plane either. (A managed database, cache or broker deployed INTO the VPC still answers on its private address — that traffic never crosses the gateway — but reaching it by name does need DNS.) See the aws_internet_gateway or aws_nat_gateway entry for what to add, and how to give it a source address you can publish.

A default route (0.0.0.0/0) IS accepted with an in-VPC next hop — an appliance address — and it captures ALL egress from the VPC. Public IPs on instances in that VPC stop serving while it exists, because the reply is routed by this same set and its destination is the internet client; the platform DNS resolver and the managed-service control plane keep working, because they ride routes more specific than a default one. It also counts as TWO against the VPC's route limit. A default route pointing at internet is refused instead: that is the route the VPC's own gateway already provides. A route naming an INSTANCE address lets that instance send with source addresses it does not own: every subnet attached to the VPC, plus the destination of every route pointing at that address -- with a default route, any address at all. Security group rules keyed on a source address stop constraining it, and it can claim another instance's address on the subnet. That is what makes the appliance forward at all, and it is granted automatically with no way to narrow it, so keep such an instance a dedicated appliance and put anything that must be protected from it in another VPC.

AttributeOutcomeNotes
route_table_idNot carried overThere are no route tables; vpc_id is emitted as a placeholder for you to point at the converted frostmoln_vpc.
regionNot needed on Frostmolnthe platform is single-region; the default region applies.
destination_cidr_blockConverted to destinationCarried over. A prefix with host bits set is masked (203.0.113.5/24 -> 203.0.113.0/24), which is the form the platform accepts; a LITERAL default route is flagged, because it captures all egress from the VPC (one built from a variable cannot be read, so it is not); a default-route half (0.0.0.0/1, 128.0.0.0/1) is refused, because those are how the platform stores a default route internally.
destination_ipv6_cidr_blockConverted to destinationCarried over like an IPv4 destination — an IPv6 route is legal with an IPv6 next hop on a subnet attached to the VPC, so set next_hop to one. An IPv6 DEFAULT route (::/0) is the exception: it is not offered, and it leaves the whole route unconverted.
destination_prefix_list_idManual action requiredLeft unconverted: prefix lists have no equivalent. Write the ranges the list holds as individual routes.
network_interface_idNot carried overA next hop is an IP ADDRESS, not a resource id, so next_hop is emitted as a placeholder: set it to the appliance's address on a subnet attached to the VPC.
instance_idNot carried overA next hop is an IP ADDRESS, not a resource id, so next_hop is emitted as a placeholder: set it to the instance's address on a subnet attached to the VPC.
gateway_idManual action requiredLeft unconverted because the three kinds of gateway this attribute carries convert differently. An internet gateway with a SPECIFIC destination becomes next_hop = internet — that is how the exception route a forced tunnel needs is written. A 0.0.0.0/0 to an internet gateway needs no route at all: the VPC's frostmoln_gateway already provides it, and writing one is refused. A VPN or local gateway has no equivalent.
nat_gateway_idManual action requiredLeft unconverted. Outbound comes from the VPC's frostmoln_gateway, which already carries the default route; a specific destination that should leave through it is written as next_hop = internet.
egress_only_gateway_idManual action requiredLeft unconverted: this is an IPv6-only construct and the platform does not offer customer IPv6 routing yet.
transit_gateway_idManual action requiredLeft unconverted: transit gateways have no equivalent.
vpc_peering_connection_idManual action requiredLeft unconverted: VPC peering has no equivalent — place workloads that must communicate in the same VPC.
vpc_endpoint_idManual action requiredLeft unconverted: VPC endpoints have no equivalent.
carrier_gateway_idManual action requiredLeft unconverted: carrier gateways have no equivalent.
local_gateway_idManual action requiredLeft unconverted: Outposts local gateways have no equivalent.
core_network_arnManual action requiredLeft unconverted: Cloud WAN core networks have no equivalent.
odb_network_arnManual action requiredLeft unconverted: Oracle Database@AWS networks have no equivalent.
  • The converter adds vpc_id automatically. a frostmoln_vpc_route belongs to a VPC rather than to a route table; set vpc_id to the converted frostmoln_vpc.
  • The converter adds next_hop automatically. a next hop is an IP address on a subnet attached to the VPC, or the token internet (which needs the VPC to have a frostmoln_gateway); set next_hop to the address traffic for this destination should go to.

aws_route53_record → frostmoln_dns_record — partially supported ​

Simple DNS records map to frostmoln_dns_record; record names become zone-relative, and alias records and routing policies (weighted, latency, failover, geolocation) have no equivalent.

Supported record types: A, AAAA, CNAME, MX, TXT, NS, SRV, CAA, PTR. Record names are zone-relative on Frostmoln (the zone name is appended automatically), so fully qualified names block the conversion - strip the zone suffix, or use "@" for the apex. Alias records must be recreated as CNAME (or A) records with explicit values. Record names must be lowercase.

AttributeOutcomeNotes
zone_idMapped to zone_id
nameConvertedRecord names are zone-relative: "www" carries over, "www.example.com" blocks the conversion (the platform appends the zone name automatically). Names must be lowercase.
typeConverted
ttlMapped to ttl
recordsMapped to records
aliasManual action requiredalias records have no equivalent; the record is converted to an explicit record with FM-TODO placeholders - fill in the value the alias resolved to (the commented-out alias block shows what it pointed at) and the TTL.
weighted_routing_policyManual action requiredrouting policies are not supported.
latency_routing_policyManual action requiredrouting policies are not supported.
failover_routing_policyManual action requiredrouting policies are not supported.
geolocation_routing_policyManual action requiredrouting policies are not supported.
geoproximity_routing_policyManual action requiredrouting policies are not supported.
cidr_routing_policyManual action requiredrouting policies are not supported.
multivalue_answer_routing_policyManual action requiredrouting policies are not supported.
set_identifierManual action requiredrouting policies are not supported.
health_check_idManual action requiredDNS health checks are not supported.
allow_overwriteNot needed on Frostmolnrecords are managed exclusively through Terraform; there is no overwrite concept.
  • The converter adds records automatically. this record has no explicit values, so it is an alias record; Frostmoln has no alias records - set the value the alias resolved to (the commented-out alias block shows its target)
  • The converter adds ttl automatically. alias records inherit their target's TTL on AWS; a frostmoln_dns_record needs an explicit one

aws_route53_zone → frostmoln_dns_zone — partially supported ​

Public hosted zones map to frostmoln_dns_zone; private zones are not supported, and a required SOA email is synthesized as a placeholder.

Zone names are normalized to lowercase fully qualified domains with a trailing dot (the platform requires that form). The required SOA admin email cannot come from Route 53 — an FM-TODO placeholder is emitted.

AttributeOutcomeNotes
nameConvertedZone names are normalized to a lowercase FQDN with a trailing dot, e.g. "example.com."
commentMapped to description
tagsConverted
tags_allNot carried overtags_all is computed, not configured: tags carry in tags, the provider-level default_tags carry onto the frostmoln provider's default_tags where the frostmoln provider accepts them as defaults, and the converted resource's tags_all holds the merged set plus any tag set outside Terraform.
vpcManual action requiredprivate hosted zones are not supported; only public zones convert.
force_destroyNot needed on Frostmolnzones are deleted with their records.
delegation_set_idNot carried overdelegation sets are platform-managed.
  • The converter adds email automatically. the SOA admin email is required; replace the placeholder with a real contact address.

aws_s3_bucket → frostmoln_bucket — partially supported ​

S3 buckets map to frostmoln_bucket (name, region, storage class, tags, versioning); CORS and lifecycle rules are separate Frostmoln resources you recreate alongside it, while ACLs, policies, website hosting, logging, replication, and object lock have no equivalent.

An aws_s3_bucket_versioning resource referencing the bucket merges into the versioning attribute. Objects are stored on encrypted disks, so SSE configuration disappears. Buckets are private by default and customer credentials cannot change that - re-grant access with frostmoln_s3_credential narrowed to the bucket. Lifecycle rules and CORS are not attributes of frostmoln_bucket: they are their own resources, frostmoln_bucket_lifecycle_configuration and frostmoln_bucket_cors_configuration, each replacing its bucket's document whole. The converter does not generate them, so recreate them yourself.

AttributeOutcomeNotes
bucketMapped to name
bucket_prefixManual action requiredgenerated names are not supported; set an explicit name.
regionConvertedFrostmoln is single-region today; the platform default region applies.
tagsConverted
tags_allNot carried overtags_all is computed, not configured: tags carry in tags, the provider-level default_tags carry onto the frostmoln provider's default_tags where the frostmoln provider accepts them as defaults, and the converted resource's tags_all holds the merged set plus any tag set outside Terraform.
force_destroyNot needed on Frostmolnbucket deletion behavior is platform-defined.
aclManual action requiredACLs cannot be set from Terraform; buckets are private by default - re-grant access with frostmoln_s3_credential narrowed to the bucket.
grantManual action requiredACL grants are not supported; buckets are private - re-grant access with S3 credentials scoped to the bucket.
policyManual action requiredbucket policies are not supported; re-create access rules with S3 credentials scoped to the bucket.
websiteManual action requiredstatic-website hosting is not available.
cors_ruleManual action requireda bucket's CORS configuration is a separate resource on Frostmoln and is not generated here — recreate these rules as a frostmoln_bucket_cors_configuration for the bucket. It replaces the bucket's CORS document WHOLE, and every new bucket already carries a rule Frostmoln added for the customer portal's origin, so a configuration that declares only the origins converted from here silently removes it and the portal's object browser stops working for that bucket. That default is applied at bucket creation only, so nothing puts it back: read the bucket's current CORS before taking it over and re-declare what is actually there.
lifecycle_ruleManual action requireda bucket's lifecycle configuration is a separate resource on Frostmoln and is not generated here — recreate the expiration, noncurrent-version expiration and abort-incomplete-multipart rules as a frostmoln_bucket_lifecycle_configuration. Storage-class transition rules have no counterpart: a bucket carries a storage class, but objects are not moved between classes on a schedule.
versioningManual action requiredset the versioning attribute on frostmoln_bucket instead (an aws_s3_bucket_versioning resource merges automatically).
loggingNot carried overbucket access logging is not yet configurable.
replication_configurationManual action requiredcross-region replication is not available.
server_side_encryption_configurationManual action requiredobject data is encrypted at rest unconditionally, but there is no per-bucket setting and no customer-managed key; re-check the requirement that named this key.
object_lock_configurationManual action requiredobject lock is not available.
object_lock_enabledManual action requiredobject lock is not available.
acceleration_statusNot needed on Frostmolnthere is no transfer-acceleration concept.
request_payerNot needed on Frostmolnthere is no requester-pays billing concept.

aws_s3_bucket_versioning → frostmoln_bucket — partially supported ​

Bucket versioning resources merge into the frostmoln_bucket they reference: the resource disappears and the bucket gains versioning = "enabled" or "suspended".

Only Enabled and Suspended states merge, and the bucket must be a same-module aws_s3_bucket reference. MFA delete is not supported.

AttributeOutcomeNotes
bucketConvertedSelects the bucket that receives the versioning attribute.
versioning_configurationConvertedThe status becomes versioning on the merged frostmoln_bucket ("enabled" or "suspended").
expected_bucket_ownerNot needed on Frostmolnthere is no account-id concept.
mfaNot carried overMFA delete is not supported.

aws_secretsmanager_secret → frostmoln_secret — partially supported ​

Secrets Manager secrets map to frostmoln_secret; the value is set on the secret itself rather than in a separate version resource.

On AWS the value lives in an aws_secretsmanager_secret_version - Frostmoln stores it on the secret and versions it internally, so a required secret_value is emitted as an FM-TODO placeholder: fill it from the corresponding version's secret_string. Two behaviours differ and are worth checking: secret NAMES are restricted to letters, digits, dots, underscores and hyphens (the idiomatic prod/db/password form is rejected, so it blocks rather than failing at apply), and the recovery window DEFAULTS to 7 days here against 30 on AWS - set recovery_window_days explicitly if you relied on the AWS default. Encryption is unconditional, so there is no key to choose; resource policies and cross-region replicas have no equivalent, and rotation is explicit rather than scheduled.

AttributeOutcomeNotes
nameConvertedSecret names are restricted to letters, digits, dots, underscores and hyphens; a slash-separated AWS name blocks the conversion.
descriptionMapped to description
recovery_window_in_daysMapped to recovery_window_daysMeans the same thing - soft delete, then permanent purge - but the platform default is 7 days against AWS's 30, so an omitted value shortens the window.
tagsConverted
tags_allNot carried overtags_all is computed, not configured: tags carry in tags, the provider-level default_tags carry onto the frostmoln provider's default_tags where the frostmoln provider accepts them as defaults, and the converted resource's tags_all holds the merged set plus any tag set outside Terraform.
name_prefixManual action requiredgenerated names are not supported; set an explicit name.
kms_key_idNot needed on Frostmolnsecrets are always encrypted at rest with a platform-managed key; there is no key to select.
policyManual action requiredresource policies are not supported; grant access with a frostmoln_iam_policy attached to the api_key, workload_identity, or group that needs the secret.
replicaNot needed on Frostmolndata is stored in the single EU region; there is nothing to replicate to.
force_overwrite_replica_secretNot needed on Frostmolnthere are no replicas.
  • The converter adds secret_value automatically. frostmoln_secret holds the value inline; set secret_value from the corresponding aws_secretsmanager_secret_version's secret_string.

aws_security_group → frostmoln_security_group — partially supported ​

Security groups map to frostmoln_security_group; inline ingress/egress blocks are split into one frostmoln_security_group_rule per CIDR, source group, or self rule.

Frostmoln security-group rules are standalone resources, so every inline rule block fans out into frostmoln_security_group_rule resources — one per CIDR block, one per source security group, and one for self. 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. An ipv6_cidr_blocks entry is REFUSED as a blocker and no rule is generated for it, so a mixed-family block converts its cidr_blocks entries and is missing exactly the IPv6 half; a block whose ONLY remote is ipv6_cidr_blocks generates no rules at all and blocks in full. Do NOT translate an IPv6 range to an IPv4 one, it selects different hosts. Prefix lists are not supported either. EGRESS IS WIDENED BY CONVERSION: a Terraform-managed AWS security group denies egress unless the configuration declares it, and every Frostmoln security group is created with allow-all egress (the platform adds one IPv4 and one IPv6 allow-any egress rule to every new group and removes neither), and converted egress rules ADD to those defaults rather than replacing them. A source group with tightly restricted egress is therefore widened just as much as one with no egress block at all - declaring egress rules does NOT make the converted group faithful. The converted configuration does not manage the defaults, so no terraform apply removes them, and the platform re-creates them whenever the group is replaced (changing vpc_id forces replacement). Deleting them restores the source posture but makes the converted rules the group's ENTIRE egress policy: confirm they cover everything the instances need outbound, including DNS; note that no converted rule is IPv6, because frostmoln_security_group_rule has no ether_type, so deleting the IPv6 default denies all IPv6 egress with no replacement expressible in Terraform; and remember egress is the UNION of every security group on the instance's ports, including the tenant's implicit default group, which has allow-all egress of its own.

AttributeOutcomeNotes
nameMapped to name
name_prefixManual action requiredgenerated names are not supported; set an explicit name.
descriptionConvertedThe description is carried to the security group's description. One longer than the platform's 1024-character limit is refused with a blocker rather than converted to configuration that fails when applied.
vpc_idMapped to vpc_id
tagsConverted
tags_allNot carried overtags_all is computed, not configured: tags carry in tags, the provider-level default_tags carry onto the frostmoln provider's default_tags where the frostmoln provider accepts them as defaults, and the converted resource's tags_all holds the merged set plus any tag set outside Terraform.
revoke_rules_on_deleteNot needed on Frostmolnrule cleanup on delete is platform-managed.

Inline ingress/egress blocks are split into frostmoln_security_group_rule resources (one per element of cidr_blocks, security_groups):

Block attributeOutcomeNotes
protocolConverted
from_portConverted to port_range_min
to_portConverted to port_range_max
cidr_blocksOne resource per element, becomes remote_cidr
security_groupsOne resource per element, becomes remote_group_id
selfConverted to remote_group_id
descriptionMapped to description
ipv6_cidr_blocksManual action requiredthe block's ipv6_cidr_blocks entries are IPv6 remotes, and a frostmoln_security_group_rule has no ether_type field — every rule the platform creates is IPv4, so no rule was generated for them. The block's cidr_blocks entries still converted: this security group is missing exactly the IPv6 half of what the source declared. Restrict those remotes to IPv4 CIDRs, or leave them out until the platform supports IPv6 security-group rules — do NOT translate an IPv6 range to an IPv4 one, it selects different hosts. (An inline block whose ONLY remote is ipv6_cidr_blocks generates no rules at all and blocks in full; the standalone aws_security_group_rule resource blocks the whole rule for the same reason.)
prefix_list_idsManual action requiredprefix lists have no equivalent; expand them into CIDR rules.
  • The converter adds name automatically. frostmoln_security_group requires a name; when the source omits one it is taken from the Name tag or the resource address.

aws_security_group_rule → frostmoln_security_group_rule — partially supported ​

Standalone security-group rules map to frostmoln_security_group_rule; one rule per CIDR (multi-CIDR lists must be split), and IPv6/prefix lists are not supported yet.

type becomes direction, from/to_port become port_range_min/max, and "-1" protocols become "any". A cidr_blocks list with more than one element blocks the conversion — create one frostmoln_security_group_rule per CIDR.

AttributeOutcomeNotes
typeConverted to direction
protocolConverted
from_portConverted to port_range_min
to_portConverted to port_range_max
cidr_blocksConverted to remote_cidra rule holds a single remote_cidr; create one frostmoln_security_group_rule per CIDR.
source_security_group_idMapped to remote_group_id
security_group_idMapped to security_group_id
descriptionMapped to description
selfConverted to remote_group_id
ipv6_cidr_blocksManual action requiredthe rule's remotes are IPv6, and a frostmoln_security_group_rule has no ether_type field — every rule the platform creates is IPv4, so this rule cannot be expressed and was left unconverted rather than emitted as a rule that is rejected when it is applied. Restrict the remote to an IPv4 CIDR, or leave the rule out until the platform supports IPv6 security-group rules — do NOT translate an IPv6 range to an IPv4 one, it selects different hosts.
prefix_list_idsManual action requiredprefix lists have no equivalent; expand them into CIDR rules.

data.aws_subnet → frostmoln_subnet — partially supported ​

The aws_subnet data source maps to the frostmoln_subnet data source, which selects a subnet by id or name (optionally narrowed by vpc_id); CIDR, zone, tag, and filter-based lookups have no equivalent.

frostmoln_subnet looks up a subnet by id or name, optionally narrowed by vpc_id. The AWS data source's alternative selectors — cidr_block, availability_zone, tags, filter blocks, and the default-for-AZ flag — block the conversion: look the subnet up by id or name instead. Attribute references (cidr_block, availability_zone, ...) are rewritten to the frostmoln_subnet data source's exported attributes.

AttributeOutcomeNotes
idMapped to id
vpc_idMapped to vpc_id
cidr_blockManual action requiredCIDR-based lookup is not supported; look the subnet up by id or name.
availability_zoneManual action requiredzone-based lookup is not supported; look the subnet up by id or name.
availability_zone_idManual action requiredzone-based lookup is not supported; look the subnet up by id or name.
default_for_azManual action requiredthere is no default-for-AZ lookup; look the subnet up by id or name.
stateManual action requiredstate-based lookup is not supported; look the subnet up by id or name.
tagsManual action requiredtag-based lookup is not supported; look the subnet up by id or name.
filterManual action requiredfilter-based lookup is not supported; look the subnet up by id or name.

aws_subnet → frostmoln_subnet — partially supported ​

Subnets map to frostmoln_subnet; the platform picks the zone, and IPv6 addressing is not supported yet.

A required subnet name is synthesized from the Name tag or the resource address. availability_zone is omitted because the platform picks the zone — set zone to a zone id to pin one (the frostmoln_regions data source exposes both zone ids and names).

AttributeOutcomeNotes
cidr_blockMapped to cidr
vpc_idMapped to vpc_id
availability_zoneConvertedThe zone is omitted - the platform picks it; set zone to a zone id to pin one (the frostmoln_regions data source exposes both zone ids and names).
availability_zone_idNot carried overthe platform picks the zone; set zone manually to pin one.
map_public_ip_on_launchNot needed on Frostmolninbound reachability is per workload (a public IP on the instance, or a load balancer), not subnet-level auto-assignment; outbound is the VPC's gateway (frostmoln_gateway), also never a subnet property.
tagsConverted
tags_allNot carried overtags_all is computed, not configured: tags carry in tags, the provider-level default_tags carry onto the frostmoln provider's default_tags where the frostmoln provider accepts them as defaults, and the converted resource's tags_all holds the merged set plus any tag set outside Terraform.
assign_ipv6_address_on_creationManual action requiredIPv6 subnets are not supported yet.
ipv6_cidr_blockManual action requiredIPv6 subnets are not supported yet.
ipv6_nativeManual action requiredIPv6 subnets are not supported yet.
enable_dns64Manual action requiredIPv6 subnets are not supported yet.
enable_resource_name_dns_a_record_on_launchNot carried overinstance DNS records are platform-managed.
enable_resource_name_dns_aaaa_record_on_launchNot carried overinstance DNS records are platform-managed.
private_dns_hostname_type_on_launchNot carried overinstance DNS records are platform-managed.
customer_owned_ipv4_poolManual action requiredcustomer-owned IP pools have no equivalent.
map_customer_owned_ip_on_launchManual action requiredcustomer-owned IP pools have no equivalent.
outpost_arnManual action requiredOutposts have no equivalent.
  • The converter adds name automatically. frostmoln_subnet requires a name; it is taken from the Name tag or the resource address.

aws_volume_attachment → frostmoln_volume_attachment — supported ​

Volume attachments map directly to frostmoln_volume_attachment; device_name becomes device_path.

Detach behavior flags (force_detach, skip_destroy, stop_instance_before_detaching) are platform-managed and dropped.

AttributeOutcomeNotes
device_nameMapped to device_path
volume_idMapped to volume_id
instance_idMapped to instance_id
force_detachNot carried overdetach behavior is platform-managed.
skip_destroyNot carried overattachments are always detached on destroy.
stop_instance_before_detachingNot carried overdetach behavior is platform-managed.

data.aws_vpc → frostmoln_vpc — partially supported ​

The aws_vpc data source maps to the frostmoln_vpc data source, which selects a VPC by id or name; CIDR, tag, and filter-based lookups have no equivalent.

frostmoln_vpc looks up a VPC by exactly one of id or name. The AWS data source's alternative selectors — cidr_block, tags, filter blocks, dhcp_options_id, state, and the default-VPC flag — block the conversion: look the VPC up by id or name instead. Attribute references (cidr_block, arn, ...) are rewritten to the frostmoln_vpc data source's exported attributes.

AttributeOutcomeNotes
idMapped to id
cidr_blockManual action requiredCIDR-based lookup is not supported; look the VPC up by id or name.
dhcp_options_idManual action requiredDHCP-options lookup is not supported; look the VPC up by id or name.
defaultManual action requiredthere is no default-VPC lookup; look the VPC up by id or name.
stateManual action requiredstate-based lookup is not supported; look the VPC up by id or name.
tagsManual action requiredtag-based lookup is not supported; look the VPC up by id or name.
filterManual action requiredfilter-based lookup is not supported; look the VPC up by id or name.

aws_vpc → frostmoln_vpc — partially supported ​

VPCs map to frostmoln_vpc; DNS options are platform defaults and IPAM/IPv6 pools are not supported yet.

A required VPC name is synthesized from the Name tag or the resource address. Platform DNS is always enabled, so the enable_dns_* flags disappear. IPv6 and IPAM-managed addressing have no equivalent yet. 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 control plane, because those are reached over routes that exist only while the egress path does (a managed database, cache or broker deployed INTO the VPC still answers on its private address; reaching it by name needs DNS). The source configuration's aws_internet_gateway and aws_nat_gateway do not convert into one — see their entries.

AttributeOutcomeNotes
cidr_blockMapped to cidr
tagsConverted
tags_allNot carried overtags_all is computed, not configured: tags carry in tags, the provider-level default_tags carry onto the frostmoln provider's default_tags where the frostmoln provider accepts them as defaults, and the converted resource's tags_all holds the merged set plus any tag set outside Terraform.
enable_dns_supportNot needed on Frostmolnplatform DNS is always on
enable_dns_hostnamesNot needed on Frostmolnplatform DNS is always on
instance_tenancyNot carried overthere is no dedicated-tenancy concept; all VPCs share the platform fleet.
enable_network_address_usage_metricsNot carried overaddress-usage metrics are not exposed per VPC.
ipv4_ipam_pool_idManual action requiredno IPAM/IPv6 support yet.
ipv4_netmask_lengthManual action requiredno IPAM/IPv6 support yet.
ipv6_cidr_blockManual action requiredno IPAM/IPv6 support yet.
ipv6_ipam_pool_idManual action requiredno IPAM/IPv6 support yet.
ipv6_netmask_lengthManual action requiredno IPAM/IPv6 support yet.
ipv6_cidr_block_network_border_groupManual action requiredno IPAM/IPv6 support yet.
assign_generated_ipv6_cidr_blockManual action requiredno IPAM/IPv6 support yet.
  • The converter adds name automatically. frostmoln_vpc requires a name; it is taken from the Name tag or the resource address.

Resources the converter does not convert ​

ResourceWhat happens
data.aws_caller_identityThere is no caller-identity data source; the tenant the provider operates in is provider configuration (the frostmoln provider's tenant_id, or FROSTMOLN_TENANT_ID), so replace references with that value.
aws_db_subnet_groupDatabase subnet groups are removed; resolve to a subnet_id on the database instance.
aws_egress_only_internet_gatewayThis is the IPv6 outbound path and Frostmoln VPCs are IPv4-only; the IPv4 outbound path is a frostmoln_gateway, a separate resource you must add. The VPC may have at most ONE, so every gateway serving it collapses into that one.
aws_iam_access_keyThere is no IAM access key; use frostmoln_api_key for the platform API, or frostmoln_s3_credential for bucket access.
aws_iam_instance_profileInstances carry no ambient cloud identity on Frostmoln; there is no instance profile to attach.
aws_iam_openid_connect_providerFrostmoln does not federate an arbitrary external OIDC issuer; workload identity covers Frostmoln-managed Kubernetes only.
aws_iam_policyManaged policies do not convert; Frostmoln has frostmoln_iam_policy, but its document is a different language that must be rewritten.
data.aws_iam_policy_documentRenders an AWS policy JSON document; Frostmoln has its own policy language, so rewrite it with the frostmoln_iam_policy_document data source.
aws_iam_roleFrostmoln has no assumable roles; permissions attach directly to an API key, a workload identity, or a group.
aws_iam_role_policyInline role policies do not convert; there are no roles on Frostmoln to inline a policy into.
aws_iam_role_policy_attachmentPolicy attachments do not convert as-is; frostmoln_iam_policy_attachment attaches to a principal or group, never to a role.
data.aws_iam_rolesThere are no assumable roles on Frostmoln to enumerate.
aws_iam_userFrostmoln has no IAM users; people are organization members and machine callers are API keys.
aws_iam_user_policyInline user policies do not convert; there is no IAM user to inline a policy into.
aws_internet_gatewayFrostmoln splits the two directions an internet gateway carries — outbound is the VPC's frostmoln_gateway, inbound is a Public IP or a load balancer — and a converted VPC has neither until you ask for them. The VPC may have at most ONE gateway, so every gateway serving it collapses into that one.
aws_internet_gateway_attachmentThere is no gateway to attach: a Frostmoln VPC's outbound path is its own resource (frostmoln_gateway) and inbound is per workload, never a VPC-wide attachment. The VPC may have at most ONE such resource, so every gateway serving it collapses into that one.
aws_main_route_table_associationThere is no main route table to point at: a Frostmoln VPC has ONE route set that already applies to the whole VPC, so this association is removed — and it carries no VPC-wide default route to the internet, which comes from the VPC's gateway.
aws_nat_gatewayA 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 NAT gateways serving one VPC collapse into a single gateway.
aws_nat_gateway_eip_associationA frostmoln_gateway carries ONE source address — the platform's, or a single Public IP you own and name — so an association that attaches several allocated addresses has no counterpart.
aws_route_tableThere is no route-table object: a Frostmoln VPC has ONE route set, held on the VPC itself, so the table is removed — its individual routes are convertible (see aws_route), but routes written INLINE in this block are not, and the internet default route it usually carries is not replaced.
aws_route_table_associationThere is nothing to associate: a Frostmoln VPC has ONE route set that applies to every subnet in it, so the association is removed and the routes of every associated table merge into that one set.
aws_s3_bucket_aclBucket and object ACLs cannot be set from Terraform; buckets are private by default and access is granted with S3 credentials.
aws_s3_bucket_lifecycle_configurationLifecycle rules are a frostmoln_bucket_lifecycle_configuration, but this resource is not converted automatically - rewrite it, because the rule vocabularies differ and a wrong guess here deletes objects.
aws_s3_bucket_ownership_controlsObject ownership is not configurable; there is no ACL or cross-account concept, so the resource is removed.
aws_s3_bucket_policyThere is no resource-side bucket policy; access is granted from the principal side instead.
aws_s3_bucket_public_access_blockPublic-access blocking is the platform default; Frostmoln buckets are private and the resource is removed.
aws_s3_bucket_server_side_encryption_configurationObject data is encrypted at rest unconditionally, but there is no per-bucket encryption setting and no customer-managed key.
aws_secretsmanager_secret_versionSecret versions have no standalone equivalent; the value is set on the frostmoln_secret directly.
data.aws_security_groupThe aws_security_group data source has no equivalent yet: Frostmoln exposes no security-group lookup data source. Reference the converted frostmoln_security_group resource, or its id, directly.
aws_wafv2_web_aclFrostmoln has a Web Application Firewall, but it is part of an Application Gateway rather than a standalone resource, so a web ACL does not convert on its own — recreate it as a frostmoln_appgw_waf_policy on the gateway that fronts the same traffic.

data.aws_caller_identity ​

This data source reads nothing and creates nothing - it exposes who Terraform is authenticated as. The frostmoln provider already knows: it operates in exactly ONE tenant, taken from the provider's tenant_id (or FROSTMOLN_TENANT_ID), defaulting to the account's default tenant when neither is set. Use a variable for the tenant id and pass it to the provider, then reference that variable where data.aws_caller_identity.current.account_id was used. Most uses of account_id are ARN construction, and that does not carry over either: Frostmoln identifies policy targets with FRNs, shaped frn:<service>:<region>:<tenant>:<type>/<id>, which you write as patterns in a frostmoln_iam_policy_document targets list - usually with * for the tenant segment, since a policy is already tenant-scoped, and always with * for the region segment, which is all the provider accepts today. There is no account number to interpolate, and nothing constructs an FRN for you. arn and user_id have no counterpart: the identity behind an API key is not addressable in configuration, and permissions are attached to the api_key, workload_identity, or group directly with frostmoln_iam_policy_attachment.

aws_db_subnet_group ​

Frostmoln database instances attach to a single subnet — set subnet_id on the frostmoln_postgres_instance/frostmoln_mysql_instance directly.

aws_egress_only_internet_gateway ​

An egress-only internet gateway is the IPv6 half of outbound connectivity. It has no equivalent, for two independent reasons, and both matter.

First, Frostmoln VPCs are IPv4-only today: every IPv6 attribute on the converted aws_vpc and aws_subnet blocks is a blocker for the same reason, so there is no IPv6 traffic left for this gateway to carry.

Second, its IPv4 counterpart is not automatic either. A Frostmoln VPC has no outbound path at all until a 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 reach to that control plane either. Attach one to the converted VPC:

resource "frostmoln_gateway" "main" {
  vpc_id = frostmoln_vpc.main.id
  mode   = "public_ip"
}

The gateway's source address is drawn by the platform, and you do not choose which one you get, so it is not an address to publish. Where a partner allow-lists your source address, or DNS points at it, allocate the address yourself and name it — the gateway then egresses from that one:

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 writes no gateway: connectivity is a stated choice, so that a VPC cannot acquire an outbound path — or a billable public address — because a field was omitted.

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>

aws_iam_access_key ​

Both replacements ARE Terraform-managed, but neither is derived from a user resource. frostmoln_api_key issues a platform API key (its value is returned only on create). frostmoln_s3_credential issues an S3 access key id and secret, and can be narrowed with allowed_buckets, allowed_actions, and ip_whitelist. A configuration that fed this key into an application should read the replacement resource's attributes, or a frostmoln_secret.

aws_iam_instance_profile ​

A plain instance authenticates with an API key delivered like any other secret. A workload running in a Frostmoln-managed Kubernetes cluster uses frostmoln_workload_identity_binding instead, which binds a namespace and service account and is granted by an attached frostmoln_iam_policy (or, coarser and optional, a flat scopes list) - no static credential on the node.

aws_iam_openid_connect_provider ​

frostmoln_workload_identity_binding trades a projected Kubernetes ServiceAccount token from a Frostmoln-managed cluster for a short-lived platform token - it does not accept a third-party issuer, so a GitHub Actions (or other external CI) keyless-deploy trust relationship has no equivalent. Those callers need an API key held as a CI secret.

aws_iam_policy ​

Recreate the policy as a frostmoln_iam_policy whose document comes from the frostmoln_iam_policy_document data source, then attach it with frostmoln_iam_policy_attachment. The engine will not translate the statements: an AWS action/ARN/condition has no mechanical equivalent in Frostmoln operations, FRNs and constraints, and a wrong guess here is a permissions bug.

data.aws_iam_policy_document ​

This is a document renderer, not cloud infrastructure - nothing is provisioned by it. frostmoln_iam_policy_document is the direct counterpart: rule blocks with name, access, operations, targets (FRNs) and constraint blocks. The statements themselves do NOT carry over - AWS actions, ARNs and condition keys have no mechanical translation to Frostmoln operations, FRNs and constraints - so the document is rewritten by hand, not converted.

aws_iam_role ​

There is no trust policy and nothing to assume. Recreate what the role granted as a frostmoln_iam_policy (document from the frostmoln_iam_policy_document data source) and attach it with frostmoln_iam_policy_attachment to an api_key, workload_identity, or group. Workloads in a Frostmoln-managed Kubernetes cluster get their identity from frostmoln_workload_identity_binding - that is the closest counterpart to IRSA.

aws_iam_role_policy ​

Recreate the permissions as a frostmoln_iam_policy and attach it with frostmoln_iam_policy_attachment to an api_key, workload_identity, or group. The policy document must be rewritten in Frostmoln's own language (frostmoln_iam_policy_document).

aws_iam_role_policy_attachment ​

Frostmoln has the same shape one level down: attach the rewritten frostmoln_iam_policy to an api_key, workload_identity, or group with frostmoln_iam_policy_attachment. Whatever the role was assumed BY becomes the attachee.

data.aws_iam_roles ​

Organization roles exist, but they are member role assignments rather than an IAM-role listing, and there is no data source for them. Permissions live on frostmoln_iam_policy attached to an api_key, workload_identity, or group.

aws_iam_user ​

Invite people to the organization and assign them an organization role; for a machine caller create a frostmoln_api_key. Organization membership and role assignment are not Terraform-managed; the API key is. Permissions on top of that come from a frostmoln_iam_policy attached to the api_key or a group.

aws_iam_user_policy ​

Attach a rewritten frostmoln_iam_policy to the api_key or group that replaces the user (frostmoln_iam_policy_attachment).

aws_internet_gateway ​

An internet gateway is not a one-to-one concept, and it is emphatically not a resource the platform makes unnecessary. It carries BOTH directions; Frostmoln separates them, and neither follows from the VPC alone.

OUTBOUND is the VPC's gateway — one explicit resource per VPC. 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 reach to that control plane either. Attach one to the converted VPC:

resource "frostmoln_gateway" "main" {
  vpc_id = frostmoln_vpc.main.id
  mode   = "public_ip"
}

The gateway's source address is drawn by the platform, and you do not choose which one you get, so it is not an address to publish. Where a partner allow-lists your source address, or DNS points at it, allocate the address yourself and name it — the gateway then egresses from that one:

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 writes no gateway: connectivity is a stated choice, so that a VPC cannot acquire an outbound path — or a billable public address — because a field was omitted.

INBOUND is per workload, not per VPC. There is no switch that makes a VPC's private addresses routable from the internet: attach a frostmoln_public_ip to the instance that must be reachable, or put a public frostmoln_load_balancer in front of it. An aws_eip in this configuration already converts to a frostmoln_public_ip, so much of the inbound half may already be present.

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>

aws_internet_gateway_attachment ​

This resource binds an internet gateway to a VPC, so it disappears with the gateway itself — but the connectivity it stood for does not follow the VPC automatically, which is the part worth reading twice.

OUTBOUND is a separate, explicit resource. A Frostmoln VPC with no gateway 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 reach to that control plane either. Attach one to the converted VPC:

resource "frostmoln_gateway" "main" {
  vpc_id = frostmoln_vpc.main.id
  mode   = "public_ip"
}

The gateway's source address is drawn by the platform, and you do not choose which one you get, so it is not an address to publish. Where a partner allow-lists your source address, or DNS points at it, allocate the address yourself and name it — the gateway then egresses from that one:

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 writes no gateway: connectivity is a stated choice, so that a VPC cannot acquire an outbound path — or a billable public address — because a field was omitted.

INBOUND is per workload: attach a frostmoln_public_ip to the instance that must be reachable, or put a public frostmoln_load_balancer in front of it.

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>

aws_main_route_table_association ​

A Frostmoln VPC's single route set already is what a main route table is for: the fallback that applies to everything in the VPC. So the association has nothing to convert into, and the routes themselves still convert — see the aws_route entry.

Because there is only one set, ROUTES FROM EVERY TABLE IN THIS VPC MERGE into it, main and non-main alike. Look for the same destination appearing in more than one table with a different target — only one of them can survive, and the platform refuses the second as a duplicate.

It is worth being explicit about what none of this means: a Frostmoln VPC has no outbound path until a gateway is attached to it, and a VPC without one is an isolated network — no outbound internet, no name resolution and no managed-service control plane. (A managed database, cache or broker deployed INTO the VPC still answers on its private address; reaching it by name needs DNS.) See the aws_internet_gateway or aws_nat_gateway entry for what to add, and how to give it a source address you can publish.

aws_nat_gateway ​

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 reach to that control plane either. Attach one to the converted VPC:

resource "frostmoln_gateway" "main" {
  vpc_id = frostmoln_vpc.main.id
  mode   = "public_ip"
}

That gateway IS the NAT function this resource performed: every instance in the VPC egresses through it, translated to its source address. The address is drawn by the platform, and you do not choose which one you get — so it is not an address to publish. Where a remote peer allow-lists your source address, or DNS points at it, allocate the address yourself and name it, which is what the NAT gateway's Elastic IP gave you:

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: it appears in your Public IP list, it draws on the same public IPv4 quota your customer-facing Public IPs do, and it is 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. A VPC that genuinely needs no internet keeps none; leave the block out.

One shape does not carry over at all: a VPC has AT MOST ONE gateway, while this configuration may hold several NAT gateways for the same VPC (typically one per availability zone). A single frostmoln_gateway replaces all of them — that many-to-one collapse is left to you to make rather than performed quietly, because which gateway's behaviour survives is a decision, not a rename. A private NAT gateway (connectivity_type = "private") is not an internet path at all and has no equivalent: there is no transit-gateway concept for it to route to.

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>

aws_nat_gateway_eip_association ​

This resource pins a specific Elastic IP as (one of) a NAT gateway's outbound source addresses. Frostmoln expresses the single-address half of that, on the VPC's gateway itself: left to itself the gateway egresses from an address the platform draws, which you do not choose and should not publish, and naming a Public IP you own makes that one the source address instead. Naming it is the analogue of this association, 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.

Several addresses on one gateway — the reason this resource exists, usually port-exhaustion headroom — has no counterpart at all: a VPC has AT MOST ONE gateway and it carries one source address.

The gateway itself is not created for you; see aws_nat_gateway, 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>

aws_route_table ​

Static routes themselves DO convert — one frostmoln_vpc_route per route, on the VPC. What has no counterpart is the TABLE: a Frostmoln VPC has a single route set, and it cannot be associated with individual subnets. Two consequences are worth checking before you migrate:

  • ROUTES FROM DIFFERENT TABLES MERGE. If this VPC has several route tables associated with different subnets, every route in them lands in one set and applies to every instance in the VPC. Look for the same destination appearing in more than one table with a different target — only one of them can survive, and the platform refuses the second as a duplicate.
  • ROUTES WRITTEN INLINE IN THIS BLOCK ARE NOT CONVERTED. Only a standalone aws_route resource converts; a route { ... } block inside the table is removed with it. Rewrite each one as a frostmoln_vpc_route on the converted frostmoln_vpc.

Subnet-to-subnet routing within a Frostmoln VPC is automatic and cannot be overridden: a destination inside a subnet attached to the VPC is REFUSED. An east-west route sending one subnet's traffic to a firewall appliance has no counterpart and cannot be recreated — do not read it as redundant; enforce east-west policy with security groups.

A default route to an internet or NAT gateway does not survive either, and nothing replaces it implicitly: a Frostmoln VPC has no outbound path until a gateway is attached to it, and a VPC without one is an isolated network — no outbound internet, no name resolution and no managed-service control plane. (A managed database, cache or broker deployed INTO the VPC still answers on its private address; reaching it by name needs DNS.) See the aws_internet_gateway or aws_nat_gateway entry for what to add, and how to give it a source address you can publish.

aws_route_table_association ​

Frostmoln routes are held on the VPC and apply to all of it, so there is no per-subnet binding for this association to convert into. That is the thing to check before migrating: ROUTES FROM TABLES ASSOCIATED WITH DIFFERENT SUBNETS MERGE into a single set, and the distinction between them is lost. Look for the same destination appearing in more than one table with a different target — only one of them can survive, and the platform refuses the second as a duplicate.

The individual routes still convert; see the aws_route entry. What the association will not do is give the subnet internet access: a Frostmoln VPC has no outbound path until a gateway is attached to it, and a VPC without one is an isolated network — no outbound internet, no name resolution and no managed-service control plane. (A managed database, cache or broker deployed INTO the VPC still answers on its private address; reaching it by name needs DNS.) See the aws_internet_gateway or aws_nat_gateway entry for what to add, and how to give it a source address you can publish. Note also that "public subnet" is not a Frostmoln concept: inbound reachability is per workload (a frostmoln_public_ip on the instance, or a public frostmoln_load_balancer), never a property of a subnet.

aws_s3_bucket_acl ​

This blocks rather than being removed silently: private is already the platform default, but a public-read or cross-account ACL grants access the conversion cannot reproduce, and dropping it without a word would quietly change who can read the data. Customer S3 credentials are denied s3:PutBucketAcl and s3:PutBucketPolicy outright, and frostmoln_bucket exposes no ACL attribute - re-grant access with frostmoln_s3_credential scoped to the bucket.

aws_s3_bucket_lifecycle_configuration ​

Recreate the rules as a frostmoln_bucket_lifecycle_configuration naming the bucket: expiration, noncurrent-version expiration and aborting incomplete multipart uploads all carry over, scoped by prefix. Transition rules do NOT: a bucket carries a storage class (frostmoln_bucket.storage_class) but objects are not moved between classes on a schedule, and there is no per-object-tag filter. The resource replaces the bucket's lifecycle document whole, so declare every rule you want to keep - and re-scope by prefix any rule that relied on a tag or size filter, because a rule that expires objects and loses its filter deletes everything in the bucket.

aws_s3_bucket_ownership_controls ​

Object ownership settings exist on AWS to reconcile ACLs with cross-account writes. Frostmoln has neither: the tenant that owns the bucket owns its objects.

aws_s3_bucket_policy ​

For the platform API, attach a frostmoln_iam_policy covering the storage operations you need to an api_key, workload_identity, or group. For S3 data-plane access, issue a frostmoln_s3_credential narrowed with allowed_buckets and allowed_actions. A policy that granted PUBLIC access has no equivalent at all - customer credentials are denied s3:PutBucketPolicy outright.

aws_s3_bucket_public_access_block ​

Frostmoln buckets are private by default and no customer credential may change bucket-level access - s3:PutBucketAcl and s3:PutBucketPolicy are denied outright, and neither frostmoln_bucket nor the portal exposes a bucket ACL. There is nothing to block, so nothing replaces this resource. Access comes from S3 credentials issued to the tenant, which should be narrowed with allowed_buckets.

aws_s3_bucket_server_side_encryption_configuration ​

Frostmoln stores objects on encrypted disks, so data at rest is always encrypted - there is nothing to switch on. What has no equivalent is key selection: SSE-KMS with a customer-managed key, and bucket keys, cannot be expressed. This blocks rather than being removed silently, because a configuration that named a specific key did so for a key-custody reason that the platform default does not satisfy.

aws_secretsmanager_secret_version ​

Frostmoln stores the value on the frostmoln_secret (secret_value) and versions it internally — take secret_string from this resource and set it as secret_value on the converted secret. Binary secrets have no equivalent: encode them before storing. Staging labels (AWSCURRENT/AWSPREVIOUS) are platform-managed.

aws_wafv2_web_acl ​

This entry exists so the firewall is REPORTED rather than silently dropped. A web ACL is usually the only thing standing between the internet and an application, and a conversion that says nothing about it leaves the customer believing their protection came across.

What it maps onto:

  • the ACL itself is a frostmoln_appgw_waf_policy on a frostmoln_application_gateway, gateway-scoped for the whole gateway or overlay-scoped for one listener or one route;
  • AWS managed rule groups are the platform's own managed ruleset, which every gateway-scoped policy carries. It is tuned with paranoia_level and anomaly_score_threshold rather than selected group by group, and its version is read (managed_ruleset_version), not written;
  • each of your own rule statements is a frostmoln_appgw_waf_rule with kind = "builder" and a builder_json condition set;
  • a rule you switch off inside a managed group is a frostmoln_appgw_waf_rule with kind = "managedOverride", or — better where it is only a false positive on one field — a frostmoln_appgw_waf_exclusion, which narrows the rule instead of disabling it everywhere;
  • the ACL's association with a load balancer is a frostmoln_appgw_waf_policy_attachment.

What does not map: rate-based statements (per-source rate limiting is rate_limit_rps and rate_limit_burst on a frostmoln_appgw_listener, not a WAF rule), CAPTCHA and challenge actions, labels, and the CLOUDFRONT scope.

THE PART THAT IS EASY TO GET WRONG. A frostmoln_appgw_waf_policy and its rules are AUTHORED, not enforced. What the gateway inspects with is the last PUBLISHED version, so a policy written without a frostmoln_appgw_waf_policy_publication inspects nothing, while terraform apply succeeds and the plan looks complete. And a published version still only reaches the appliance on the gateway's next frostmoln_appgw_config_apply. Write all of them, or the firewall is a configuration that governs no traffic.


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.