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

Nanokit requires a set of AWS IAM permissions to orchestrate infrastructure (EC2, VPC, EFS, Route53) and services (ECS, Fargate, ECR, CloudWatch). You can set these up using either Automated CLI Provisioning or Manual IAM Configuration.


When you run nkapp provider auth aws, the CLI automatically attempts to configure all required IAM groups, memberships, and policies on your behalf.

[!IMPORTANT] Prerequisites for Automation: To allow the CLI to automate this setup, the AWS Access Keys used for authentication must belong to a user who already possesses IAM administration permissions (such as the AWS-managed policy IAMFullAccess or AdministratorAccess). If your key belongs to a restricted user, please refer to the Manual Configuration steps below.

What the CLI Automates

  1. Creates the IAM Group: Checks for the existence of admin-group and creates it if missing.
  2. Attaches Group Policies: Links the following 5 policies to admin-group:
    • AmazonEC2FullAccess
    • AmazonECS_FullAccess
    • AmazonRoute53FullAccess
    • AmazonEC2ContainerServiceRole
    • AmazonECSTaskExecutionRolePolicy
  3. Assigns User Membership: Adds your authenticated IAM user to the admin-group.
  4. Attaches Direct Policies: Links the following 3 policies directly to your IAM user:
    • AmazonEC2ContainerRegistryFullAccess
    • AmazonElasticFileSystemFullAccess
    • CloudWatchLogsFullAccess
  5. Provisions Inline Permissions: Creates and attaches a custom inline policy (nk-ecs-execution-role-policy) to your user, scoped dynamically to your resolved AWS Account ID.

2. Manual IAM Configuration

If you are using restricted Access Keys for a user without IAM administration privileges (meaning the automated CLI commands throw warning messages), you must perform the following manual setup in the AWS Console once.

Step 1: Create the User Group and Attach Policies

  1. Open the IAM Console.
  2. Navigate to User Groups and click Create Group. Name the group: admin-group.
  3. In the Attach permissions policies search bar, search for and attach the following policies:
    • AmazonEC2FullAccess
    • AmazonECS_FullAccess
    • AmazonRoute53FullAccess
    • AmazonEC2ContainerServiceRole
    • AmazonECSTaskExecutionRolePolicy
  4. Click Create Group.

Step 2: Add Your User to the Group

  1. Inside the group details for admin-group, go to the Users tab and click Add Users.
  2. Select your admin user and click Add Users.

Step 3: Attach Direct Policies to the User

  1. Navigate to Users and select your admin user.
  2. Under the Permissions tab, click Add permissions -> Attach policies directly.
  3. Search for and attach the following policies:
    • AmazonEC2ContainerRegistryFullAccess
    • AmazonElasticFileSystemFullAccess
    • CloudWatchLogsFullAccess
  4. Click Next and then Add permissions.

Step 4: Add Custom Inline Permissions Policy

  1. Select your admin user profile.
  2. In the Permissions tab, click Add permissions -> Create inline policy.
  3. In the JSON editor tab, paste the following policy document (be sure to replace <ACCOUNT_ID> with your numerical AWS Account ID):
{ "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.