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:
- AWS Credentials: Your AWS keys are configured via
nk auth. - IAM Permissions: Your user has the necessary permissions to manage ECS, EC2, and IAM roles (see the IAM Permissions section below).
- 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:
- ECS (The Orchestrator): The “brain” that manages your container lifecycle, service discovery, and health checks.
- 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.
1. Automated CLI Provisioning (Recommended)
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
IAMFullAccessorAdministratorAccess). If your key belongs to a restricted user, please refer to the Manual Configuration steps below.
What the CLI Automates
- Creates the IAM Group: Checks for the existence of
admin-groupand creates it if missing. - Attaches Group Policies: Links the following 5 policies to
admin-group:AmazonEC2FullAccessAmazonECS_FullAccessAmazonRoute53FullAccessAmazonEC2ContainerServiceRoleAmazonECSTaskExecutionRolePolicy
- Assigns User Membership: Adds your authenticated IAM user to the
admin-group. - Attaches Direct Policies: Links the following 3 policies directly to your IAM user:
AmazonEC2ContainerRegistryFullAccessAmazonElasticFileSystemFullAccessCloudWatchLogsFullAccess
- 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
- Open the IAM Console.
- Navigate to User Groups and click Create Group. Name the group:
admin-group. - In the Attach permissions policies search bar, search for and attach the following policies:
AmazonEC2FullAccessAmazonECS_FullAccessAmazonRoute53FullAccessAmazonEC2ContainerServiceRoleAmazonECSTaskExecutionRolePolicy
- Click Create Group.
Step 2: Add Your User to the Group
- Inside the group details for
admin-group, go to the Users tab and click Add Users. - Select your
adminuser and click Add Users.
Step 3: Attach Direct Policies to the User
- Navigate to Users and select your
adminuser. - Under the Permissions tab, click Add permissions -> Attach policies directly.
- Search for and attach the following policies:
AmazonEC2ContainerRegistryFullAccessAmazonElasticFileSystemFullAccessCloudWatchLogsFullAccess
- Click Next and then Add permissions.
Step 4: Add Custom Inline Permissions Policy
- Select your
adminuser profile. - In the Permissions tab, click Add permissions -> Create inline policy.
- 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.ymlunderinfra.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.
1. Dynamic DNS Sync (Recommended)
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.comHow 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):
- Nanokit must be configured to use Private Subnets.
- You must provision a NAT Gateway with an Elastic IP in a Public Subnet.
- 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
gatewayservice, 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:
- A Record: Point your domain to the Public IP found in
.nanokit/services-state.jsonor the Nanokit Dashboard.- Note: You must manually update this if the IP changes.
- 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 statusView Live Logs
nk logs web --followNanokit 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.