Lambda & ECS
Lambda functions, event source mappings, resource permissions, ECS clusters, task definitions, and services.
API Group:
aws.konfig.io/v1alpha1
LambdaFunction # ✅ Working ⏱ async
Creates and manages a Lambda function from a ZIP file (S3) or container image. Supports VPC placement, layers, DLQ, X-Ray tracing, CloudWatch logging configuration, EFS file system mounts, SnapStart, and reserved concurrency.
⏱ Async — polls every 5 seconds until the function reaches the Active state after creation or code updates.
Spec
| Field | Type | Required | Description |
| functionName | string | ✅ | Lambda function name. Immutable after creation. |
| roleArn | string | | IAM execution role ARN. One of roleArn or roleRef.name required. |
| roleRef.name | string | | Name of the IAMRole CR for function execution. |
| code.imageUri | string | | Container image URI (ECR). Use for container image functions. Mutually exclusive with S3 code. |
| code.s3.s3Bucket | string | | S3 bucket containing the deployment package. |
| code.s3.s3Key | string | | S3 key of the deployment package ZIP. |
| code.s3.s3ObjectVersion | string | | S3 object version for versioned buckets. |
| runtime | string | | Lambda runtime (e.g. nodejs20.x, python3.12, java21, go1.x). Not required for container images. |
| handler | string | | Entry point handler (e.g. index.handler). Not required for container images. |
| architecture | string | | x86_64 or arm64. Default: x86_64. |
| description | string | | Human-readable description. |
| timeout | int32 | | Maximum execution time in seconds (1–900). Default: 3. |
| memorySize | int32 | | Memory allocation in MB (128–10240). Default: 128. |
| ephemeralStorageSize | int32 | | /tmp storage in MB (512–10240). Default: 512. |
| environment | map[string]string | | Environment variables for the function. |
| vpcConfig.subnetRefs | []SubnetRef | | Subnet CR names or IDs for VPC deployment. |
| vpcConfig.securityGroupRefs | []string | | Security group CR names for the function's ENIs. |
| layers | []string | | Layer version ARNs (maximum 5). |
| deadLetterConfig.targetARN | string | | SQS queue or SNS topic ARN for failed invocation events. |
| tracingConfig.mode | string | | X-Ray tracing: PassThrough (default) or Active. |
| loggingConfig.logFormat | string | | Text or JSON. |
| loggingConfig.logGroup | string | | CloudWatch log group name. Defaults to /aws/lambda/<function-name>. |
| loggingConfig.systemLogLevel | string | | Lambda platform log level: DEBUG, INFO, or WARN. |
| loggingConfig.applicationLogLevel | string | | Application log level: TRACE, DEBUG, INFO, WARN, ERROR, or FATAL. |
| reservedConcurrency | int32 | | Reserved concurrency: nil = don't manage, 0 = throttle all invocations, -1 = delete existing reservation, positive = set limit. |
| fileSystemConfigs | []EFSConfig | | EFS access point mounts. |
| fileSystemConfigs[].arn | string | | EFS access point ARN. |
| fileSystemConfigs[].localMountPath | string | | Mount path in the function (must start with /mnt/). |
| snapStart.applyOn | string | | SnapStart: PublishedVersions or None. Java runtimes only. |
| imageConfig.command | []string | | Container CMD override (container image functions). |
| imageConfig.entryPoint | []string | | Container ENTRYPOINT override. |
| imageConfig.workingDirectory | string | | Container working directory override. |
| tags | map[string]string | | AWS tags applied to the function. |
Status
| Field | Description |
| functionArn | The ARN of the Lambda function. |
| state | Function state: Pending, Active, Inactive, Failed. |
| codeSha256 | SHA256 hash of the deployed code package (used for drift detection). |
| conditions | Standard Kubernetes conditions. |
| observedGeneration | Last reconciled generation. |
| lastSyncTime | RFC3339 timestamp of last sync. |
Example — Basic ZIP Function
apiVersion: aws.konfig.io/v1alpha1
kind: LambdaFunction
metadata:
name: my-api-handler
namespace: serverless
spec:
functionName: my-api-handler
roleArn: arn:aws:iam::123456789012:role/lambda-execution-role
code:
s3:
s3Bucket: my-deployment-bucket
s3Key: functions/my-api-handler/v1.2.3.zip
runtime: python3.12
handler: app.handler
timeout: 30
memorySize: 256
environment:
DATABASE_URL: "postgresql://host:5432/db"
LOG_LEVEL: INFO
tags:
env: prod
service: api
Example — Full-Featured ZIP Function
apiVersion: aws.konfig.io/v1alpha1
kind: LambdaFunction
metadata:
name: prod-data-processor
namespace: serverless
spec:
functionName: prod-data-processor
roleRef:
name: data-processor-role
code:
s3:
s3Bucket: my-deployment-bucket
s3Key: functions/data-processor/v2.0.0.zip
s3ObjectVersion: abc123versId
runtime: nodejs20.x
handler: dist/index.handler
architecture: arm64
description: "Processes incoming data events from SQS"
timeout: 300
memorySize: 1024
ephemeralStorageSize: 2048
environment:
QUEUE_URL: "https://sqs.us-east-1.amazonaws.com/123456789012/my-queue"
ENVIRONMENT: prod
vpcConfig:
subnetRefs:
- prod-private-subnet-1a
securityGroupRefs:
- lambda-sg
layers:
- arn:aws:lambda:us-east-1:123456789012:layer:my-dependencies:5
deadLetterConfig:
targetARN: arn:aws:sqs:us-east-1:123456789012:lambda-dlq
tracingConfig:
mode: Active
loggingConfig:
logFormat: JSON
systemLogLevel: WARN
applicationLogLevel: INFO
reservedConcurrency: 50
tags:
env: prod
service: data-processor
Example — Container Image Function
apiVersion: aws.konfig.io/v1alpha1
kind: LambdaFunction
metadata:
name: ml-inference
namespace: serverless
spec:
functionName: ml-inference
roleArn: arn:aws:iam::123456789012:role/lambda-execution-role
code:
imageUri: 123456789012.dkr.ecr.us-east-1.amazonaws.com/ml-inference:v1.5.0
architecture: arm64
timeout: 60
memorySize: 4096
imageConfig:
command:
- inference.handler
workingDirectory: /app
environment:
MODEL_PATH: /opt/model
tags:
env: prod
type: container
Example — Java SnapStart Function
apiVersion: aws.konfig.io/v1alpha1
kind: LambdaFunction
metadata:
name: java-api
namespace: serverless
spec:
functionName: java-api
roleArn: arn:aws:iam::123456789012:role/lambda-execution-role
code:
s3:
s3Bucket: my-deployment-bucket
s3Key: functions/java-api/v1.0.0.jar
runtime: java21
handler: com.example.Handler::handleRequest
timeout: 30
memorySize: 512
snapStart:
applyOn: PublishedVersions
tags:
env: prod
runtime: java
Notes
functionName is immutable after creation.
reservedConcurrency: nil means the operator does not manage concurrency at all. 0 throttles all invocations. -1 removes any existing reservation. Positive values set a specific limit.
- SnapStart (
snapStart.applyOn: PublishedVersions) is only supported on Java runtimes (java11, java17, java21).
- EFS file system mount paths must start with
/mnt/.
Deletion
Immediate. The Lambda function and all its versions and aliases are deleted.
LambdaEventSourceMapping # ✅ Working
Creates an event source mapping that connects an SQS queue, Kinesis stream, or DynamoDB stream to a Lambda function as a trigger.
Spec
| Field | Type | Required | Description |
| functionArn | string | | Lambda function ARN. One of functionArn or functionRef.name required. |
| functionRef.name | string | | Name of the LambdaFunction CR. |
| eventSourceArn | string | ✅ | ARN of the event source (SQS queue, Kinesis stream, DynamoDB stream, or MSK cluster). |
| batchSize | int32 | | Number of records per batch. SQS: 1–10000. Kinesis/DynamoDB: 1–10000. |
| enabled | bool | | Enable or disable the mapping. Default: true. |
| startingPosition | string | | Position in stream to start reading: TRIM_HORIZON, LATEST, or AT_TIMESTAMP. Not applicable for SQS. |
| maximumBatchingWindowInSeconds | int32 | | Maximum time to wait before invoking (0–300). |
| filterCriteria.filters | []string | | JSON filter patterns. Only events matching a filter will be sent to Lambda. |
Status
| Field | Description |
| uuid | The UUID of the event source mapping. |
| state | Mapping state: Creating, Enabled, Disabled, Enabling, Disabling. |
| conditions | Standard Kubernetes conditions. |
| observedGeneration | Last reconciled generation. |
| lastSyncTime | RFC3339 timestamp of last sync. |
Example — SQS Trigger
apiVersion: aws.konfig.io/v1alpha1
kind: LambdaEventSourceMapping
metadata:
name: data-processor-sqs-trigger
namespace: serverless
spec:
functionRef:
name: prod-data-processor
eventSourceArn: arn:aws:sqs:us-east-1:123456789012:order-processing
batchSize: 10
enabled: true
maximumBatchingWindowInSeconds: 5
filterCriteria:
filters:
- '{"body": {"eventType": ["ORDER_CREATED", "ORDER_UPDATED"]}}'
Deletion
Immediate. The event source mapping is deleted. The Lambda function and event source (SQS queue, etc.) are unaffected.
LambdaPermission # ✅ Working
Adds a resource-based policy statement to a Lambda function, granting an AWS service or account permission to invoke the function. Idempotent — a ResourceConflictException for an existing statement ID is treated as success.
Spec
| Field | Type | Required | Description |
| functionArn | string | | Lambda function ARN. One of functionArn or functionRef.name required. |
| functionRef.name | string | | Name of the LambdaFunction CR. |
| statementId | string | ✅ | Unique identifier for the policy statement. |
| action | string | ✅ | Lambda action to allow (e.g. lambda:InvokeFunction). |
| principal | string | ✅ | AWS service or account principal (e.g. sqs.amazonaws.com, apigateway.amazonaws.com). |
| sourceArn | string | | ARN of the specific resource allowed to invoke (recommended to prevent confused deputy attacks). |
| sourceAccount | string | | AWS account ID for cross-account invocations. |
Status
| Field | Description |
| statementExists | Boolean indicating whether the policy statement exists in the function's resource policy. |
| conditions | Standard Kubernetes conditions. |
| observedGeneration | Last reconciled generation. |
| lastSyncTime | RFC3339 timestamp of last sync. |
Example — Allow SQS to Invoke
apiVersion: aws.konfig.io/v1alpha1
kind: LambdaPermission
metadata:
name: allow-sqs-invoke
namespace: serverless
spec:
functionRef:
name: prod-data-processor
statementId: AllowSQSInvoke
action: lambda:InvokeFunction
principal: sqs.amazonaws.com
sourceArn: arn:aws:sqs:us-east-1:123456789012:order-processing
Notes
- This resource is idempotent — if a statement with the same
statementId already exists (e.g. from a previous apply), the controller treats it as success.
- Always specify
sourceArn to prevent confused deputy vulnerabilities when granting service principals access.
Deletion
Immediate. The specific policy statement is removed from the function's resource policy.
ECSCluster # ✅ Working
Creates and manages an ECS cluster with capacity provider configuration and Container Insights monitoring.
Spec
| Field | Type | Required | Description |
| clusterName | string | ✅ | Name of the ECS cluster. Immutable after creation. |
| capacityProviders | []string | | Capacity providers to associate (e.g. ["FARGATE", "FARGATE_SPOT"]). |
| containerInsights | bool | | Enable Container Insights CloudWatch metrics. Default: false. |
| tags | map[string]string | | AWS tags applied to the cluster. |
Status
| Field | Description |
| clusterArn | The ARN of the ECS cluster. |
| status | Cluster status: PROVISIONING, ACTIVE, INACTIVE. |
| conditions | Standard Kubernetes conditions. |
| observedGeneration | Last reconciled generation. |
| lastSyncTime | RFC3339 timestamp of last sync. |
Example
apiVersion: aws.konfig.io/v1alpha1
kind: ECSCluster
metadata:
name: prod-cluster
namespace: containers
spec:
clusterName: prod-services
capacityProviders:
- FARGATE
- FARGATE_SPOT
containerInsights: true
tags:
env: prod
Deletion
Immediate. The cluster is deleted. Any services still running in the cluster must be deleted first.
ECSTaskDefinition # ✅ Working
Registers ECS task definitions. A new revision is registered only when the spec content hash changes, avoiding unnecessary revision churn on every reconcile.
Spec
| Field | Type | Required | Description |
| family | string | ✅ | Task definition family name. |
| cpu | string | ✅ | Task CPU units (e.g. "256", "1024"). Required for Fargate. |
| memory | string | ✅ | Task memory in MiB (e.g. "512", "2048"). Required for Fargate. |
| networkMode | string | | Network mode: awsvpc, bridge, host, none. Default: awsvpc. Required for Fargate. |
| executionRoleArn | string | | ECS task execution role ARN (for pulling images, writing logs). Mutually exclusive with executionRoleRef.name. |
| executionRoleRef.name | string | | Name of the IAMRole CR for task execution. |
| taskRoleArn | string | | IAM role ARN for task code (application AWS API calls). Mutually exclusive with taskRoleRef.name. |
| taskRoleRef.name | string | | Name of the IAMRole CR for the task. |
| containerDefinitions | []ContainerDef | ✅ | List of container definitions. |
| containerDefinitions[].name | string | | Container name. |
| containerDefinitions[].image | string | | Container image URI. |
| containerDefinitions[].cpu | int32 | | Container CPU units. |
| containerDefinitions[].memory | int32 | | Container memory in MiB (hard limit). |
| containerDefinitions[].essential | bool | | If true, stopping this container stops the task. Default: true. |
| containerDefinitions[].command | []string | | Command override. |
| containerDefinitions[].environment | map[string]string | | Environment variables. |
| containerDefinitions[].logGroup | string | | CloudWatch Logs group name for awslogs driver. |
| containerDefinitions[].portMappings | []PortMapping | | Port mappings for the container. |
| containerDefinitions[].portMappings[].containerPort | int32 | | Container port number. |
| containerDefinitions[].portMappings[].protocol | string | | tcp or udp. Default: tcp. |
| tags | map[string]string | | AWS tags applied to the task definition. |
Status
| Field | Description |
| taskDefinitionArn | Full ARN including revision (e.g. arn:aws:ecs:...:task-definition/my-app:5). |
| revision | The current active revision number. |
| specHash | Hash of the spec used to detect changes and avoid unnecessary revisions. |
| conditions | Standard Kubernetes conditions. |
| observedGeneration | Last reconciled generation. |
| lastSyncTime | RFC3339 timestamp of last sync. |
Example
apiVersion: aws.konfig.io/v1alpha1
kind: ECSTaskDefinition
metadata:
name: my-web-app
namespace: containers
spec:
family: my-web-app
cpu: "512"
memory: "1024"
networkMode: awsvpc
executionRoleRef:
name: ecs-task-execution-role
taskRoleRef:
name: my-web-app-role
containerDefinitions:
- name: web
image: 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-web-app:v2.1.0
cpu: 256
memory: 512
essential: true
environment:
ENVIRONMENT: prod
LOG_LEVEL: info
logGroup: /ecs/my-web-app
portMappings:
- containerPort: 8080
protocol: tcp
- name: nginx
image: nginx:1.25
cpu: 128
memory: 256
essential: true
portMappings:
- containerPort: 80
protocol: tcp
tags:
env: prod
service: my-web-app
Notes
- A new revision is registered with
RegisterTaskDefinition only when the spec hash changes. This prevents unnecessary revision accumulation on drift detection cycles.
- The
taskDefinitionArn in status includes the revision number. Reference this in ECSService.spec.taskDefinitionRef.name or use the family name (which defaults to the latest revision).
Deletion
Deregisters active revision. The current active revision is deregistered. AWS retains deregistered revisions but they cannot be used to run new tasks. Previous revisions are not affected.
ECSService # ✅ Working
Creates and manages a long-running ECS service with desired task count, load balancer integration, VPC networking, and ECS Exec support.
Spec
| Field | Type | Required | Description |
| clusterName | string | | ECS cluster name. Mutually exclusive with clusterRef.name. |
| clusterRef.name | string | | Name of the ECSCluster CR. |
| serviceName | string | ✅ | ECS service name. Immutable after creation. |
| taskDefinitionArn | string | | Task definition ARN (with or without revision). Mutually exclusive with taskDefinitionRef.name. |
| taskDefinitionRef.name | string | | Name of the ECSTaskDefinition CR. |
| desiredCount | int32 | ✅ | Number of tasks to run. |
| launchType | string | | FARGATE, EC2, or EXTERNAL. Default: FARGATE. |
| networkConfiguration.subnetRefs | []SubnetRef | | Subnet CR names or IDs for task ENIs (awsvpc mode). |
| networkConfiguration.securityGroupRefs | []string | | Security group CR names for task ENIs. |
| networkConfiguration.assignPublicIp | string | | ENABLED or DISABLED. Default: DISABLED. |
| loadBalancers | []LoadBalancerConfig | | Target group associations. |
| loadBalancers[].targetGroupArn | string | | Target group ARN to register tasks with. |
| loadBalancers[].containerName | string | | Name of the container to register with the target group. |
| loadBalancers[].containerPort | int32 | | Container port to route traffic to. |
| healthCheckGracePeriodSeconds | int32 | | Seconds to ignore health check failures after a task starts (useful for slow-starting apps). |
| enableExecuteCommand | bool | | Enable ECS Exec for interactive task access (aws ecs execute-command). |
| tags | map[string]string | | AWS tags applied to the service. |
Status
| Field | Description |
| serviceArn | The ARN of the ECS service. |
| status | Service status: ACTIVE, DRAINING, INACTIVE. |
| runningCount | Number of tasks currently running. |
| pendingCount | Number of tasks in pending state. |
| conditions | Standard Kubernetes conditions. |
| observedGeneration | Last reconciled generation. |
| lastSyncTime | RFC3339 timestamp of last sync. |
Example
apiVersion: aws.konfig.io/v1alpha1
kind: ECSService
metadata:
name: my-web-app-service
namespace: containers
spec:
clusterRef:
name: prod-cluster
serviceName: my-web-app
taskDefinitionRef:
name: my-web-app
desiredCount: 3
launchType: FARGATE
networkConfiguration:
subnetRefs:
- prod-private-subnet-1a
- prod-private-subnet-1b
securityGroupRefs:
- web-sg
assignPublicIp: DISABLED
loadBalancers:
- targetGroupArn: arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/my-web-app/abc123
containerName: nginx
containerPort: 80
healthCheckGracePeriodSeconds: 60
enableExecuteCommand: true
tags:
env: prod
service: my-web-app
Deletion
Force-deleted immediately. The service is deleted with force: true, which terminates all running tasks without waiting for them to drain. For graceful shutdown, scale desiredCount to 0 first, then delete the CR.