From 0b30003b9e6ce8f29a3e96b61542656a68261aed Mon Sep 17 00:00:00 2001 From: cathy Date: Mon, 13 Apr 2026 10:59:55 -0500 Subject: [PATCH 1/4] feat: add sqs autoscaling docs --- applications/configure/sqs-autoscaling.mdx | 95 ++++++++++++++++++++++ mint.json | 1 + 2 files changed, 96 insertions(+) create mode 100644 applications/configure/sqs-autoscaling.mdx diff --git a/applications/configure/sqs-autoscaling.mdx b/applications/configure/sqs-autoscaling.mdx new file mode 100644 index 0000000..76cd457 --- /dev/null +++ b/applications/configure/sqs-autoscaling.mdx @@ -0,0 +1,95 @@ +--- +title: "SQS Queue-Depth Autoscaling" +description: "Scale your workers based on Amazon SQS queue depth using the SQS Exporter addon" +--- + +# SQS Queue-Depth Autoscaling + +If your application processes messages from Amazon SQS, Porter can automatically scale your worker services based on queue depth. When messages pile up, Porter scales up your workers. When the queue drains, it scales back down. + +This guide uses the [SQS Exporter](https://github.com/porter-dev/sqs-exporter) Porter addon — a lightweight Prometheus exporter that polls SQS queue depth and feeds it to Porter's built-in [metric-based autoscaler](/applications/observability/custom-metrics-and-autoscaling) via KEDA. + +## Prerequisites + +- An AWS account with an SQS queue +- An IAM user or role with permissions to read SQS queue attributes +- A worker service on Porter that processes messages from the queue + +## Step 1: Create IAM Credentials + +Create an IAM user and attach the **`AmazonSQSReadOnlyAccess`** managed policy — it includes `sqs:GetQueueAttributes`, which is all the exporter needs. Generate an access key for the user and keep the credentials handy for Step 2. + +{/* TODO: (Cathy) update when irsa is supported */} +{/* **Note:** If your cluster uses IAM Roles for Service Accounts (IRSA), you can attach the policy to your node role instead and omit explicit credentials from the Helm values. */} + +## Step 2: Deploy the SQS Exporter + +1. Navigate to your application in the Porter dashboard +2. Go to the **Add-ons** tab +3. Click **Add New** and select **Helm Chart** +4. Configure the Helm chart: + - **Repository URL**: `oci://ghcr.io/porter-dev` + - **Chart Name**: `sqs-exporter` +5. In the **Helm Values** section, paste the following configuration: + +```yaml +sqsQueueUrls: "https://sqs.us-east-1.amazonaws.com/123456789/your-queue-name" + +aws: + region: "us-east-1" + accessKeyId: "YOUR_ACCESS_KEY_ID" + secretAccessKey: "YOUR_SECRET_ACCESS_KEY" + sessionToken: "" # optional, only for temporary credentials + +pollIntervalSeconds: 10 +``` + + +Replace `sqsQueueUrls` with your full SQS queue URL, and replace `YOUR_ACCESS_KEY_ID` and `YOUR_SECRET_ACCESS_KEY` with the credentials from Step 1. To monitor multiple queues, provide a comma-separated list of URLs. + + +6. Click **Deploy** + +Verify the exporter is running by checking the add-on logs — you should see the exporter polling your queue with no `AccessDenied` errors. + +## Step 3: Configure Metric-Based Autoscaling + +1. Navigate to your application in the Porter dashboard +2. Go to the **Services** tab and click on your worker service +3. Under **Autoscaling**, select the **Metric-based** tab +4. Fill in the following fields: + - **Min instances**: `1` (or `0` for scale-to-zero) + - **Max instances**: `10` (adjust based on your workload) + - **Metric name**: `sqs_messages_visible` + - **Query**: `avg(sqs_messages_visible{queue_name="your-queue-name"})` + - **Threshold**: `10` (target number of messages per worker instance) + + +Replace `your-queue-name` with the name portion of your SQS queue URL (e.g., for `https://sqs.us-east-1.amazonaws.com/123456789/order-processing`, use `order-processing`). The `queue_name` label must match exactly or autoscaling won't trigger. + + +## Scaling Latency + +End-to-end scale-up latency depends on the metrics pipeline: + +| Step | Default | +|------|---------| +| SQS poll | 10s | +| Prometheus scrape | 15s | +| KEDA poll | 30s | +| HPA scale-up stabilization | 60s | + +The HPA scale-up stabilization window (60s) is the dominant factor. For queue-based workloads where fast scale-up matters, you can drop it to `0` via your worker service's **Settings** tab → **Helm overrides**: + +```yaml +keda: + hpa: + scaleUp: + stabilizationWindowSeconds: 0 + policy: + type: Percent + value: 100 + periodSeconds: 15 +``` + +Node provisioning is often the remaining bottleneck once the autoscaling pipeline is tuned. diff --git a/mint.json b/mint.json index 835f3d0..0dfcacb 100644 --- a/mint.json +++ b/mint.json @@ -102,6 +102,7 @@ "applications/configure/basic-configuration", "applications/configure/autoscaling", "applications/configure/temporal-autoscaling", + "applications/configure/sqs-autoscaling", "applications/configure/custom-domains", "applications/configure/zero-downtime-deployments", "applications/configure/advanced-networking" From 8346cf5fc21cd9485909be55fb95f62ab8b36ceb Mon Sep 17 00:00:00 2001 From: cathy Date: Tue, 14 Apr 2026 19:02:08 -0500 Subject: [PATCH 2/4] add irsa support --- applications/configure/sqs-autoscaling.mdx | 112 +++++++++++++++++++-- 1 file changed, 103 insertions(+), 9 deletions(-) diff --git a/applications/configure/sqs-autoscaling.mdx b/applications/configure/sqs-autoscaling.mdx index 76cd457..10ef40a 100644 --- a/applications/configure/sqs-autoscaling.mdx +++ b/applications/configure/sqs-autoscaling.mdx @@ -15,12 +15,63 @@ This guide uses the [SQS Exporter](https://github.com/porter-dev/sqs-exporter) P - An IAM user or role with permissions to read SQS queue attributes - A worker service on Porter that processes messages from the queue -## Step 1: Create IAM Credentials +## Step 1: Set Up AWS Credentials -Create an IAM user and attach the **`AmazonSQSReadOnlyAccess`** managed policy — it includes `sqs:GetQueueAttributes`, which is all the exporter needs. Generate an access key for the user and keep the credentials handy for Step 2. +Choose one of the following authentication methods. IRSA is recommended — it uses short-lived tokens tied to your cluster's OIDC provider, so there are no long-lived keys to rotate or store. + +### Option A: IRSA (recommended) + +IRSA (IAM Roles for Service Accounts) attaches an IAM role directly to the exporter's Kubernetes service account. EKS injects a short-lived OIDC token into the pod automatically. + +**1. Find your OIDC provider URL.** + +In the AWS Console, go to **EKS → your cluster → Overview tab → OpenID Connect provider URL**. Copy the URL and strip the `https://` prefix — this is your `OIDC_PROVIDER`. + +**2. Create an IAM role with a custom trust policy.** + +Go to **IAM → Roles → Create role → Custom trust policy** and paste the following, substituting your values: + +```json +{ + "Version": "2012-10-17", + "Statement": [{ + "Effect": "Allow", + "Principal": { + "Federated": "arn:aws:iam::{ACCOUNT_ID}:oidc-provider/{OIDC_PROVIDER}" + }, + "Action": "sts:AssumeRoleWithWebIdentity", + "Condition": { + "StringEquals": { + "{OIDC_PROVIDER}:sub": "system:serviceaccount:{NAMESPACE}:helmchart-sqs-exporter", + "{OIDC_PROVIDER}:aud": "sts.amazonaws.com" + } + } + }] +} +``` + +- `ACCOUNT_ID`: your AWS account ID +- `OIDC_PROVIDER`: the value from step 1 (without `https://`) +- `NAMESPACE`: the namespace of your Porter deployment target (typically `default`) + +**3. Attach a permissions policy** to the role. Create an inline policy: + +```json +{ + "Version": "2012-10-17", + "Statement": [{ + "Effect": "Allow", + "Action": "sqs:GetQueueAttributes", + "Resource": "arn:aws:sqs:{REGION}:{ACCOUNT_ID}:{QUEUE_NAME}" + }] +} +``` + +Keep the role ARN handy — you'll use it in Step 2. -{/* TODO: (Cathy) update when irsa is supported */} -{/* **Note:** If your cluster uses IAM Roles for Service Accounts (IRSA), you can attach the policy to your node role instead and omit explicit credentials from the Helm values. */} +### Option B: Static credentials (fallback) + +Create an IAM user and attach the **`AmazonSQSReadOnlyAccess`** managed policy — it includes `sqs:GetQueueAttributes`, which is all the exporter needs. Generate an access key for the user and keep the credentials handy for Step 2. ## Step 2: Deploy the SQS Exporter @@ -30,7 +81,24 @@ Create an IAM user and attach the **`AmazonSQSReadOnlyAccess`** managed policy 4. Configure the Helm chart: - **Repository URL**: `oci://ghcr.io/porter-dev` - **Chart Name**: `sqs-exporter` -5. In the **Helm Values** section, paste the following configuration: + - **Chart Version**: `0.1.1` +5. In the **Helm Values** section, paste the configuration for your chosen auth method: + +**Option A: IRSA** + +```yaml +sqsQueueUrls: "https://sqs.us-east-1.amazonaws.com/123456789/your-queue-name" + +serviceAccount: + roleArn: "arn:aws:iam::{ACCOUNT_ID}:role/{ROLE_NAME}" + +aws: + region: "us-east-1" + +pollIntervalSeconds: 10 +``` + +**Option B: Static credentials** ```yaml sqsQueueUrls: "https://sqs.us-east-1.amazonaws.com/123456789/your-queue-name" @@ -45,12 +113,12 @@ pollIntervalSeconds: 10 ``` -Replace `sqsQueueUrls` with your full SQS queue URL, and replace `YOUR_ACCESS_KEY_ID` and `YOUR_SECRET_ACCESS_KEY` with the credentials from Step 1. To monitor multiple queues, provide a comma-separated list of URLs. +Replace `sqsQueueUrls` with your full SQS queue URL. To monitor multiple queues, provide a comma-separated list of URLs. 6. Click **Deploy** -Verify the exporter is running by checking the add-on logs — you should see the exporter polling your queue with no `AccessDenied` errors. +Verify the exporter is running by checking the add-on logs — you should see either `using static AWS credentials` or `using ambient AWS credential chain`, followed by the exporter polling your queue with no `AccessDenied` errors. ## Step 3: Configure Metric-Based Autoscaling @@ -58,8 +126,8 @@ Verify the exporter is running by checking the add-on logs — you should see th 2. Go to the **Services** tab and click on your worker service 3. Under **Autoscaling**, select the **Metric-based** tab 4. Fill in the following fields: - - **Min instances**: `1` (or `0` for scale-to-zero) - - **Max instances**: `10` (adjust based on your workload) + - **Min replicas**: `0` (scale to zero when queue is empty) or `1` (always keep one worker warm) + - **Max replicas**: `10` (adjust based on your workload) - **Metric name**: `sqs_messages_visible` - **Query**: `avg(sqs_messages_visible{queue_name="your-queue-name"})` - **Threshold**: `10` (target number of messages per worker instance) @@ -68,6 +136,32 @@ Verify the exporter is running by checking the add-on logs — you should see th Replace `your-queue-name` with the name portion of your SQS queue URL (e.g., for `https://sqs.us-east-1.amazonaws.com/123456789/order-processing`, use `order-processing`). The `queue_name` label must match exactly or autoscaling won't trigger. +### Worker AWS credentials + +The worker pod also needs AWS credentials to consume from SQS. + +**Option A: IRSA (recommended)** + +Attach an IAM role to the worker's service account. The role needs `sqs:ReceiveMessage`, `sqs:DeleteMessage`, and `sqs:GetQueueAttributes` on your queue. Use Porter's connections feature to bind the role, or annotate the service account directly with `eks.amazonaws.com/role-arn`. + +Then set these as environment variables under the worker service's **Environment** tab: + +``` +SQS_QUEUE_URL={QUEUE_URL} +AWS_REGION={AWS_REGION} +``` + +**Option B: Static credentials (fallback)** + +Set the following environment variables under the worker service's **Environment** tab (use Porter's secret config for the key and secret): + +``` +AWS_REGION={AWS_REGION} +AWS_ACCESS_KEY_ID={ACCESS_KEY_ID} +AWS_SECRET_ACCESS_KEY={SECRET_ACCESS_KEY} +SQS_QUEUE_URL={QUEUE_URL} +``` + ## Scaling Latency End-to-end scale-up latency depends on the metrics pipeline: From accc6665d2c2579ab2059231e15876fe0570c5e9 Mon Sep 17 00:00:00 2001 From: cathy Date: Fri, 17 Apr 2026 15:22:25 -0500 Subject: [PATCH 3/4] irso forward --- applications/configure/sqs-autoscaling.mdx | 169 ++++++++++++++------- 1 file changed, 114 insertions(+), 55 deletions(-) diff --git a/applications/configure/sqs-autoscaling.mdx b/applications/configure/sqs-autoscaling.mdx index 10ef40a..f65960a 100644 --- a/applications/configure/sqs-autoscaling.mdx +++ b/applications/configure/sqs-autoscaling.mdx @@ -9,19 +9,21 @@ If your application processes messages from Amazon SQS, Porter can automatically This guide uses the [SQS Exporter](https://github.com/porter-dev/sqs-exporter) Porter addon — a lightweight Prometheus exporter that polls SQS queue depth and feeds it to Porter's built-in [metric-based autoscaler](/applications/observability/custom-metrics-and-autoscaling) via KEDA. +This guide assumes you're running on EKS and uses [IRSA](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) (IAM Roles for Service Accounts) so the exporter and worker pick up short-lived, auto-rotated credentials from a pod-scoped IAM role — no long-lived keys to store or rotate. + + +Not on EKS, or need static credentials? See the [appendix](#appendix-static-credentials) at the end of this guide. + + ## Prerequisites - An AWS account with an SQS queue -- An IAM user or role with permissions to read SQS queue attributes - A worker service on Porter that processes messages from the queue +- Permissions to create IAM roles in your AWS account -## Step 1: Set Up AWS Credentials - -Choose one of the following authentication methods. IRSA is recommended — it uses short-lived tokens tied to your cluster's OIDC provider, so there are no long-lived keys to rotate or store. - -### Option A: IRSA (recommended) +## Step 1: Create an IAM Role for the Exporter -IRSA (IAM Roles for Service Accounts) attaches an IAM role directly to the exporter's Kubernetes service account. EKS injects a short-lived OIDC token into the pod automatically. +Porter deploys Helm chart addons with the release name `helmchart`, so the exporter's Kubernetes service account will always be named `helmchart-sqs-exporter`. You'll reference this in the trust policy below. **1. Find your OIDC provider URL.** @@ -67,11 +69,7 @@ Go to **IAM → Roles → Create role → Custom trust policy** and paste the fo } ``` -Keep the role ARN handy — you'll use it in Step 2. - -### Option B: Static credentials (fallback) - -Create an IAM user and attach the **`AmazonSQSReadOnlyAccess`** managed policy — it includes `sqs:GetQueueAttributes`, which is all the exporter needs. Generate an access key for the user and keep the credentials handy for Step 2. +Keep the role ARN handy — you'll use it in the next step. ## Step 2: Deploy the SQS Exporter @@ -82,9 +80,7 @@ Create an IAM user and attach the **`AmazonSQSReadOnlyAccess`** managed policy - **Repository URL**: `oci://ghcr.io/porter-dev` - **Chart Name**: `sqs-exporter` - **Chart Version**: `0.1.1` -5. In the **Helm Values** section, paste the configuration for your chosen auth method: - -**Option A: IRSA** +5. In the **Helm Values** section, paste: ```yaml sqsQueueUrls: "https://sqs.us-east-1.amazonaws.com/123456789/your-queue-name" @@ -98,70 +94,96 @@ aws: pollIntervalSeconds: 10 ``` -**Option B: Static credentials** - -```yaml -sqsQueueUrls: "https://sqs.us-east-1.amazonaws.com/123456789/your-queue-name" - -aws: - region: "us-east-1" - accessKeyId: "YOUR_ACCESS_KEY_ID" - secretAccessKey: "YOUR_SECRET_ACCESS_KEY" - sessionToken: "" # optional, only for temporary credentials - -pollIntervalSeconds: 10 -``` - Replace `sqsQueueUrls` with your full SQS queue URL. To monitor multiple queues, provide a comma-separated list of URLs. 6. Click **Deploy** -Verify the exporter is running by checking the add-on logs — you should see either `using static AWS credentials` or `using ambient AWS credential chain`, followed by the exporter polling your queue with no `AccessDenied` errors. +Verify the exporter is running by checking the add-on logs — you should see `using ambient AWS credential chain`, followed by the exporter polling your queue with no `AccessDenied` errors. -## Step 3: Configure Metric-Based Autoscaling +## Step 3: Grant the Worker AWS Access -1. Navigate to your application in the Porter dashboard -2. Go to the **Services** tab and click on your worker service -3. Under **Autoscaling**, select the **Metric-based** tab -4. Fill in the following fields: - - **Min replicas**: `0` (scale to zero when queue is empty) or `1` (always keep one worker warm) - - **Max replicas**: `10` (adjust based on your workload) - - **Metric name**: `sqs_messages_visible` - - **Query**: `avg(sqs_messages_visible{queue_name="your-queue-name"})` - - **Threshold**: `10` (target number of messages per worker instance) +The worker pod needs AWS credentials to consume from SQS. First, create an IAM role with these permissions on your queue: - -Replace `your-queue-name` with the name portion of your SQS queue URL (e.g., for `https://sqs.us-east-1.amazonaws.com/123456789/order-processing`, use `order-processing`). The `queue_name` label must match exactly or autoscaling won't trigger. - +- `sqs:ReceiveMessage` +- `sqs:DeleteMessage` +- `sqs:GetQueueAttributes` + +The role's trust policy must name the worker's service account so IRSA can assume it: -### Worker AWS credentials +```json +{ + "Version": "2012-10-17", + "Statement": [{ + "Effect": "Allow", + "Principal": { + "Federated": "arn:aws:iam::{ACCOUNT_ID}:oidc-provider/{OIDC_PROVIDER}" + }, + "Action": "sts:AssumeRoleWithWebIdentity", + "Condition": { + "StringEquals": { + "{OIDC_PROVIDER}:sub": "system:serviceaccount:{NAMESPACE}:{APP_NAME}-{SERVICE_NAME}", + "{OIDC_PROVIDER}:aud": "sts.amazonaws.com" + } + } + }] +} +``` -The worker pod also needs AWS credentials to consume from SQS. +Porter names the worker's service account `{APP_NAME}-{SERVICE_NAME}` (e.g. `sqs-poller-poller` for app `sqs-poller` with service `poller`). -**Option A: IRSA (recommended)** +Then attach the role to the worker using one of the following. -Attach an IAM role to the worker's service account. The role needs `sqs:ReceiveMessage`, `sqs:DeleteMessage`, and `sqs:GetQueueAttributes` on your queue. Use Porter's connections feature to bind the role, or annotate the service account directly with `eks.amazonaws.com/role-arn`. +### Option A: `porter.yaml` -Then set these as environment variables under the worker service's **Environment** tab: +Declare the [`awsRole` connection](/applications/configuration-as-code/services/connections#aws-role-connection) under your worker service. If your app doesn't have a `porter.yaml`, you can create one at the root of your repo with just the worker service declared — Porter merges it with your dashboard config. +```yaml +services: + - name: worker + # ... + connections: + - type: awsRole + role: my-worker-sqs-access ``` -SQS_QUEUE_URL={QUEUE_URL} -AWS_REGION={AWS_REGION} + +### Option B: Annotate the service account manually + +If you'd rather not introduce a `porter.yaml`, annotate the worker's service account directly: + +```bash +kubectl annotate sa {APP_NAME}-{SERVICE_NAME} -n {NAMESPACE} \ + eks.amazonaws.com/role-arn=arn:aws:iam::{ACCOUNT_ID}:role/{ROLE_NAME} ``` -**Option B: Static credentials (fallback)** +Either option results in the service account carrying the `eks.amazonaws.com/role-arn` annotation, which EKS uses to inject IRSA credentials into the pod. -Set the following environment variables under the worker service's **Environment** tab (use Porter's secret config for the key and secret): +### Set the worker's environment variables + +Under the worker service's **Environment** tab, set: ``` -AWS_REGION={AWS_REGION} -AWS_ACCESS_KEY_ID={ACCESS_KEY_ID} -AWS_SECRET_ACCESS_KEY={SECRET_ACCESS_KEY} SQS_QUEUE_URL={QUEUE_URL} +AWS_REGION={AWS_REGION} ``` +## Step 4: Configure Metric-Based Autoscaling + +1. Navigate to your application in the Porter dashboard +2. Go to the **Services** tab and click on your worker service +3. Under **Autoscaling**, select the **Metric-based** tab +4. Fill in the following fields: + - **Min replicas**: `0` (scale to zero when queue is empty) or `1` (always keep one worker warm) + - **Max replicas**: `10` (adjust based on your workload) + - **Metric name**: `sqs_messages_visible` + - **Query**: `avg(sqs_messages_visible{queue_name="your-queue-name"})` + - **Threshold**: `10` (target number of messages per worker instance) + + +Replace `your-queue-name` with the name portion of your SQS queue URL (e.g., for `https://sqs.us-east-1.amazonaws.com/123456789/order-processing`, use `order-processing`). The `queue_name` label must match exactly or autoscaling won't trigger. + + ## Scaling Latency End-to-end scale-up latency depends on the metrics pipeline: @@ -187,3 +209,40 @@ keda: ``` Node provisioning is often the remaining bottleneck once the autoscaling pipeline is tuned. + +## Appendix: Static credentials + +Use this path if you're running on self-managed Kubernetes, need cross-account access where setting up an OIDC trust policy isn't feasible, or just want to run the exporter locally for development. On EKS, prefer IRSA — it avoids long-lived keys entirely. + +### Exporter addon + +Create an IAM user and attach the **`AmazonSQSReadOnlyAccess`** managed policy — it includes `sqs:GetQueueAttributes`, which is all the exporter needs. Generate an access key for the user. + +Follow [Step 2](#step-2-deploy-the-sqs-exporter) to add the addon in Porter, skipping the IAM role setup. Use these Helm values instead: + +```yaml +sqsQueueUrls: "https://sqs.us-east-1.amazonaws.com/123456789/your-queue-name" + +aws: + region: "us-east-1" + accessKeyId: "YOUR_ACCESS_KEY_ID" + secretAccessKey: "YOUR_SECRET_ACCESS_KEY" + sessionToken: "" # optional, only for temporary credentials + +pollIntervalSeconds: 10 +``` + +With static credentials configured, you should see `using static AWS credentials` in the add-on logs. + +### Worker + +Skip the IAM role setup in [Step 3](#step-3-grant-the-worker-aws-access) and instead create an IAM user with `sqs:ReceiveMessage`, `sqs:DeleteMessage`, and `sqs:GetQueueAttributes` on your queue. Generate an access key. Then follow [Step 4](#step-4-configure-metric-based-autoscaling) to set up autoscaling. + +Set these environment variables under the worker service's **Environment** tab (use Porter's secret config for the key and secret): + +``` +AWS_REGION={AWS_REGION} +AWS_ACCESS_KEY_ID={ACCESS_KEY_ID} +AWS_SECRET_ACCESS_KEY={SECRET_ACCESS_KEY} +SQS_QUEUE_URL={QUEUE_URL} +``` From c7d6fdb5d918481a22a1ec6f803be9314ecbd3c6 Mon Sep 17 00:00:00 2001 From: cathy Date: Fri, 17 Apr 2026 15:29:37 -0500 Subject: [PATCH 4/4] cr --- applications/configure/sqs-autoscaling.mdx | 52 +--------------------- 1 file changed, 2 insertions(+), 50 deletions(-) diff --git a/applications/configure/sqs-autoscaling.mdx b/applications/configure/sqs-autoscaling.mdx index f65960a..a31ce49 100644 --- a/applications/configure/sqs-autoscaling.mdx +++ b/applications/configure/sqs-autoscaling.mdx @@ -11,10 +11,6 @@ This guide uses the [SQS Exporter](https://github.com/porter-dev/sqs-exporter) P This guide assumes you're running on EKS and uses [IRSA](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) (IAM Roles for Service Accounts) so the exporter and worker pick up short-lived, auto-rotated credentials from a pod-scoped IAM role — no long-lived keys to store or rotate. - -Not on EKS, or need static credentials? See the [appendix](#appendix-static-credentials) at the end of this guide. - - ## Prerequisites - An AWS account with an SQS queue @@ -186,16 +182,9 @@ Replace `your-queue-name` with the name portion of your SQS queue URL (e.g., for ## Scaling Latency -End-to-end scale-up latency depends on the metrics pipeline: - -| Step | Default | -|------|---------| -| SQS poll | 10s | -| Prometheus scrape | 15s | -| KEDA poll | 30s | -| HPA scale-up stabilization | 60s | +Scale-up isn't instant — expect on the order of a minute or two between messages arriving in your queue and new worker pods becoming ready. This latency comes from a combination of SQS polling, metrics scraping, and the stabilization period before the autoscaler commits to a scale-up. -The HPA scale-up stabilization window (60s) is the dominant factor. For queue-based workloads where fast scale-up matters, you can drop it to `0` via your worker service's **Settings** tab → **Helm overrides**: +For queue-based workloads where faster scale-up matters, you can shorten the stabilization window via your worker service's **Settings** tab → **Helm overrides**: ```yaml keda: @@ -209,40 +198,3 @@ keda: ``` Node provisioning is often the remaining bottleneck once the autoscaling pipeline is tuned. - -## Appendix: Static credentials - -Use this path if you're running on self-managed Kubernetes, need cross-account access where setting up an OIDC trust policy isn't feasible, or just want to run the exporter locally for development. On EKS, prefer IRSA — it avoids long-lived keys entirely. - -### Exporter addon - -Create an IAM user and attach the **`AmazonSQSReadOnlyAccess`** managed policy — it includes `sqs:GetQueueAttributes`, which is all the exporter needs. Generate an access key for the user. - -Follow [Step 2](#step-2-deploy-the-sqs-exporter) to add the addon in Porter, skipping the IAM role setup. Use these Helm values instead: - -```yaml -sqsQueueUrls: "https://sqs.us-east-1.amazonaws.com/123456789/your-queue-name" - -aws: - region: "us-east-1" - accessKeyId: "YOUR_ACCESS_KEY_ID" - secretAccessKey: "YOUR_SECRET_ACCESS_KEY" - sessionToken: "" # optional, only for temporary credentials - -pollIntervalSeconds: 10 -``` - -With static credentials configured, you should see `using static AWS credentials` in the add-on logs. - -### Worker - -Skip the IAM role setup in [Step 3](#step-3-grant-the-worker-aws-access) and instead create an IAM user with `sqs:ReceiveMessage`, `sqs:DeleteMessage`, and `sqs:GetQueueAttributes` on your queue. Generate an access key. Then follow [Step 4](#step-4-configure-metric-based-autoscaling) to set up autoscaling. - -Set these environment variables under the worker service's **Environment** tab (use Porter's secret config for the key and secret): - -``` -AWS_REGION={AWS_REGION} -AWS_ACCESS_KEY_ID={ACCESS_KEY_ID} -AWS_SECRET_ACCESS_KEY={SECRET_ACCESS_KEY} -SQS_QUEUE_URL={QUEUE_URL} -```