Skip to Content
ConfigurationInfrastructureAWS (ECS & Fargate)Getting Started

AWS (ECS & Fargate)

Nanokit leverages AWS ECS (Elastic Container Service) with AWS Fargate to provide a serverless, highly scalable orchestration layer. This guide explains how the provider works and how to handle advanced networking.


Prerequisites

Before running your first deploy (nk up), ensure the following:

  1. AWS Credentials: Your AWS keys are configured via nk auth.
  2. IAM Permissions: Your user has the necessary permissions to manage ECS, EC2, and IAM roles (see the IAM Permissions section below).
  3. VPC Quotas: Nanokit automatically creates a dedicated VPC for your project. Ensure your AWS account limits allow for the creation of additional VPCs and Internet Gateways.

[!NOTE] Nanokit automatically manages the creation of ECS Clusters and Task Execution Roles per project and environment. You do not need to create these manually.


Architectural Concepts

When you deploy to AWS using Nanokit, the system distinguishes between two layers:

  1. ECS (The Orchestrator): The “brain” that manages your container lifecycle, service discovery, and health checks.
  2. Fargate (The Compute Engine): The “muscle” that provides the serverless CPU and RAM. You don’t manage individual EC2 instances; AWS handles the underlying hardware.

IAM Permissions

To allow Nanokit to orchestrate your AWS environment, your IAM user/role requires the following policies:

  • AmazonECS_FullAccess: To manage clusters, tasks, and services.
  • AmazonEC2FullAccess: To create VPCs, Subnets, and Security Groups.
  • AmazonEC2ContainerRegistryFullAccess: To build and push container images (ECR).
  • CloudWatchLogsFullAccess: To aggregate container logs.
  • AmazonElasticFileSystemFullAccess: To manage persistent volumes (EFS).
  • AmazonRoute53FullAccess (Optional): Required if using dns: aws.

Granular IAM Permissions

Nanokit automatically manages the Task Execution Role (nk-ecs-execution-role) required for Fargate logging. If you are using a restricted IAM user, ensure they have the following granular permissions:

  • iam:GetRole: To verify the role exists.
  • iam:CreateRole: To provision the role.
  • iam:PutRolePolicy: To manage the internal logging policy (nk-logging-policy).
  • iam:AttachRolePolicy: To link the AmazonECSTaskExecutionRolePolicy.
  • iam:PassRole: To allow the ECS service to assume the execution role.
  • iam:CreateServiceLinkedRole: To allow Nanokit to provision the mandatory AWSServiceRoleForECS if it doesn’t exist.

Inline Policy Example

You can add this JSON as an inline policy to your IAM user to grant the necessary granular permissions (replace <ACCOUNT_ID> with your AWS account number):

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "iam:GetRole", "iam:CreateRole", "iam:PutRolePolicy", "iam:AttachRolePolicy", "iam:PassRole" ], "Resource": "arn:aws:iam::<ACCOUNT_ID>:role/nk-ecs-execution-role" }, { "Effect": "Allow", "Action": [ "iam:CreateServiceLinkedRole" ], "Resource": "arn:aws:iam::*:role/aws-service-role/ecs.amazonaws.com/AWSServiceRoleForECS*", "Condition": { "StringLike": { "iam:AWSServiceName": "ecs.amazonaws.com" } } }, { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:DescribeLogGroups", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:*:<ACCOUNT_ID>:log-group:/nk/*" } ] }

[!TIP] If you cannot grant IAM management permissions to your user, you can manually create the role and provide its ARN in nanokit.yml under infra.executionRoleArn.


Networking & DNS

AWS Fargate tasks launched in public subnets receive ephemeral Public IP addresses. These IPs change whenever a service is restarted or updated.

The easiest way to map a domain to an ephemeral IP is to let Nanokit handle the update automatically. In your nanokit.yml:

infra: provider: aws dns: cloudflare # Or 'aws' for Route53 autoCreateDomain: true services: web: host: myapp.com

How it works: At the end of each deploy, Nanokit identifies the new IP of your task and performs an UPSERT on your DNS records (Cloudflare A record or Route53 Resource Record Set).

2. Static IP Strategy (NAT Gateway)

If you require a stable, static outbound IP (e.g., for IP whitelisting in a third-party API):

  1. Nanokit must be configured to use Private Subnets.
  2. You must provision a NAT Gateway with an Elastic IP in a Public Subnet.
  3. All outbound traffic from Fargate will then originate from that Static Elastic IP.

[!CAUTION] NAT Gateways incur a significant hourly cost on AWS (~$33/month + data processing).

3. Load Balancing & CNAME

Nanokit’s standard stage configuration points DNS directly to the Task IP for simplicity. For production-grade high availability:

  • Manual ALB: You can provision an AWS Application Load Balancer (ALB).
  • CNAME Mapping: In your DNS provider (GoDaddy, Namecheap, etc.), create a CNAME record pointing to the DNS name provided by the ALB.
  • Gateway Service: If you use a Nanokit gateway service, ensure it is the target of your CNAME.

External Domains (Other Providers)

If your domain is on a provider not supported by Nanokit’s DNS Sync:

  1. A Record: Point your domain to the Public IP found in .nanokit/services-state.json or the Nanokit Dashboard.
    • Note: You must manually update this if the IP changes.
  2. Name Server Transfer: The best approach is to point your domain’s Name Servers (NS) to Cloudflare or Route53 and then use Dynamic DNS Sync (Option 1).

Troubleshooting

Check Infrastructure Status

nk infra status

View Live Logs

nk logs web --follow

Nanokit automatically streams logs from CloudWatch Logs to your terminal.


Persistent Storage (AWS EFS)

AWS Fargate tasks use ephemeral storage by default. For stateful services (like MongoDB or Postgres), Nanokit automatically provisions and manages Amazon EFS (Elastic File System).

Read the full EFS Persistence Guide to learn how to configure volumes and handle permissions.