Deploy AWS App Runner Services

The aws:apprunner/service:Service resource, part of the Pulumi AWS provider, defines an App Runner service that deploys and runs containerized web applications from source code or container images. This guide focuses on three capabilities: GitHub repository deployment with build configuration, pre-built container image deployment, and X-Ray tracing integration.

App Runner services require either a GitHub connection (for code repositories) or container images in ECR. VPC egress requires a VPC connector; observability requires an ObservabilityConfiguration resource. The examples are intentionally small. Combine them with your own health checks, instance configuration, and auto scaling policies.

Deploy from a GitHub repository with build configuration

Teams building containerized applications from source often connect App Runner to a GitHub repository. App Runner clones the code, runs your build command, and deploys the resulting container.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.apprunner.Service("example", {
    serviceName: "example",
    sourceConfiguration: {
        authenticationConfiguration: {
            connectionArn: exampleAwsApprunnerConnection.arn,
        },
        codeRepository: {
            codeConfiguration: {
                codeConfigurationValues: {
                    buildCommand: "python setup.py develop",
                    port: "8000",
                    runtime: "PYTHON_3",
                    startCommand: "python runapp.py",
                },
                configurationSource: "API",
            },
            repositoryUrl: "https://github.com/example/my-example-python-app",
            sourceCodeVersion: {
                type: "BRANCH",
                value: "main",
            },
        },
    },
    networkConfiguration: {
        egressConfiguration: {
            egressType: "VPC",
            vpcConnectorArn: connector.arn,
        },
    },
    tags: {
        Name: "example-apprunner-service",
    },
});
import pulumi
import pulumi_aws as aws

example = aws.apprunner.Service("example",
    service_name="example",
    source_configuration={
        "authentication_configuration": {
            "connection_arn": example_aws_apprunner_connection["arn"],
        },
        "code_repository": {
            "code_configuration": {
                "code_configuration_values": {
                    "build_command": "python setup.py develop",
                    "port": "8000",
                    "runtime": "PYTHON_3",
                    "start_command": "python runapp.py",
                },
                "configuration_source": "API",
            },
            "repository_url": "https://github.com/example/my-example-python-app",
            "source_code_version": {
                "type": "BRANCH",
                "value": "main",
            },
        },
    },
    network_configuration={
        "egress_configuration": {
            "egress_type": "VPC",
            "vpc_connector_arn": connector["arn"],
        },
    },
    tags={
        "Name": "example-apprunner-service",
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/apprunner"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := apprunner.NewService(ctx, "example", &apprunner.ServiceArgs{
			ServiceName: pulumi.String("example"),
			SourceConfiguration: &apprunner.ServiceSourceConfigurationArgs{
				AuthenticationConfiguration: &apprunner.ServiceSourceConfigurationAuthenticationConfigurationArgs{
					ConnectionArn: pulumi.Any(exampleAwsApprunnerConnection.Arn),
				},
				CodeRepository: &apprunner.ServiceSourceConfigurationCodeRepositoryArgs{
					CodeConfiguration: &apprunner.ServiceSourceConfigurationCodeRepositoryCodeConfigurationArgs{
						CodeConfigurationValues: &apprunner.ServiceSourceConfigurationCodeRepositoryCodeConfigurationCodeConfigurationValuesArgs{
							BuildCommand: pulumi.String("python setup.py develop"),
							Port:         pulumi.String("8000"),
							Runtime:      pulumi.String("PYTHON_3"),
							StartCommand: pulumi.String("python runapp.py"),
						},
						ConfigurationSource: pulumi.String("API"),
					},
					RepositoryUrl: pulumi.String("https://github.com/example/my-example-python-app"),
					SourceCodeVersion: &apprunner.ServiceSourceConfigurationCodeRepositorySourceCodeVersionArgs{
						Type:  pulumi.String("BRANCH"),
						Value: pulumi.String("main"),
					},
				},
			},
			NetworkConfiguration: &apprunner.ServiceNetworkConfigurationArgs{
				EgressConfiguration: &apprunner.ServiceNetworkConfigurationEgressConfigurationArgs{
					EgressType:      pulumi.String("VPC"),
					VpcConnectorArn: pulumi.Any(connector.Arn),
				},
			},
			Tags: pulumi.StringMap{
				"Name": pulumi.String("example-apprunner-service"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.AppRunner.Service("example", new()
    {
        ServiceName = "example",
        SourceConfiguration = new Aws.AppRunner.Inputs.ServiceSourceConfigurationArgs
        {
            AuthenticationConfiguration = new Aws.AppRunner.Inputs.ServiceSourceConfigurationAuthenticationConfigurationArgs
            {
                ConnectionArn = exampleAwsApprunnerConnection.Arn,
            },
            CodeRepository = new Aws.AppRunner.Inputs.ServiceSourceConfigurationCodeRepositoryArgs
            {
                CodeConfiguration = new Aws.AppRunner.Inputs.ServiceSourceConfigurationCodeRepositoryCodeConfigurationArgs
                {
                    CodeConfigurationValues = new Aws.AppRunner.Inputs.ServiceSourceConfigurationCodeRepositoryCodeConfigurationCodeConfigurationValuesArgs
                    {
                        BuildCommand = "python setup.py develop",
                        Port = "8000",
                        Runtime = "PYTHON_3",
                        StartCommand = "python runapp.py",
                    },
                    ConfigurationSource = "API",
                },
                RepositoryUrl = "https://github.com/example/my-example-python-app",
                SourceCodeVersion = new Aws.AppRunner.Inputs.ServiceSourceConfigurationCodeRepositorySourceCodeVersionArgs
                {
                    Type = "BRANCH",
                    Value = "main",
                },
            },
        },
        NetworkConfiguration = new Aws.AppRunner.Inputs.ServiceNetworkConfigurationArgs
        {
            EgressConfiguration = new Aws.AppRunner.Inputs.ServiceNetworkConfigurationEgressConfigurationArgs
            {
                EgressType = "VPC",
                VpcConnectorArn = connector.Arn,
            },
        },
        Tags = 
        {
            { "Name", "example-apprunner-service" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.apprunner.Service;
import com.pulumi.aws.apprunner.ServiceArgs;
import com.pulumi.aws.apprunner.inputs.ServiceSourceConfigurationArgs;
import com.pulumi.aws.apprunner.inputs.ServiceSourceConfigurationAuthenticationConfigurationArgs;
import com.pulumi.aws.apprunner.inputs.ServiceSourceConfigurationCodeRepositoryArgs;
import com.pulumi.aws.apprunner.inputs.ServiceSourceConfigurationCodeRepositoryCodeConfigurationArgs;
import com.pulumi.aws.apprunner.inputs.ServiceSourceConfigurationCodeRepositoryCodeConfigurationCodeConfigurationValuesArgs;
import com.pulumi.aws.apprunner.inputs.ServiceSourceConfigurationCodeRepositorySourceCodeVersionArgs;
import com.pulumi.aws.apprunner.inputs.ServiceNetworkConfigurationArgs;
import com.pulumi.aws.apprunner.inputs.ServiceNetworkConfigurationEgressConfigurationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var example = new Service("example", ServiceArgs.builder()
            .serviceName("example")
            .sourceConfiguration(ServiceSourceConfigurationArgs.builder()
                .authenticationConfiguration(ServiceSourceConfigurationAuthenticationConfigurationArgs.builder()
                    .connectionArn(exampleAwsApprunnerConnection.arn())
                    .build())
                .codeRepository(ServiceSourceConfigurationCodeRepositoryArgs.builder()
                    .codeConfiguration(ServiceSourceConfigurationCodeRepositoryCodeConfigurationArgs.builder()
                        .codeConfigurationValues(ServiceSourceConfigurationCodeRepositoryCodeConfigurationCodeConfigurationValuesArgs.builder()
                            .buildCommand("python setup.py develop")
                            .port("8000")
                            .runtime("PYTHON_3")
                            .startCommand("python runapp.py")
                            .build())
                        .configurationSource("API")
                        .build())
                    .repositoryUrl("https://github.com/example/my-example-python-app")
                    .sourceCodeVersion(ServiceSourceConfigurationCodeRepositorySourceCodeVersionArgs.builder()
                        .type("BRANCH")
                        .value("main")
                        .build())
                    .build())
                .build())
            .networkConfiguration(ServiceNetworkConfigurationArgs.builder()
                .egressConfiguration(ServiceNetworkConfigurationEgressConfigurationArgs.builder()
                    .egressType("VPC")
                    .vpcConnectorArn(connector.arn())
                    .build())
                .build())
            .tags(Map.of("Name", "example-apprunner-service"))
            .build());

    }
}
resources:
  example:
    type: aws:apprunner:Service
    properties:
      serviceName: example
      sourceConfiguration:
        authenticationConfiguration:
          connectionArn: ${exampleAwsApprunnerConnection.arn}
        codeRepository:
          codeConfiguration:
            codeConfigurationValues:
              buildCommand: python setup.py develop
              port: '8000'
              runtime: PYTHON_3
              startCommand: python runapp.py
            configurationSource: API
          repositoryUrl: https://github.com/example/my-example-python-app
          sourceCodeVersion:
            type: BRANCH
            value: main
      networkConfiguration:
        egressConfiguration:
          egressType: VPC
          vpcConnectorArn: ${connector.arn}
      tags:
        Name: example-apprunner-service

The codeRepository block specifies the repository URL and branch to track. The codeConfigurationValues define how App Runner builds and runs your application: buildCommand installs dependencies, startCommand launches the server, runtime selects the language environment, and port exposes the HTTP endpoint. The authenticationConfiguration references a GitHub connection that grants App Runner access to private repositories. The networkConfiguration routes outbound traffic through a VPC connector, enabling access to RDS or internal services.

Deploy from a pre-built container image

Applications with existing container images can skip the build step by pointing App Runner at an ECR or public registry.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.apprunner.Service("example", {
    serviceName: "example",
    sourceConfiguration: {
        imageRepository: {
            imageConfiguration: {
                port: "8000",
            },
            imageIdentifier: "public.ecr.aws/aws-containers/hello-app-runner:latest",
            imageRepositoryType: "ECR_PUBLIC",
        },
        autoDeploymentsEnabled: false,
    },
    tags: {
        Name: "example-apprunner-service",
    },
});
import pulumi
import pulumi_aws as aws

example = aws.apprunner.Service("example",
    service_name="example",
    source_configuration={
        "image_repository": {
            "image_configuration": {
                "port": "8000",
            },
            "image_identifier": "public.ecr.aws/aws-containers/hello-app-runner:latest",
            "image_repository_type": "ECR_PUBLIC",
        },
        "auto_deployments_enabled": False,
    },
    tags={
        "Name": "example-apprunner-service",
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/apprunner"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := apprunner.NewService(ctx, "example", &apprunner.ServiceArgs{
			ServiceName: pulumi.String("example"),
			SourceConfiguration: &apprunner.ServiceSourceConfigurationArgs{
				ImageRepository: &apprunner.ServiceSourceConfigurationImageRepositoryArgs{
					ImageConfiguration: &apprunner.ServiceSourceConfigurationImageRepositoryImageConfigurationArgs{
						Port: pulumi.String("8000"),
					},
					ImageIdentifier:     pulumi.String("public.ecr.aws/aws-containers/hello-app-runner:latest"),
					ImageRepositoryType: pulumi.String("ECR_PUBLIC"),
				},
				AutoDeploymentsEnabled: pulumi.Bool(false),
			},
			Tags: pulumi.StringMap{
				"Name": pulumi.String("example-apprunner-service"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.AppRunner.Service("example", new()
    {
        ServiceName = "example",
        SourceConfiguration = new Aws.AppRunner.Inputs.ServiceSourceConfigurationArgs
        {
            ImageRepository = new Aws.AppRunner.Inputs.ServiceSourceConfigurationImageRepositoryArgs
            {
                ImageConfiguration = new Aws.AppRunner.Inputs.ServiceSourceConfigurationImageRepositoryImageConfigurationArgs
                {
                    Port = "8000",
                },
                ImageIdentifier = "public.ecr.aws/aws-containers/hello-app-runner:latest",
                ImageRepositoryType = "ECR_PUBLIC",
            },
            AutoDeploymentsEnabled = false,
        },
        Tags = 
        {
            { "Name", "example-apprunner-service" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.apprunner.Service;
import com.pulumi.aws.apprunner.ServiceArgs;
import com.pulumi.aws.apprunner.inputs.ServiceSourceConfigurationArgs;
import com.pulumi.aws.apprunner.inputs.ServiceSourceConfigurationImageRepositoryArgs;
import com.pulumi.aws.apprunner.inputs.ServiceSourceConfigurationImageRepositoryImageConfigurationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var example = new Service("example", ServiceArgs.builder()
            .serviceName("example")
            .sourceConfiguration(ServiceSourceConfigurationArgs.builder()
                .imageRepository(ServiceSourceConfigurationImageRepositoryArgs.builder()
                    .imageConfiguration(ServiceSourceConfigurationImageRepositoryImageConfigurationArgs.builder()
                        .port("8000")
                        .build())
                    .imageIdentifier("public.ecr.aws/aws-containers/hello-app-runner:latest")
                    .imageRepositoryType("ECR_PUBLIC")
                    .build())
                .autoDeploymentsEnabled(false)
                .build())
            .tags(Map.of("Name", "example-apprunner-service"))
            .build());

    }
}
resources:
  example:
    type: aws:apprunner:Service
    properties:
      serviceName: example
      sourceConfiguration:
        imageRepository:
          imageConfiguration:
            port: '8000'
          imageIdentifier: public.ecr.aws/aws-containers/hello-app-runner:latest
          imageRepositoryType: ECR_PUBLIC
        autoDeploymentsEnabled: false
      tags:
        Name: example-apprunner-service

The imageRepository block replaces codeRepository when deploying pre-built containers. The imageIdentifier points to your container image (ECR Public shown here; private ECR and Docker Hub are also supported). The imageRepositoryType tells App Runner which registry authentication to use. Setting autoDeploymentsEnabled to false prevents automatic redeployment when the image tag updates; set it to true for continuous deployment.

Enable X-Ray tracing for request monitoring

Production services often need distributed tracing to diagnose latency and errors across service boundaries.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const exampleObservabilityConfiguration = new aws.apprunner.ObservabilityConfiguration("example", {
    observabilityConfigurationName: "example",
    traceConfiguration: {
        vendor: "AWSXRAY",
    },
});
const example = new aws.apprunner.Service("example", {
    serviceName: "example",
    observabilityConfiguration: {
        observabilityConfigurationArn: exampleObservabilityConfiguration.arn,
        observabilityEnabled: true,
    },
    sourceConfiguration: {
        imageRepository: {
            imageConfiguration: {
                port: "8000",
            },
            imageIdentifier: "public.ecr.aws/aws-containers/hello-app-runner:latest",
            imageRepositoryType: "ECR_PUBLIC",
        },
        autoDeploymentsEnabled: false,
    },
    tags: {
        Name: "example-apprunner-service",
    },
});
import pulumi
import pulumi_aws as aws

example_observability_configuration = aws.apprunner.ObservabilityConfiguration("example",
    observability_configuration_name="example",
    trace_configuration={
        "vendor": "AWSXRAY",
    })
example = aws.apprunner.Service("example",
    service_name="example",
    observability_configuration={
        "observability_configuration_arn": example_observability_configuration.arn,
        "observability_enabled": True,
    },
    source_configuration={
        "image_repository": {
            "image_configuration": {
                "port": "8000",
            },
            "image_identifier": "public.ecr.aws/aws-containers/hello-app-runner:latest",
            "image_repository_type": "ECR_PUBLIC",
        },
        "auto_deployments_enabled": False,
    },
    tags={
        "Name": "example-apprunner-service",
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/apprunner"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		exampleObservabilityConfiguration, err := apprunner.NewObservabilityConfiguration(ctx, "example", &apprunner.ObservabilityConfigurationArgs{
			ObservabilityConfigurationName: pulumi.String("example"),
			TraceConfiguration: &apprunner.ObservabilityConfigurationTraceConfigurationArgs{
				Vendor: pulumi.String("AWSXRAY"),
			},
		})
		if err != nil {
			return err
		}
		_, err = apprunner.NewService(ctx, "example", &apprunner.ServiceArgs{
			ServiceName: pulumi.String("example"),
			ObservabilityConfiguration: &apprunner.ServiceObservabilityConfigurationArgs{
				ObservabilityConfigurationArn: exampleObservabilityConfiguration.Arn,
				ObservabilityEnabled:          pulumi.Bool(true),
			},
			SourceConfiguration: &apprunner.ServiceSourceConfigurationArgs{
				ImageRepository: &apprunner.ServiceSourceConfigurationImageRepositoryArgs{
					ImageConfiguration: &apprunner.ServiceSourceConfigurationImageRepositoryImageConfigurationArgs{
						Port: pulumi.String("8000"),
					},
					ImageIdentifier:     pulumi.String("public.ecr.aws/aws-containers/hello-app-runner:latest"),
					ImageRepositoryType: pulumi.String("ECR_PUBLIC"),
				},
				AutoDeploymentsEnabled: pulumi.Bool(false),
			},
			Tags: pulumi.StringMap{
				"Name": pulumi.String("example-apprunner-service"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var exampleObservabilityConfiguration = new Aws.AppRunner.ObservabilityConfiguration("example", new()
    {
        ObservabilityConfigurationName = "example",
        TraceConfiguration = new Aws.AppRunner.Inputs.ObservabilityConfigurationTraceConfigurationArgs
        {
            Vendor = "AWSXRAY",
        },
    });

    var example = new Aws.AppRunner.Service("example", new()
    {
        ServiceName = "example",
        ObservabilityConfiguration = new Aws.AppRunner.Inputs.ServiceObservabilityConfigurationArgs
        {
            ObservabilityConfigurationArn = exampleObservabilityConfiguration.Arn,
            ObservabilityEnabled = true,
        },
        SourceConfiguration = new Aws.AppRunner.Inputs.ServiceSourceConfigurationArgs
        {
            ImageRepository = new Aws.AppRunner.Inputs.ServiceSourceConfigurationImageRepositoryArgs
            {
                ImageConfiguration = new Aws.AppRunner.Inputs.ServiceSourceConfigurationImageRepositoryImageConfigurationArgs
                {
                    Port = "8000",
                },
                ImageIdentifier = "public.ecr.aws/aws-containers/hello-app-runner:latest",
                ImageRepositoryType = "ECR_PUBLIC",
            },
            AutoDeploymentsEnabled = false,
        },
        Tags = 
        {
            { "Name", "example-apprunner-service" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.apprunner.ObservabilityConfiguration;
import com.pulumi.aws.apprunner.ObservabilityConfigurationArgs;
import com.pulumi.aws.apprunner.inputs.ObservabilityConfigurationTraceConfigurationArgs;
import com.pulumi.aws.apprunner.Service;
import com.pulumi.aws.apprunner.ServiceArgs;
import com.pulumi.aws.apprunner.inputs.ServiceObservabilityConfigurationArgs;
import com.pulumi.aws.apprunner.inputs.ServiceSourceConfigurationArgs;
import com.pulumi.aws.apprunner.inputs.ServiceSourceConfigurationImageRepositoryArgs;
import com.pulumi.aws.apprunner.inputs.ServiceSourceConfigurationImageRepositoryImageConfigurationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var exampleObservabilityConfiguration = new ObservabilityConfiguration("exampleObservabilityConfiguration", ObservabilityConfigurationArgs.builder()
            .observabilityConfigurationName("example")
            .traceConfiguration(ObservabilityConfigurationTraceConfigurationArgs.builder()
                .vendor("AWSXRAY")
                .build())
            .build());

        var example = new Service("example", ServiceArgs.builder()
            .serviceName("example")
            .observabilityConfiguration(ServiceObservabilityConfigurationArgs.builder()
                .observabilityConfigurationArn(exampleObservabilityConfiguration.arn())
                .observabilityEnabled(true)
                .build())
            .sourceConfiguration(ServiceSourceConfigurationArgs.builder()
                .imageRepository(ServiceSourceConfigurationImageRepositoryArgs.builder()
                    .imageConfiguration(ServiceSourceConfigurationImageRepositoryImageConfigurationArgs.builder()
                        .port("8000")
                        .build())
                    .imageIdentifier("public.ecr.aws/aws-containers/hello-app-runner:latest")
                    .imageRepositoryType("ECR_PUBLIC")
                    .build())
                .autoDeploymentsEnabled(false)
                .build())
            .tags(Map.of("Name", "example-apprunner-service"))
            .build());

    }
}
resources:
  example:
    type: aws:apprunner:Service
    properties:
      serviceName: example
      observabilityConfiguration:
        observabilityConfigurationArn: ${exampleObservabilityConfiguration.arn}
        observabilityEnabled: true
      sourceConfiguration:
        imageRepository:
          imageConfiguration:
            port: '8000'
          imageIdentifier: public.ecr.aws/aws-containers/hello-app-runner:latest
          imageRepositoryType: ECR_PUBLIC
        autoDeploymentsEnabled: false
      tags:
        Name: example-apprunner-service
  exampleObservabilityConfiguration:
    type: aws:apprunner:ObservabilityConfiguration
    name: example
    properties:
      observabilityConfigurationName: example
      traceConfiguration:
        vendor: AWSXRAY

The observabilityConfiguration block enables AWS X-Ray tracing by referencing an ObservabilityConfiguration resource. The traceConfiguration vendor must be set to “AWSXRAY”. Once enabled, App Runner automatically instruments incoming requests and propagates trace context to downstream services, allowing you to visualize request flows in the X-Ray console.

Beyond these examples

These snippets focus on specific App Runner service features: code and image repository sources, VPC egress configuration, and X-Ray distributed tracing. They’re intentionally minimal rather than full application deployments.

The examples may reference pre-existing infrastructure such as GitHub connections (for code repositories), VPC connectors (for private egress), and ECR repositories or public container images. They focus on configuring the service rather than provisioning everything around it.

To keep things focused, common service patterns are omitted, including:

  • Health check customization (healthCheckConfiguration)
  • Instance sizing and IAM roles (instanceConfiguration)
  • Auto scaling limits (autoScalingConfigurationArn)
  • Custom encryption keys (encryptionConfiguration)

These omissions are intentional: the goal is to illustrate how each App Runner feature is wired, not provide drop-in production modules. See the App Runner Service resource reference for all available configuration options.

Let's deploy AWS App Runner Services

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Deployment Sources & Configuration
What are my deployment source options for App Runner?
You can deploy from either a code repository or an image repository. Code repositories require build configuration (buildCommand, startCommand, runtime), while image repositories use pre-built container images.
Do I need authentication for all source types?
Code repositories require authenticationConfiguration with a connectionArn. Public ECR images (ECR_PUBLIC) don’t require authentication, as shown in the image repository example.
What does autoDeploymentsEnabled control?
It controls whether App Runner automatically deploys new versions when your source changes. The image repository example sets it to false to require manual deployments.
Configuration & Immutability
What properties can't be changed after creating the service?
serviceName and encryptionConfiguration are immutable. Changing these requires replacing the service.
What happens if I don't specify a region?
The service defaults to the region configured in your Pulumi provider.
Do I need to provide an auto-scaling configuration?
No, autoScalingConfigurationArn is required but App Runner uses the latest default auto-scaling configuration if you don’t provide one.
Networking & Access
How do I connect my service to VPC resources?
Configure networkConfiguration.egressConfiguration with egressType: "VPC" and a vpcConnectorArn, as shown in the code repository example.
What URL does my service get?
App Runner generates a serviceUrl subdomain that you can use to access your web application.
Monitoring & Observability
How do I enable observability for my service?
Create an aws.apprunner.ObservabilityConfiguration resource, then reference its ARN in your service’s observabilityConfiguration with observabilityEnabled: true.

Using a different cloud?

Explore compute guides for other cloud providers: