# Ipa Stack Queue

> Deploy a queue tier stack: SQS + DLQ + worker Lambda + ESM + DynamoDB (feature-flagged).

- Skill: `aws-samples/ipa-stack-queue` (Agent Skill)
- Install (CLI): `npx skillmds@latest add aws-samples/ipa-stack-queue`
- Raw SKILL.md: https://api.skillmd.com/api/skills/aws-samples/ipa-stack-queue/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: aws-samples (https://skillmd.com/u/aws-samples)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/aws-samples/ipa-stack-queue

---


# ipa-stack-queue

Deploy a queue tier stack: SQS + DLQ + worker Lambda + ESM + DynamoDB (feature-flagged).

## Stack Identity

| Property | Value |
|----------|-------|
| Stack name | `{APP_NAMESPACE}-{APP_ENV}-queue` |
| Template | `infra/cfn/queue/queue.yml` |
| Capabilities | `CAPABILITY_NAMED_IAM` |
| Lifecycle | deploy (solution stack) |
| Tier | queue |

## Parameters

| Parameter | Required | Default | Description |
|-----------|----------|---------|-------------|
| Namespace | Yes | — | Project namespace prefix |
| Environment | Yes | — | Deployment environment (dev/staging/prod) |
| ImageUri | Yes | — | ECR image URI with tag |
| AuthIssuer | Yes | — | Cognito OIDC issuer URL |
| AuthAudience | Yes | — | Cognito app client ID |
| QueueName | No | `jobs` | Logical queue name |
| VisibilityTimeout | No | `300` | Message visibility timeout (seconds) |
| MessageRetentionPeriod | No | `345600` | Message retention (seconds, default 4 days) |
| MaxReceiveCount | No | `3` | Attempts before DLQ |
| CreateDLQ | No | `true` | Create dead-letter queue |
| FunctionName | No | `fn-worker` | Worker Lambda name |
| MemorySize | No | `512` | Worker Lambda memory (MB) |
| Timeout | No | `300` | Worker Lambda timeout (seconds) |
| ImageCommand | No | `python,-m,sqs_handler` | Worker container CMD |
| EnableJobsTable | No | `false` | Feature flag: create jobs DynamoDB table |

## Feature Flags

| Flag | Default | Condition | Controls |
|------|---------|-----------|----------|
| EnableJobsTable | `false` | HasJobsTable | JobsTable resource, DynamoDB IAM policy, JobsTableArn output |
| CreateDLQ | `true` | HasDLQ | DeadLetterQueue resource, DlqUrl/DlqArn outputs, DLQ depth alarm |

## Wirable Parameters

| Parameter | Source Stack | Source Output | Notes |
|-----------|-------------|---------------|-------|
| ImageUri | ecr | RepositoryUri | Append `:$(IMAGE_TAG)` |
| AuthIssuer | cognito | IssuerUrl | OIDC issuer URL |
| AuthAudience | cognito | UserPoolClientId | App client ID |

## Outputs

| Output | Export Name | Description |
|--------|------------|-------------|
| QueueUrl | `{StackName}-QueueUrl` | Consumed by backend → SqsQueueUrl |
| QueueArn | `{StackName}-QueueArn` | Consumed by backend → SqsSendQueueArns |
| QueueName | `{StackName}-QueueName` | Physical queue name |
| WorkerFunctionArn | `{StackName}-WorkerFunctionArn` | Worker Lambda ARN |
| WorkerFunctionName | `{StackName}-WorkerFunctionName` | Worker Lambda name |
| DlqUrl | `{StackName}-DlqUrl` | Conditional (HasDLQ) |
| DlqArn | `{StackName}-DlqArn` | Conditional (HasDLQ) |
| JobsTableArn | `{StackName}-JobsTableArn` | Conditional (HasJobsTable) |

## Build Requirements

The queue worker Lambda reuses the shared `rest-lambda` container image built by the backend stack — CMD is overridden via the `ImageCommand` parameter. No additional build target is required for this stack; do not emit a duplicate `build-rest-lambda` when backend is also in the composition.

## Security

- SQS: Deny non-SSL policy, SQS-managed SSE
- Lambda: Per-function execution role, SQS receive policy always present
- IAM: Conditional DynamoDB policies scoped to `!GetAtt Table.Arn`
- Log groups: 30-day retention
- No CrossTierTableArns parameter (K2:B — convention-based ARN only)

## Deploy Order

Queue deploys **before** backend (S2:B). Backend receives queue outputs via wirable parameters.

## Local Dev Environment

After deployment, the `update-env-sqs` target in `scripts/env.mk` writes `SQS_QUEUE_URL` to `.env`:

| Variable | Source Output | Description |
|----------|--------------|-------------|
| SQS_QUEUE_URL | QueueUrl | SQS queue URL for job submission |

This enables the local FastAPI backend (`load_dotenv()`) to submit jobs to the deployed queue without manual `.env` configuration. The target runs as part of `post-deploy.mk`'s `update-env` step, gated by `.env` existence (skipped in CI/CD).

## Compose Config

Parameter overrides applied by `/ipa-compose`:

| Parameter | Value | Reason |
|-----------|-------|--------|
| FunctionName | fn-worker | Distinct from REST handler |
| InvokeMode | BUFFERED | Synchronous SQS processing |
| Timeout | 300 | Match REST handler timeout |
| ImageCommand | python,-m,sqs_handler | Worker entrypoint |
| EnableJobsTable | true | Job tracking feature |

## Deploy Command

```bash
aws cloudformation deploy \
  --template-file infra/cfn/queue/queue.yml \
  --stack-name $(APP_NAMESPACE)-$(APP_ENV)-queue \
  --capabilities CAPABILITY_NAMED_IAM \
  --parameter-overrides \
    Namespace=$(APP_NAMESPACE) \
    Environment=$(APP_ENV) \
    ImageUri=$(REPO_URI):$(IMAGE_TAG) \
    AuthIssuer=$(AUTH_ISSUER) \
    AuthAudience=$(AUTH_AUDIENCE) \
    EnableJobsTable=true
```

## Terraform Module

| Property | Value |
|----------|-------|
| Module path | `infra/tf/queue/` |
| State key | `{namespace}-{env}/queue/terraform.tfstate` |
| Required version | `>= 1.5.0` |
| Providers | `hashicorp/aws >= 5.0` |

### Variables

| Variable | Type | Default | Maps to CFN |
|----------|------|---------|-------------|
| namespace | string | — | Namespace |
| environment | string | — | Environment |
| region | string | — | (implicit) |
| state_bucket | string | — | (TF infrastructure) |
| image_uri | string | — | ImageUri |
| auth_issuer | string | — | AuthIssuer |
| auth_audience | string | — | AuthAudience |
| queue_name | string | `jobs` | QueueName |
| visibility_timeout | number | `300` | VisibilityTimeout |
| message_retention_period | number | `345600` | MessageRetentionPeriod |
| max_receive_count | number | `3` | MaxReceiveCount |
| function_name | string | `fn-worker` | FunctionName |
| memory_size | number | `512` | MemorySize |
| timeout | number | `300` | Timeout |
| image_command | string | `python,-m,sqs_handler` | ImageCommand |
| enable_jobs_table | bool | `false` | EnableJobsTable |

### Outputs

| Output | Maps to CFN |
|--------|-------------|
| queue_url | QueueUrl |
| queue_arn | QueueArn |
| queue_name | QueueName |
| worker_function_arn | WorkerFunctionArn |
| worker_function_name | WorkerFunctionName |
| dlq_url | DlqUrl |
| dlq_arn | DlqArn |
| jobs_table_arn | JobsTableArn |

### Remote State References

| Source Module | Data Source | Outputs Used |
|--------------|-------------|--------------|
| cognito | `terraform_remote_state.cognito` | issuer_url, user_pool_client_id |
| ecr | `terraform_remote_state.ecr` | repository_uri |

