Skip to content

AWS.AppRunner reference

Source: src/AWS/AppRunner/AssociateCustomDomain.ts

Associate a custom domain with an App Runner Service from a Lambda (or other AWS runtime) — the multi-tenant SaaS “bring your own domain” flow: a customer adds their domain, the platform associates it at runtime and hands back the DNS validation records App Runner returns. Track validation with DescribeCustomDomains.

Provide AppRunner.AssociateCustomDomainHttp on the hosting function’s Effect to implement the binding.

const associateCustomDomain = yield* AppRunner.AssociateCustomDomain(service);
const { CustomDomain, DNSTarget } = yield* associateCustomDomain({
DomainName: "app.customer.com",
EnableWWWSubdomain: false,
});
// CustomDomain.CertificateValidationRecords -> CNAMEs the customer creates
// DNSTarget -> where the customer points app.customer.com

Source: src/AWS/AppRunner/AutoScalingConfiguration.ts

An AWS App Runner auto scaling configuration.

Auto scaling configurations are immutable revisions: changing maxConcurrency, minSize, or maxSize creates a new revision under the same name (the ARN and revision attributes change). A configuration can be shared across multiple App Runner services.

AutoScalingConfiguration: Creating an Auto Scaling Configuration

Section titled “AutoScalingConfiguration: Creating an Auto Scaling Configuration”
const scaling = yield* AppRunner.AutoScalingConfiguration("Scaling", {
maxConcurrency: 50,
minSize: 1,
maxSize: 3,
});

AutoScalingConfiguration: Using with an App Runner Service

Section titled “AutoScalingConfiguration: Using with an App Runner Service”
const service = yield* AppRunner.Service("Api", {
imageRepository: {
imageIdentifier: "public.ecr.aws/aws-containers/hello-app-runner:latest",
imageRepositoryType: "ECR_PUBLIC",
port: "8000",
},
autoScalingConfigurationArn: scaling.autoScalingConfigurationArn,
});

Source: src/AWS/AppRunner/DescribeCustomDomains.ts

Describe the custom domains associated with an App Runner Service from a Lambda (or other AWS runtime) — poll a domain’s certificate validation status (PENDING_VALIDATION -> SUCCESS) after AssociateCustomDomain, and read the DNSTarget customers point their DNS at.

Provide AppRunner.DescribeCustomDomainsHttp on the hosting function’s Effect to implement the binding.

const describeCustomDomains = yield* AppRunner.DescribeCustomDomains(service);
const { CustomDomains, DNSTarget } = yield* describeCustomDomains();
const domain = CustomDomains.find((d) => d.DomainName === "app.customer.com");
// domain?.Status -> "pending_certificate_dns_validation" | "active" | ...

Source: src/AWS/AppRunner/DisassociateCustomDomain.ts

Disassociate a custom domain from an App Runner Service from a Lambda (or other AWS runtime) — the teardown half of the multi-tenant SaaS domain flow when a customer removes their domain.

Provide AppRunner.DisassociateCustomDomainHttp on the hosting function’s Effect to implement the binding.

const disassociateCustomDomain =
yield* AppRunner.DisassociateCustomDomain(service);
yield* disassociateCustomDomain({ DomainName: "app.customer.com" });

Source: src/AWS/AppRunner/ListOperations.ts

List the operations that occurred on an App Runner Service (most recent first) from a Lambda (or other AWS runtime) — the tracking counterpart to the asynchronous StartDeployment, PauseService, and ResumeService calls, whose returned OperationIds appear here with Status transitions (IN_PROGRESS -> SUCCEEDED / FAILED / ROLLBACK_*).

Provide AppRunner.ListOperationsHttp on the hosting function’s Effect to implement the binding.

const listOperations = yield* AppRunner.ListOperations(service);
const { OperationSummaryList } = yield* listOperations({ MaxResults: 5 });
const deployment = OperationSummaryList?.find((op) => op.Id === operationId);
// deployment?.Status -> "IN_PROGRESS" | "SUCCEEDED" | ...

Source: src/AWS/AppRunner/ObservabilityConfiguration.ts

An AWS App Runner observability configuration — enables AWS X-Ray tracing for the App Runner services that reference it.

Observability configurations are immutable revisions: changing traceConfiguration creates a new revision under the same name (the ARN and revision attributes change). A configuration can be shared across multiple App Runner services.

ObservabilityConfiguration: Creating an Observability Configuration

Section titled “ObservabilityConfiguration: Creating an Observability Configuration”
const observability = yield* AppRunner.ObservabilityConfiguration("Tracing", {
traceConfiguration: { vendor: "AWSXRAY" },
});

ObservabilityConfiguration: Using with an App Runner Service

Section titled “ObservabilityConfiguration: Using with an App Runner Service”
const service = yield* AppRunner.Service("Api", {
imageRepository: {
imageIdentifier: "public.ecr.aws/aws-containers/hello-app-runner:latest",
imageRepositoryType: "ECR_PUBLIC",
port: "8000",
},
observabilityConfiguration: {
observabilityEnabled: true,
observabilityConfigurationArn:
observability.observabilityConfigurationArn,
},
});

Source: src/AWS/AppRunner/PauseService.ts

Pause an App Runner Service from a Lambda (or other AWS runtime). App Runner releases the service’s compute capacity (the endpoint stops serving) while keeping its configuration — e.g. a nightly scheduler that pauses non-production services to stop compute billing. The call is asynchronous; pair with ListOperations or ResumeService.

Provide AppRunner.PauseServiceHttp on the hosting function’s Effect to implement the binding.

const pauseService = yield* AppRunner.PauseService(service);
const { Service: paused } = yield* pauseService();
// paused.Status -> "OPERATION_IN_PROGRESS" (settles to "PAUSED")

Source: src/AWS/AppRunner/ResumeService.ts

Resume a paused App Runner Service from a Lambda (or other AWS runtime). App Runner re-provisions compute capacity and the endpoint starts serving again. The call is asynchronous; pair with ListOperations to track the returned OperationId.

Provide AppRunner.ResumeServiceHttp on the hosting function’s Effect to implement the binding.

const resumeService = yield* AppRunner.ResumeService(service);
const { Service: resumed } = yield* resumeService();
// resumed.Status -> "OPERATION_IN_PROGRESS" (settles to "RUNNING")

Source: src/AWS/AppRunner/Service.ts

An AWS App Runner service — the zero-infrastructure way to run a container behind an HTTPS endpoint: App Runner provisions, load-balances, scales, and patches the fleet for you. Service creation and deletion are asynchronous and take several minutes; the provider waits (bounded) for operations to settle.

Service is a Platform: alongside the low-level container-image form (imageRepository), it supports Effect-native implementations — an inline Effect HTTP program that Alchemy bundles, containerizes, pushes to a managed ECR repository, and deploys, provisioning the instance and ECR access roles automatically. Capability bindings (e.g. DynamoDB GetItem) attach IAM policy statements to the managed instance role.

Public ECR Image

const service = yield* AppRunner.Service("Hello", {
imageRepository: {
imageIdentifier: "public.ecr.aws/aws-containers/hello-app-runner:latest",
imageRepositoryType: "ECR_PUBLIC",
port: "8000",
},
instanceConfiguration: { cpu: "256", memory: "512" },
});
// service.serviceUrl -> "xxxxxxxx.us-west-2.awsapprunner.com"

Private ECR Image with Access Role

const service = yield* AppRunner.Service("Api", {
imageRepository: {
imageIdentifier: `${repository.repositoryUri}:latest`,
imageRepositoryType: "ECR",
port: "8080",
runtimeEnvironmentVariables: { NODE_ENV: "production" },
},
accessRoleArn: accessRole.roleArn,
autoDeploymentsEnabled: true,
});
export default class Api extends AppRunner.Service<Api>()(
"Api",
{
main: import.meta.url,
port: 3000,
instanceConfiguration: { cpu: "256", memory: "512" },
},
Effect.gen(function* () {
return {
fetch: Effect.gen(function* () {
const request = yield* HttpServerRequest;
return HttpServerResponse.text("hello from app runner");
}),
};
}),
) {}

main is bundled with rolldown at deploy time. Unused code is tree-shaken. effect, alchemy, and @distilled.cloud are marked pure so unused parts prune more aggressively. Your app is not marked pure.

Mark additional packages as pure

Only list packages with no top-level side effects.

{
main: import.meta.url,
build: {
pure: { packages: ["my-lib", "@my-scope/*"] },
},
}

Turn it off

{
main: import.meta.url,
build: { pure: false },
}
const service = yield* AppRunner.Service("Api", {
imageRepository: {
imageIdentifier: "public.ecr.aws/aws-containers/hello-app-runner:latest",
imageRepositoryType: "ECR_PUBLIC",
port: "8000",
},
autoScalingConfigurationArn: scaling.autoScalingConfigurationArn,
networkConfiguration: {
egressType: "VPC",
vpcConnectorArn: connector.vpcConnectorArn,
},
});

Source: src/AWS/AppRunner/StartDeployment.ts

Start a manual deployment of an App Runner Service from a Lambda (or other AWS runtime) — App Runner re-pulls the latest image (or commit) and rolls a new container fleet. The call is asynchronous; pair with ListOperations to track the returned OperationId to completion.

Provide AppRunner.StartDeploymentHttp on the hosting function’s Effect to implement the binding.

const startDeployment = yield* AppRunner.StartDeployment(service);
const { OperationId } = yield* startDeployment();

Source: src/AWS/AppRunner/VpcConnector.ts

An AWS App Runner VPC connector. Associating a connector with an App Runner service routes the service’s outbound traffic through your VPC (e.g. to reach an RDS database in private subnets).

VPC connectors are immutable: any change to subnets or security groups replaces the connector.

const connector = yield* AppRunner.VpcConnector("Egress", {
subnets: [subnetA.subnetId, subnetB.subnetId],
securityGroups: [egressSecurityGroup.securityGroupId],
});

VpcConnector: Routing a Service through the VPC

Section titled “VpcConnector: Routing a Service through the VPC”
const service = yield* AppRunner.Service("Api", {
imageRepository: {
imageIdentifier: image.imageUri,
imageRepositoryType: "ECR",
port: "8080",
},
accessRoleArn: accessRole.roleArn,
networkConfiguration: {
egressType: "VPC",
vpcConnectorArn: connector.vpcConnectorArn,
},
});