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.

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 Frostmoln
ownersNot needed on Frostmoln
executable_usersNot needed on Frostmoln
filterNot needed on Frostmoln
name_regexNot carried over
include_deprecatedNot carried over
  • 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 required
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 required
mixed_instances_policyManual action required
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_policy
tag (also matches tags)Manual action required
availability_zonesNot carried over
load_balancersManual action required
capacity_rebalanceNot carried over
instance_refreshNot carried over
warm_poolNot carried over
suspended_processesNot carried over
enabled_metricsNot carried over
metrics_granularityNot carried over
placement_groupManual action required
service_linked_role_arnNot needed on Frostmoln
max_instance_lifetimeNot carried over
instance_maintenance_policyNot carried over
protect_from_scale_inNot carried over
desired_capacity_typeNot carried over
wait_for_capacity_timeoutNot needed on Frostmoln
wait_for_elb_capacityNot needed on Frostmoln
min_elb_capacityNot needed on Frostmoln
force_deleteNot needed on Frostmoln
force_delete_warm_poolNot needed on Frostmoln
ignore_failed_scaling_activitiesNot needed on Frostmoln
  • 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
storage_tierNot carried over
permanent_restoreNot carried over
temporary_restore_daysNot carried over
outpost_arnManual action required
  • 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 over
throughputNot carried over
kms_key_idManual action required
multi_attach_enabledManual action required
final_snapshotNot carried over
outpost_arnManual action required
tagsConverted
  • 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 Frostmoln
tagsConverted
addressManual action required
public_ipv4_poolManual action required
customer_owned_ipv4_poolManual action required
associate_with_private_ipManual action required
network_border_groupNot carried over
network_interfaceManual action required

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 Frostmoln
network_interface_idManual action required
private_ip_addressManual action required
public_ipManual action required

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 required
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 Frostmoln
associate_public_ip_addressConvertedA true value becomes a generated frostmoln_public_ip bound to the instance.
tagsConverted
volume_tagsNot carried over
private_ipNot carried over
secondary_private_ipsManual action required
iam_instance_profileManual action required
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 required
network_interfaceManual action required
ipv6_address_countManual action required
ipv6_addressesManual action required
monitoringNot needed on Frostmoln
ebs_optimizedNot needed on Frostmoln
metadata_optionsNot needed on Frostmoln
credit_specificationNot needed on Frostmoln
source_dest_checkNot carried over
tenancyNot carried over
host_idManual action required
host_resource_group_arnManual action required
placement_groupManual action required
placement_partition_numberManual action required
cpu_options (also matches cpu_core_count, cpu_threads_per_core)Not carried over
hibernationNot carried over
disable_api_terminationNot carried over
disable_api_stopNot carried over
instance_initiated_shutdown_behaviorNot carried over
instance_market_optionsManual action required
capacity_reservation_specificationNot carried over
get_password_dataNot carried over
launch_templateManual action required
maintenance_optionsNot carried over
private_dns_name_optionsNot carried over
enclave_optionsManual action required
  • 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 required
public_keyMapped to public_key
tagsNot carried over

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 required
descriptionNot carried over
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 required
user_dataConvertedAWS launch-template user data is base64; frostmoln_launch_template takes plain text.
tagsConverted
tag_specificationsManual action required
default_versionNot needed on Frostmoln
update_default_versionNot needed on Frostmoln
block_device_mappingsManual action requiredA volume split arrives in a later release.
network_interfacesManual action required
iam_instance_profileManual action required
instance_market_optionsManual action required
instance_requirementsManual action required
placementManual action required
monitoringNot needed on Frostmoln
ebs_optimizedNot needed on Frostmoln
metadata_optionsNot needed on Frostmoln
credit_specificationNot needed on Frostmoln
cpu_optionsNot carried over
kernel_idNot carried over
ram_disk_idNot carried over
disable_api_stopNot carried over
disable_api_terminationNot carried over
instance_initiated_shutdown_behaviorNot carried over
hibernation_optionsNot carried over
elastic_gpu_specifications (retired by the provider)Manual action required
elastic_inference_accelerator (retired by the provider)Manual action required
enclave_optionsManual action required
license_specificationNot carried over
maintenance_optionsNot carried over
private_dns_name_optionsNot carried over
capacity_reservation_specificationNot carried over
  • 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 provider_type amphora/ovn.

AttributeOutcomeNotes
nameMapped to name
name_prefixManual action required
internalConverted to schemeA public scheme requires a public_ip_id — create a frostmoln_public_ip for the load balancer.
load_balancer_typeConverted to provider_type
subnetsConverted to subnet_id
subnet_mappingManual action required
security_groupsNot carried over
tagsConverted
enable_deletion_protectionNot carried over
access_logsManual action required
connection_logsManual action required
idle_timeoutNot carried over
enable_http2Not carried over
enable_cross_zone_load_balancingNot needed on Frostmoln
ip_address_typeNot carried over
drop_invalid_header_fieldsNot carried over
preserve_host_headerNot carried over
xff_header_processing_modeNot carried over
desync_mitigation_modeNot carried over
enable_waf_fail_openNot carried over
dns_record_client_routing_policyNot carried over
enable_tls_version_and_cipher_suite_headersNot carried over
enable_zonal_shiftNot carried over
client_keep_aliveNot carried over
customer_owned_ipv4_poolManual action required
enforce_security_group_inbound_rules_on_private_link_trafficNot carried over
  • 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 over
certificate_arnManual action required
alpn_policyNot carried over
mutual_authenticationManual action required
tcp_idle_timeout_secondsNot carried over
tagsNot carried over
  • 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 load balancers of network type (provider_type ovn) only support source_ip_port, so change lb_algorithm when attaching this pool to an ovn load balancer. Member ports are set per frostmoln_lb_member, so the port attribute is dropped.

AttributeOutcomeNotes
nameMapped to name
name_prefixManual action required
protocolConverted
portNot carried over
vpc_idNot needed on Frostmoln
target_typeNot needed on Frostmoln
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 over
load_balancing_cross_zone_enabledNot needed on Frostmoln
proxy_protocol_v2Converted to proxy_protocol
deregistration_delayNot carried over
slow_startNot carried over
preserve_client_ipNot carried over
connection_terminationNot carried over
lambda_multi_value_headers_enabledManual action required
ip_address_typeNot carried over
target_failoverNot carried over
target_health_stateNot carried over
target_group_healthNot carried over
tagsNot carried over

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 over
matcherMapped to expected_codes
portNot carried over
enabledNot carried over
  • 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 over
  • The converter adds load_balancer_id automatically. frostmoln_lb_member requires load_balancer_id; set it to the converted load balancer.

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 required
weighted_routing_policyManual action required
latency_routing_policyManual action required
failover_routing_policyManual action required
geolocation_routing_policyManual action required
geoproximity_routing_policyManual action required
cidr_routing_policyManual action required
multivalue_answer_routing_policyManual action required
set_identifierManual action required
health_check_idManual action required
allow_overwriteNot needed on Frostmoln
  • 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
vpcManual action required
force_destroyNot needed on Frostmoln
delegation_set_idNot carried over
  • 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); ACLs, policies, website hosting, CORS, 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 do exist on the platform (expiration and noncurrent-version cleanup, not transitions), but frostmoln_bucket exposes no lifecycle attribute, so they are set outside Terraform.

AttributeOutcomeNotes
bucketMapped to name
bucket_prefixManual action required
regionConvertedFrostmoln is single-region today; the platform default region applies.
tagsConverted
force_destroyNot needed on Frostmoln
aclManual action required
grantManual action required
policyManual action required
websiteManual action required
cors_ruleManual action required
lifecycle_ruleManual action required
versioningManual action required
loggingNot carried over
replication_configurationManual action required
server_side_encryption_configurationManual action required
object_lock_configurationManual action required
object_lock_enabledManual action required
acceleration_statusNot needed on Frostmoln
request_payerNot needed on Frostmoln

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 Frostmoln
mfaNot carried over

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
name_prefixManual action required
kms_key_idNot needed on Frostmoln
policyManual action required
replicaNot needed on Frostmoln
force_overwrite_replica_secretNot needed on Frostmoln
  • 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 (Neutron adds one IPv4 and one IPv6 allow-any egress rule to every new group, and Frostmoln removes neither), and converted egress rules ADD to those defaults rather than replacing them. 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 Neutron 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 and the instance metadata service; 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 required
descriptionMapped to description
vpc_idMapped to vpc_id
tagsConverted
revoke_rules_on_deleteNot needed on Frostmoln

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 required
prefix_list_idsManual action required
  • 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_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 required
prefix_list_idsManual action required

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 required
availability_zoneManual action required
availability_zone_idManual action required
default_for_azManual action required
stateManual action required
tagsManual action required
filterManual action required

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 over
map_public_ip_on_launchNot needed on Frostmoln
tagsConverted
assign_ipv6_address_on_creationManual action required
ipv6_cidr_blockManual action required
ipv6_nativeManual action required
enable_dns64Manual action required
enable_resource_name_dns_a_record_on_launchNot carried over
enable_resource_name_dns_aaaa_record_on_launchNot carried over
private_dns_hostname_type_on_launchNot carried over
customer_owned_ipv4_poolManual action required
map_customer_owned_ip_on_launchManual action required
outpost_arnManual action required
  • 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 over
skip_destroyNot carried over
stop_instance_before_detachingNot carried over

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 required
dhcp_options_idManual action required
defaultManual action required
stateManual action required
tagsManual action required
filterManual action required

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 connectivity, because those are reached over routes that exist only while the egress path does. 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
enable_dns_supportNot needed on Frostmoln
enable_dns_hostnamesNot needed on Frostmoln
instance_tenancyNot carried over
enable_network_address_usage_metricsNot carried over
ipv4_ipam_pool_idManual action required
ipv4_netmask_lengthManual action required
ipv6_cidr_blockManual action required
ipv6_ipam_pool_idManual action required
ipv6_netmask_lengthManual action required
ipv6_cidr_block_network_border_groupManual action required
assign_generated_ipv6_cidr_blockManual action required
  • The converter adds name automatically. frostmoln_vpc requires a name; it is taken from the Name tag or the resource address.

Resources without an equivalent

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_associationRouting inside a VPC is platform-managed and main route table associations are removed; there is no main route table, and no VPC-wide default route to the internet — outbound 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_routeRouting inside a VPC is platform-managed and individual routes are removed; a default route to the internet is not one of them — outbound comes from the VPC's gateway, a separate resource you must add.
aws_route_tableRouting inside a VPC is platform-managed per subnet and route tables are removed; the internet default route one usually carries is not replaced — outbound comes from the VPC's gateway, a separate resource you must add.
aws_route_table_associationRouting inside a VPC is platform-managed and route table associations are removed; associating a subnet with a table that carried an internet default route does not carry that route over — outbound comes from the VPC's gateway.
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_configurationObject lifecycle rules have no Terraform surface; the platform supports expiration and noncurrent-version cleanup, but storage-class transitions do not.
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.

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 managed-service connectivity 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 managed-service connectivity 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 managed-service connectivity 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

Frostmoln has no main route table for a VPC to point at, so this association has nothing to convert to. It is worth being explicit about what that does NOT mean: 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 connectivity. 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 managed-service connectivity 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

Subnet-to-subnet routing within a Frostmoln VPC is automatic, so a route describing it has nothing to convert to.

A default route pointing at an internet or NAT gateway is a different matter: nothing the platform does replaces it. 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, and, because the platform DNS resolver and the managed-service control plane are reached over routes that exist only while that path does, no name resolution and no managed-service connectivity either. See the 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

Subnet-to-subnet routing within a Frostmoln VPC is automatic, so the table itself has nothing to convert to. Its 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 connectivity. 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 subnets route within the VPC without a table to be associated with, so the association has nothing to convert to. What it 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 connectivity. 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

Frostmoln object storage does have lifecycle rules - expiration, noncurrent-version expiration, and aborting incomplete multipart uploads - but frostmoln_bucket exposes no lifecycle attribute, so they are set outside Terraform against the bucket's lifecycle endpoint. Transition rules have no equivalent: a bucket carries a storage class (frostmoln_bucket.storage_class) but objects are not moved between classes on a schedule.

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.


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.