AWS
The AWS plugin enables formae to manage AWS resources using the AWS Cloud Control API.
Configuration
Target
Configure an AWS target in your Forma file:
import "@formae/formae.pkl"
import "@aws/aws.pkl"
target: formae.Target = new formae.Target {
label = "aws-target"
config = new aws.Config {
region = "us-east-1"
// Optional: specify a named profile
// profile = "my-profile"
}
}
Credentials
The plugin uses the standard AWS credential chain. Configure credentials using one of the following methods:
Environment Variables:
export AWS_ACCESS_KEY_ID="your-access-key"
export AWS_SECRET_ACCESS_KEY="your-secret-key"
export AWS_REGION="us-east-1"
# For temporary credentials (e.g., from STS AssumeRole)
export AWS_SESSION_TOKEN="your-session-token"
Named Profile:
# Use a profile from ~/.aws/credentials
export AWS_PROFILE="my-profile"
You can also restrict credential usage to a named profile using the profile property:
config = new aws.Config {
region = "us-east-1"
profile = "my-profile"
}
# ~/.aws/credentials
[my-profile]
aws_access_key_id = YOUR_ACCESS_KEY_ID
aws_secret_access_key = YOUR_SECRET_ACCESS_KEY
IAM Instance Profile / ECS Task Role: When running on EC2 or ECS, credentials are automatically retrieved from the instance metadata service.
OIDC (for CI/CD):
For GitHub Actions, use aws-actions/configure-aws-credentials with OIDC federation.
Examples
Examples are bundled with formae at /opt/pel/formae/examples/formae-plugin-aws/.
Before running any example, resolve the Pkl dependencies:
pkl project resolve /opt/pel/formae/examples/formae-plugin-aws
Available examples:
| Example | Description |
|---|---|
| lifeline | Basic VPC infrastructure with subnets and security groups |
| lambda-env | Lambda functions with supporting infrastructure |
| ecs-hello-world | ECS cluster with services |
| eks-automode | EKS cluster with auto mode |
| static-website | S3 + CloudFront static website |
# Evaluate an example
formae eval /opt/pel/formae/examples/formae-plugin-aws/lifeline/basic_infrastructure.pkl
# Apply resources
formae apply --mode reconcile --watch /opt/pel/formae/examples/formae-plugin-aws/lifeline/basic_infrastructure.pkl
Supported Resources
| Type | Discoverable | Extractable | Comment |
|---|---|---|---|
| AWS::ApiGateway::ApiKey | ✅ | ✅ | |
| AWS::ApiGateway::Deployment | ✅ | ✅ | |
| AWS::ApiGateway::Method | ❌ | ✅ | |
| AWS::ApiGateway::Resource | ❌ | ✅ | |
| AWS::ApiGateway::RestApi | ✅ | ✅ | |
| AWS::ApiGateway::Stage | ✅ | ✅ | |
| AWS::ApiGateway::UsagePlan | ✅ | ✅ | |
| AWS::ApiGateway::UsagePlanKey | ✅ | ✅ | |
| AWS::CloudFront::Distribution | ❌ | ❌ | |
| AWS::DynamoDB::GlobalTable | ✅ | ✅ | |
| AWS::DynamoDB::Table | ✅ | ✅ | |
| AWS::EC2::CapacityReservation | ✅ | ✅ | |
| AWS::EC2::CapacityReservationFleet | ✅ | ✅ | |
| AWS::EC2::CarrierGateway | ✅ | ✅ | |
| AWS::EC2::ClientVpnAuthorizationRule | ❌ | ✅ | |
| AWS::EC2::ClientVpnEndpoint | ❌ | ✅ | |
| AWS::EC2::ClientVpnRoute | ❌ | ✅ | |
| AWS::EC2::ClientVpnTargetNetworkAssociation | ❌ | ✅ | |
| AWS::EC2::CustomerGateway | ✅ | ✅ | |
| AWS::EC2::DHCPOptions | ✅ | ✅ | |
| AWS::EC2::EC2Fleet | ✅ | ✅ | |
| AWS::EC2::EIP | ✅ | ✅ | |
| AWS::EC2::EIPAssociation | ✅ | ✅ | |
| AWS::EC2::EgressOnlyInternetGateway | ✅ | ✅ | |
| AWS::EC2::EnclaveCertificateIamRoleAssociation | ❌ | ✅ | |
| AWS::EC2::FlowLog | ✅ | ✅ | |
| AWS::EC2::GatewayRouteTableAssociation | ❌ | ✅ | |
| AWS::EC2::Host | ✅ | ✅ | |
| AWS::EC2::IPAM | ✅ | ✅ | |
| AWS::EC2::IPAMAllocation | ✅ | ✅ | |
| AWS::EC2::IPAMPool | ✅ | ✅ | |
| AWS::EC2::IPAMPoolCidr | ✅ | ✅ | |
| AWS::EC2::IPAMResourceDiscovery | ✅ | ✅ | |
| AWS::EC2::IPAMResourceDiscoveryAssociation | ✅ | ✅ | |
| AWS::EC2::IPAMScope | ✅ | ✅ | |
| AWS::EC2::Instance | ✅ | ✅ | |
| AWS::EC2::InstanceConnectEndpoint | ✅ | ✅ | |
| AWS::EC2::InternetGateway | ✅ | ✅ | |
| AWS::EC2::KeyPair | ✅ | ✅ | |
| AWS::EC2::LaunchTemplate | ✅ | ✅ | |
| AWS::EC2::LocalGatewayRoute | ✅ | ✅ | |
| AWS::EC2::LocalGatewayRouteTable | ✅ | ✅ | |
| AWS::EC2::LocalGatewayRouteTableVPCAssociation | ✅ | ✅ | |
| AWS::EC2::LocalGatewayRouteTableVirtualInterfaceGroupAssociation | ✅ | ✅ | |
| AWS::EC2::NatGateway | ✅ | ✅ | |
| AWS::EC2::NetworkAcl | ✅ | ✅ | |
| AWS::EC2::NetworkAclEntry | ❌ | ✅ | |
| AWS::EC2::NetworkInsightsAccessScope | ✅ | ✅ | |
| AWS::EC2::NetworkInsightsAccessScopeAnalysis | ✅ | ✅ | |
| AWS::EC2::NetworkInsightsAnalysis | ✅ | ✅ | |
| AWS::EC2::NetworkInsightsPath | ✅ | ✅ | |
| AWS::EC2::NetworkInterface | ✅ | ✅ | |
| AWS::EC2::NetworkInterfaceAttachment | ✅ | ✅ | |
| AWS::EC2::NetworkInterfacePermission | ❌ | ✅ | |
| AWS::EC2::NetworkPerformanceMetricSubscription | ✅ | ✅ | |
| AWS::EC2::PlacementGroup | ✅ | ✅ | |
| AWS::EC2::PrefixList | ❌ | ❌ | |
| AWS::EC2::Route | ❌ | ✅ | |
| AWS::EC2::RouteTable | ✅ | ✅ | |
| AWS::EC2::SecurityGroup | ✅ | ✅ | |
| AWS::EC2::SecurityGroupEgress | ✅ | ✅ | |
| AWS::EC2::SecurityGroupIngress | ✅ | ✅ | |
| AWS::EC2::SecurityGroupVpcAssociation | ✅ | ✅ | |
| AWS::EC2::SnapshotBlockPublicAccess | ✅ | ✅ | |
| AWS::EC2::SpotFleet | ✅ | ✅ | |
| AWS::EC2::Subnet | ✅ | ✅ | |
| AWS::EC2::SubnetCidrBlock | ✅ | ✅ | |
| AWS::EC2::SubnetNetworkAclAssociation | ✅ | ✅ | |
| AWS::EC2::SubnetRouteTableAssociation | ✅ | ✅ | |
| AWS::EC2::TrafficMirrorFilter | ✅ | ✅ | |
| AWS::EC2::TrafficMirrorFilterRule | ✅ | ✅ | |
| AWS::EC2::TrafficMirrorSession | ✅ | ✅ | |
| AWS::EC2::TrafficMirrorTarget | ✅ | ✅ | |
| AWS::EC2::TransitGateway | ✅ | ✅ | |
| AWS::EC2::TransitGatewayAttachment | ✅ | ✅ | |
| AWS::EC2::TransitGatewayConnect | ✅ | ✅ | |
| AWS::EC2::TransitGatewayMulticastDomain | ✅ | ✅ | |
| AWS::EC2::TransitGatewayMulticastDomainAssociation | ✅ | ✅ | |
| AWS::EC2::TransitGatewayMulticastGroupMember | ✅ | ✅ | |
| AWS::EC2::TransitGatewayMulticastGroupSource | ✅ | ✅ | |
| AWS::EC2::TransitGatewayPeeringAttachment | ✅ | ✅ | |
| AWS::EC2::TransitGatewayRoute | ✅ | ✅ | |
| AWS::EC2::TransitGatewayRouteTable | ✅ | ✅ | |
| AWS::EC2::TransitGatewayRouteTableAssociation | ✅ | ✅ | |
| AWS::EC2::TransitGatewayRouteTablePropagation | ✅ | ✅ | |
| AWS::EC2::TransitGatewayVpcAttachment | ✅ | ✅ | |
| AWS::EC2::VPC | ✅ | ✅ | |
| AWS::EC2::VPCBlockPublicAccessExclusion | ✅ | ✅ | |
| AWS::EC2::VPCBlockPublicAccessOptions | ❌ | ✅ | |
| AWS::EC2::VPCCidrBlock | ✅ | ✅ | |
| AWS::EC2::VPCDHCPOptionsAssociation | ✅ | ✅ | |
| AWS::EC2::VPCEndpoint | ✅ | ✅ | |
| AWS::EC2::VPCEndpointConnectionNotification | ✅ | ✅ | |
| AWS::EC2::VPCEndpointService | ✅ | ✅ | |
| AWS::EC2::VPCEndpointServicePermissions | ✅ | ✅ | |
| AWS::EC2::VPCGatewayAttachment | ✅ | ✅ | |
| AWS::EC2::VPCPeeringConnection | ✅ | ✅ | |
| AWS::EC2::VPNConnection | ✅ | ✅ | |
| AWS::EC2::VPNConnectionRoute | ✅ | ✅ | |
| AWS::EC2::VPNGateway | ✅ | ✅ | |
| AWS::EC2::VPNGatewayRoutePropagation | ❌ | ✅ | |
| AWS::EC2::VerifiedAccessEndpoint | ✅ | ✅ | |
| AWS::EC2::VerifiedAccessGroup | ✅ | ✅ | |
| AWS::EC2::VerifiedAccessInstance | ✅ | ✅ | |
| AWS::EC2::VerifiedAccessTrustProvider | ✅ | ✅ | |
| AWS::EC2::Volume | ✅ | ✅ | |
| AWS::EC2::VolumeAttachment | ✅ | ✅ | |
| AWS::ECR::PullThroughCacheRule | ✅ | ✅ | |
| AWS::ECR::RegistryPolicy | ✅ | ✅ | |
| AWS::ECR::ReplicationConfiguration | ✅ | ✅ | |
| AWS::ECR::Repository | ✅ | ✅ | |
| AWS::ECR::RepositoryCreationTemplate | ✅ | ✅ | |
| AWS::ECS::CapacityProvider | ❌ | ✅ | |
| AWS::ECS::Cluster | ✅ | ✅ | |
| AWS::ECS::ClusterCapacityProviderAssociations | ✅ | ✅ | |
| AWS::ECS::PrimaryTaskSet | ❌ | ✅ | |
| AWS::ECS::Service | ✅ | ✅ | |
| AWS::ECS::TaskDefinition | ✅ | ✅ | |
| AWS::ECS::TaskSet | ✅ | ✅ | |
| AWS::EFS::AccessPoint | ✅ | ✅ | |
| AWS::EFS::FileSystem | ✅ | ✅ | |
| AWS::EFS::MountTarget | ✅ | ✅ | |
| AWS::EKS::Cluster | ✅ | ✅ | |
| AWS::EKS::Nodegroup | ✅ | ✅ | |
| AWS::ElasticBeanstalk::Application | ✅ | ✅ | |
| AWS::ElasticBeanstalk::ApplicationVersion | ✅ | ✅ | |
| AWS::ElasticBeanstalk::ConfigurationTemplate | ✅ | ✅ | |
| AWS::ElasticBeanstalk::Environment | ✅ | ✅ | |
| AWS::ElasticLoadBalancingV2::Listener | ✅ | ✅ | |
| AWS::ElasticLoadBalancingV2::ListenerCertificate | ❌ | ✅ | |
| AWS::ElasticLoadBalancingV2::ListenerRule | ❌ | ✅ | |
| AWS::ElasticLoadBalancingV2::LoadBalancer | ✅ | ✅ | |
| AWS::ElasticLoadBalancingV2::TargetGroup | ✅ | ✅ | |
| AWS::ElasticLoadBalancingV2::TrustStore | ✅ | ✅ | |
| AWS::ElasticLoadBalancingV2::TrustStoreRevocation | ✅ | ✅ | |
| AWS::IAM::AccessKey | ❌ | ✅ | |
| AWS::IAM::Group | ✅ | ✅ | |
| AWS::IAM::GroupPolicy | ❌ | ✅ | |
| AWS::IAM::InstanceProfile | ✅ | ✅ | |
| AWS::IAM::ManagedPolicy | ❌ | ✅ | |
| AWS::IAM::OIDCProvider | ✅ | ✅ | |
| AWS::IAM::Policy | ❌ | ✅ | |
| AWS::IAM::Role | ✅ | ✅ | |
| AWS::IAM::RolePolicy | ✅ | ✅ | |
| AWS::IAM::SAMLProvider | ✅ | ✅ | |
| AWS::IAM::ServerCertificate | ✅ | ✅ | |
| AWS::IAM::ServiceLinkedRole | ❌ | ✅ | |
| AWS::IAM::User | ❌ | ❌ | |
| AWS::IAM::UserPolicy | ❌ | ✅ | |
| AWS::IAM::UserToGroupAddition | ❌ | ✅ | |
| AWS::IAM::VirtualMFADevice | ❌ | ❌ | |
| AWS::KMS::Alias | ❌ | ✅ | |
| AWS::KMS::Key | ❌ | ❌ | |
| AWS::Lambda::Alias | ✅ | ✅ | |
| AWS::Lambda::CodeSigningConfig | ✅ | ✅ | |
| AWS::Lambda::EventInvokeConfig | ✅ | ✅ | |
| AWS::Lambda::EventSourceMapping | ✅ | ✅ | |
| AWS::Lambda::Function | ✅ | ✅ | |
| AWS::Lambda::LayerVersion | ❌ | ✅ | |
| AWS::Lambda::LayerVersionPermission | ❌ | ✅ | |
| AWS::Lambda::Permission | ❌ | ✅ | |
| AWS::Lambda::Url | ✅ | ✅ | |
| AWS::Lambda::Version | ✅ | ✅ | |
| AWS::Logs::LogGroup | ✅ | ✅ | |
| AWS::RDS::CustomDBEngineVersion | ✅ | ✅ | |
| AWS::RDS::DBCluster | ✅ | ✅ | |
| AWS::RDS::DBClusterParameterGroup | ✅ | ✅ | |
| AWS::RDS::DBInstance | ✅ | ✅ | |
| AWS::RDS::DBParameterGroup | ✅ | ✅ | |
| AWS::RDS::DBProxy | ✅ | ✅ | |
| AWS::RDS::DBProxyEndpoint | ✅ | ✅ | |
| AWS::RDS::DBProxyTargetGroup | ✅ | ✅ | |
| AWS::RDS::DBSecurityGroup | ❌ | ✅ | |
| AWS::RDS::DBSecurityGroupIngress | ❌ | ✅ | |
| AWS::RDS::DBShardGroup | ✅ | ✅ | |
| AWS::RDS::DBSubnetGroup | ✅ | ✅ | |
| AWS::RDS::EventSubscription | ✅ | ✅ | |
| AWS::RDS::GlobalCluster | ✅ | ✅ | |
| AWS::RDS::Integration | ✅ | ✅ | |
| AWS::RDS::OptionGroup | ✅ | ✅ | |
| AWS::Route53::CidrCollection | ✅ | ✅ | |
| AWS::Route53::DNSSEC | ✅ | ✅ | |
| AWS::Route53::HealthCheck | ✅ | ✅ | |
| AWS::Route53::HostedZone | ✅ | ✅ | |
| AWS::Route53::KeySigningKey | ✅ | ✅ | |
| AWS::Route53::RecordSet | ✅ | ✅ | |
| AWS::Route53::RecordSetGroup | ❌ | ✅ | |
| AWS::S3::AccessGrant | ❌ | ✅ | |
| AWS::S3::AccessGrantsInstance | ❌ | ✅ | |
| AWS::S3::AccessGrantsLocation | ❌ | ✅ | |
| AWS::S3::AccessPoint | ✅ | ✅ | |
| AWS::S3::Bucket | ✅ | ✅ | |
| AWS::S3::BucketPolicy | ✅ | ✅ | |
| AWS::S3::MultiRegionAccessPoint | ✅ | ✅ | |
| AWS::S3::MultiRegionAccessPointPolicy | ❌ | ✅ | |
| AWS::S3::StorageLens | ✅ | ✅ | |
| AWS::S3::StorageLensGroup | ✅ | ✅ | |
| AWS::SQS::Queue | ✅ | ✅ | |
| AWS::SQS::QueueInlinePolicy | ❌ | ✅ | |
| AWS::SQS::QueuePolicy | ❌ | ✅ | |
| AWS::SageMaker::Domain | ✅ | ✅ | This resource creates an EFS system - AutoHomeEFS - which will need to be manually removed prior to successfully destroying the domain. |
| AWS::SageMaker::Endpoint | ❌ | ✅ | |
| AWS::SageMaker::ModelPackageGroup | ❌ | ✅ | |
| AWS::SageMaker::UserProfile | ✅ | ✅ | |
| AWS::SecretsManager::ResourcePolicy | ✅ | ✅ | |
| AWS::SecretsManager::RotationSchedule | ✅ | ✅ | |
| AWS::SecretsManager::Secret | ✅ | ✅ | |
| AWS::SecretsManager::SecretTargetAttachment | ❌ | ✅ |