Skip to content

AWS Resources & Runtime Access ​

Applications use short-lived ECS task-role credentials. Declare resources once, then bind each resource only to the services that need it.

yaml
resources:
  uploads:
    type: s3
    create:
      versioning: true
    retain: true

  events:
    type: sns
    existing:
      arn: arn:aws:sns:us-east-1:123456789012:application-events

  reporting:
    type: rds
    existing:
      identifier: reporting-prod
      endpoint: reporting.internal
      port: 5432
      security_group_id: sg-0123456789
      secret_arn: arn:aws:secretsmanager:us-east-1:123456789012:secret:reporting
      kms_key_arn: arn:aws:kms:us-east-1:123456789012:key/00000000-0000-0000-0000-000000000000

services:
  web:
    type: web
    port: 8080
    health_check: /health
    bindings:
      - resource: uploads
        access: [list, read, write]
        prefix: user-content
      - resource: events
        access: [publish]
      - resource: reporting
        access: [connect]

Keel creates a separate IAM task role and security group for each service. S3, SNS, and SQS bindings become resource-scoped IAM statements. RDS and cache bindings add ingress rules to the linked security group. Keel injects resource identifiers through variables such as UPLOADS_BUCKET_NAME and EVENTS_TOPIC_ARN, and linked secrets through ECS secret injection.

Supported capabilities ​

TypeOwnershipCapabilities
S3managed or existinglist, read, write, delete
SNSmanaged or existingpublish
SQSmanaged or existingsend, consume
RDS / cacheexistingconnect
IAM roleexistingassume

An IAM-role binding grants the service sts:AssumeRole. The target role's trust policy must also trust the generated <app>-<service>-ecs-task role, including for cross-account access.

For an AWS service without a curated resource type, use an advanced custom IAM statement on the service and keep actions/resources narrowly scoped:

yaml
services:
  worker:
    permissions:
      - actions: [ses:SendEmail]
        resources: [arn:aws:ses:us-east-1:123456789012:identity/example.com]

Set kms_key_arn for an existing resource or secret encrypted with a customer-managed KMS key. Keel adds the necessary data-key and decrypt actions. For cross-account access, the resource, role, or KMS key policy in the owning account must also authorize the generated service task role.

Private subnets automatically receive a free S3 gateway endpoint when an S3 resource is configured. Set vpc.private_aws_endpoints: true to provision interface endpoints for configured SNS, SQS, and STS access.

What retain means ​

retain defaults to true and controls what happens to managed data resources during keel destroy:

  • S3, SNS, and SQS: keel destroy removes the resource from Keel state but leaves it in AWS, where it continues to incur charges. Keel prints the AWS CLI command to delete each retained resource. During normal applies, retain also sets lifecycle { prevent_destroy = true }.

  • Database: Keel cannot retain the live RDS instance while removing its VPC and security group. Instead, database.retain enables deletion protection and creates a final snapshot. Teardown prints the command to restore it.

keel destroy names everything it will delete and everything it will keep, then asks you to type the app name. Two flags change what survives:

  • --delete-retained destroys retain: true resources along with the stack.
  • --no-final-snapshot deletes the database without a snapshot.

Deployment history also survives by default. Remove it with --prune-history during teardown or keel history prune later. See Interruptions & Rescue for other account-wide state.

After redeploying an app whose resources were retained

The new keel up will collide with the surviving names — delete them, rename the resource in keel.yml, or import them first.

Resource commands ​

bash
# Create and bind a managed resource
keel resources add s3 uploads --versioning --bind web:list,read,write

# Link an existing resource without transferring ownership to Keel
keel resources link arn:aws:sns:us-east-1:123456789012:application-events \
  --as events --bind web:publish

# Change access later
keel resources bind uploads worker --access read
keel resources unbind uploads worker

# Inspect the complete app inventory and effective rules
keel resources
keel resources show uploads
keel resources show @load-balancer
keel resources --service web
keel resources --json

# Inspect access from a service's point of view
keel access show web
keel access explain web uploads

Built-in resources use @ names in the inventory, including @vpc, @cluster, @registry, @load-balancer, @logs, and optional add-ons such as @database, @cache, @domain, and @waf.

Keel — the missing platform layer for AWS.