Deploy Azure Spring Cloud Services

The azure-native:appplatform:Service resource, part of the Pulumi Azure Native provider, provisions the Azure Spring Apps service instance: its tier, region, and platform-level configuration. This guide focuses on three capabilities: tier selection and maintenance scheduling, Container Apps integration, and VNet injection for private connectivity.

Azure Spring Apps services require a resource group and may reference virtual networks, Container Apps environments, or marketplace resources. The examples are intentionally small. Combine them with your own application deployments, custom domains, and monitoring configuration.

Create a Standard tier service with maintenance windows

Most deployments begin with a Standard tier service that provides managed Spring Boot hosting, with scheduled maintenance windows to control platform updates.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const service = new azure_native.appplatform.Service("service", {
    location: "eastus",
    properties: {
        maintenanceScheduleConfiguration: {
            day: azure_native.appplatform.WeekDay.Sunday,
            frequency: "Weekly",
            hour: 10,
        },
    },
    resourceGroupName: "myResourceGroup",
    serviceName: "myservice",
    sku: {
        name: "S0",
        tier: "Standard",
    },
    tags: {
        key1: "value1",
    },
});
import pulumi
import pulumi_azure_native as azure_native

service = azure_native.appplatform.Service("service",
    location="eastus",
    properties={
        "maintenance_schedule_configuration": {
            "day": azure_native.appplatform.WeekDay.SUNDAY,
            "frequency": "Weekly",
            "hour": 10,
        },
    },
    resource_group_name="myResourceGroup",
    service_name="myservice",
    sku={
        "name": "S0",
        "tier": "Standard",
    },
    tags={
        "key1": "value1",
    })
package main

import (
	appplatform "github.com/pulumi/pulumi-azure-native-sdk/appplatform/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := appplatform.NewService(ctx, "service", &appplatform.ServiceArgs{
			Location: pulumi.String("eastus"),
			Properties: &appplatform.ClusterResourcePropertiesArgs{
				MaintenanceScheduleConfiguration: &appplatform.WeeklyMaintenanceScheduleConfigurationArgs{
					Day:       pulumi.String(appplatform.WeekDaySunday),
					Frequency: pulumi.String("Weekly"),
					Hour:      pulumi.Int(10),
				},
			},
			ResourceGroupName: pulumi.String("myResourceGroup"),
			ServiceName:       pulumi.String("myservice"),
			Sku: &appplatform.SkuArgs{
				Name: pulumi.String("S0"),
				Tier: pulumi.String("Standard"),
			},
			Tags: pulumi.StringMap{
				"key1": pulumi.String("value1"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var service = new AzureNative.AppPlatform.Service("service", new()
    {
        Location = "eastus",
        Properties = new AzureNative.AppPlatform.Inputs.ClusterResourcePropertiesArgs
        {
            MaintenanceScheduleConfiguration = new AzureNative.AppPlatform.Inputs.WeeklyMaintenanceScheduleConfigurationArgs
            {
                Day = AzureNative.AppPlatform.WeekDay.Sunday,
                Frequency = "Weekly",
                Hour = 10,
            },
        },
        ResourceGroupName = "myResourceGroup",
        ServiceName = "myservice",
        Sku = new AzureNative.AppPlatform.Inputs.SkuArgs
        {
            Name = "S0",
            Tier = "Standard",
        },
        Tags = 
        {
            { "key1", "value1" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.appplatform.Service;
import com.pulumi.azurenative.appplatform.ServiceArgs;
import com.pulumi.azurenative.appplatform.inputs.ClusterResourcePropertiesArgs;
import com.pulumi.azurenative.appplatform.inputs.WeeklyMaintenanceScheduleConfigurationArgs;
import com.pulumi.azurenative.appplatform.inputs.SkuArgs;
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 service = new Service("service", ServiceArgs.builder()
            .location("eastus")
            .properties(ClusterResourcePropertiesArgs.builder()
                .maintenanceScheduleConfiguration(Map.ofEntries(
                    Map.entry("day", "Sunday"),
                    Map.entry("frequency", "Weekly"),
                    Map.entry("hour", 10)
                ))
                .build())
            .resourceGroupName("myResourceGroup")
            .serviceName("myservice")
            .sku(SkuArgs.builder()
                .name("S0")
                .tier("Standard")
                .build())
            .tags(Map.of("key1", "value1"))
            .build());

    }
}
resources:
  service:
    type: azure-native:appplatform:Service
    properties:
      location: eastus
      properties:
        maintenanceScheduleConfiguration:
          day: Sunday
          frequency: Weekly
          hour: 10
      resourceGroupName: myResourceGroup
      serviceName: myservice
      sku:
        name: S0
        tier: Standard
      tags:
        key1: value1

The sku property sets the service tier and capacity. The maintenanceScheduleConfiguration schedules when Azure applies platform updates, specifying day of week and hour. Without this configuration, Azure schedules maintenance automatically.

Deploy to Container Apps managed environments

The StandardGen2 tier integrates with Azure Container Apps managed environments, allowing Spring Apps to share infrastructure with containerized workloads.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const service = new azure_native.appplatform.Service("service", {
    location: "eastus",
    properties: {
        managedEnvironmentId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.App/managedEnvironments/myenvironment",
    },
    resourceGroupName: "myResourceGroup",
    serviceName: "myservice",
    sku: {
        name: "S0",
        tier: "StandardGen2",
    },
    tags: {
        key1: "value1",
    },
});
import pulumi
import pulumi_azure_native as azure_native

service = azure_native.appplatform.Service("service",
    location="eastus",
    properties={
        "managed_environment_id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.App/managedEnvironments/myenvironment",
    },
    resource_group_name="myResourceGroup",
    service_name="myservice",
    sku={
        "name": "S0",
        "tier": "StandardGen2",
    },
    tags={
        "key1": "value1",
    })
package main

import (
	appplatform "github.com/pulumi/pulumi-azure-native-sdk/appplatform/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := appplatform.NewService(ctx, "service", &appplatform.ServiceArgs{
			Location: pulumi.String("eastus"),
			Properties: &appplatform.ClusterResourcePropertiesArgs{
				ManagedEnvironmentId: pulumi.String("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.App/managedEnvironments/myenvironment"),
			},
			ResourceGroupName: pulumi.String("myResourceGroup"),
			ServiceName:       pulumi.String("myservice"),
			Sku: &appplatform.SkuArgs{
				Name: pulumi.String("S0"),
				Tier: pulumi.String("StandardGen2"),
			},
			Tags: pulumi.StringMap{
				"key1": pulumi.String("value1"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var service = new AzureNative.AppPlatform.Service("service", new()
    {
        Location = "eastus",
        Properties = new AzureNative.AppPlatform.Inputs.ClusterResourcePropertiesArgs
        {
            ManagedEnvironmentId = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.App/managedEnvironments/myenvironment",
        },
        ResourceGroupName = "myResourceGroup",
        ServiceName = "myservice",
        Sku = new AzureNative.AppPlatform.Inputs.SkuArgs
        {
            Name = "S0",
            Tier = "StandardGen2",
        },
        Tags = 
        {
            { "key1", "value1" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.appplatform.Service;
import com.pulumi.azurenative.appplatform.ServiceArgs;
import com.pulumi.azurenative.appplatform.inputs.ClusterResourcePropertiesArgs;
import com.pulumi.azurenative.appplatform.inputs.SkuArgs;
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 service = new Service("service", ServiceArgs.builder()
            .location("eastus")
            .properties(ClusterResourcePropertiesArgs.builder()
                .managedEnvironmentId("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.App/managedEnvironments/myenvironment")
                .build())
            .resourceGroupName("myResourceGroup")
            .serviceName("myservice")
            .sku(SkuArgs.builder()
                .name("S0")
                .tier("StandardGen2")
                .build())
            .tags(Map.of("key1", "value1"))
            .build());

    }
}
resources:
  service:
    type: azure-native:appplatform:Service
    properties:
      location: eastus
      properties:
        managedEnvironmentId: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.App/managedEnvironments/myenvironment
      resourceGroupName: myResourceGroup
      serviceName: myservice
      sku:
        name: S0
        tier: StandardGen2
      tags:
        key1: value1

The managedEnvironmentId property connects the service to an existing Container Apps environment. The StandardGen2 tier runs on Container Apps infrastructure rather than dedicated Spring Apps compute. This enables resource sharing and unified networking with other containerized applications.

Provision Enterprise tier with VMware Tanzu

Enterprise tier services integrate VMware Tanzu components for advanced Spring application management.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const service = new azure_native.appplatform.Service("service", {
    location: "eastus",
    properties: {
        marketplaceResource: {
            plan: "tanzu-asc-ent-mtr",
            product: "azure-spring-cloud-vmware-tanzu-2",
            publisher: "vmware-inc",
        },
    },
    resourceGroupName: "myResourceGroup",
    serviceName: "myservice",
    sku: {
        name: "E0",
        tier: "Enterprise",
    },
    tags: {
        key1: "value1",
    },
});
import pulumi
import pulumi_azure_native as azure_native

service = azure_native.appplatform.Service("service",
    location="eastus",
    properties={
        "marketplace_resource": {
            "plan": "tanzu-asc-ent-mtr",
            "product": "azure-spring-cloud-vmware-tanzu-2",
            "publisher": "vmware-inc",
        },
    },
    resource_group_name="myResourceGroup",
    service_name="myservice",
    sku={
        "name": "E0",
        "tier": "Enterprise",
    },
    tags={
        "key1": "value1",
    })
package main

import (
	appplatform "github.com/pulumi/pulumi-azure-native-sdk/appplatform/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := appplatform.NewService(ctx, "service", &appplatform.ServiceArgs{
			Location: pulumi.String("eastus"),
			Properties: &appplatform.ClusterResourcePropertiesArgs{
				MarketplaceResource: &appplatform.MarketplaceResourceArgs{
					Plan:      pulumi.String("tanzu-asc-ent-mtr"),
					Product:   pulumi.String("azure-spring-cloud-vmware-tanzu-2"),
					Publisher: pulumi.String("vmware-inc"),
				},
			},
			ResourceGroupName: pulumi.String("myResourceGroup"),
			ServiceName:       pulumi.String("myservice"),
			Sku: &appplatform.SkuArgs{
				Name: pulumi.String("E0"),
				Tier: pulumi.String("Enterprise"),
			},
			Tags: pulumi.StringMap{
				"key1": pulumi.String("value1"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var service = new AzureNative.AppPlatform.Service("service", new()
    {
        Location = "eastus",
        Properties = new AzureNative.AppPlatform.Inputs.ClusterResourcePropertiesArgs
        {
            MarketplaceResource = new AzureNative.AppPlatform.Inputs.MarketplaceResourceArgs
            {
                Plan = "tanzu-asc-ent-mtr",
                Product = "azure-spring-cloud-vmware-tanzu-2",
                Publisher = "vmware-inc",
            },
        },
        ResourceGroupName = "myResourceGroup",
        ServiceName = "myservice",
        Sku = new AzureNative.AppPlatform.Inputs.SkuArgs
        {
            Name = "E0",
            Tier = "Enterprise",
        },
        Tags = 
        {
            { "key1", "value1" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.appplatform.Service;
import com.pulumi.azurenative.appplatform.ServiceArgs;
import com.pulumi.azurenative.appplatform.inputs.ClusterResourcePropertiesArgs;
import com.pulumi.azurenative.appplatform.inputs.MarketplaceResourceArgs;
import com.pulumi.azurenative.appplatform.inputs.SkuArgs;
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 service = new Service("service", ServiceArgs.builder()
            .location("eastus")
            .properties(ClusterResourcePropertiesArgs.builder()
                .marketplaceResource(MarketplaceResourceArgs.builder()
                    .plan("tanzu-asc-ent-mtr")
                    .product("azure-spring-cloud-vmware-tanzu-2")
                    .publisher("vmware-inc")
                    .build())
                .build())
            .resourceGroupName("myResourceGroup")
            .serviceName("myservice")
            .sku(SkuArgs.builder()
                .name("E0")
                .tier("Enterprise")
                .build())
            .tags(Map.of("key1", "value1"))
            .build());

    }
}
resources:
  service:
    type: azure-native:appplatform:Service
    properties:
      location: eastus
      properties:
        marketplaceResource:
          plan: tanzu-asc-ent-mtr
          product: azure-spring-cloud-vmware-tanzu-2
          publisher: vmware-inc
      resourceGroupName: myResourceGroup
      serviceName: myservice
      sku:
        name: E0
        tier: Enterprise
      tags:
        key1: value1

The marketplaceResource property configures the VMware Tanzu marketplace offering. The plan, product, and publisher identify the specific Tanzu components to provision. Enterprise tier provides Tanzu Build Service for container image creation and Application Configuration Service for centralized config management.

Inject service into virtual network subnets

Applications needing private connectivity to databases or internal services require VNet injection to place the service runtime and apps in dedicated subnets.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const service = new azure_native.appplatform.Service("service", {
    location: "eastus",
    properties: {
        networkProfile: {
            appNetworkResourceGroup: "my-app-network-rg",
            appSubnetId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork/subnets/apps",
            ingressConfig: {
                readTimeoutInSeconds: 300,
            },
            serviceCidr: "10.8.0.0/16,10.244.0.0/16,10.245.0.1/16",
            serviceRuntimeNetworkResourceGroup: "my-service-runtime-network-rg",
            serviceRuntimeSubnetId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork/subnets/serviceRuntime",
        },
        vnetAddons: {
            dataPlanePublicEndpoint: true,
            logStreamPublicEndpoint: true,
        },
    },
    resourceGroupName: "myResourceGroup",
    serviceName: "myservice",
    sku: {
        name: "S0",
        tier: "Standard",
    },
    tags: {
        key1: "value1",
    },
});
import pulumi
import pulumi_azure_native as azure_native

service = azure_native.appplatform.Service("service",
    location="eastus",
    properties={
        "network_profile": {
            "app_network_resource_group": "my-app-network-rg",
            "app_subnet_id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork/subnets/apps",
            "ingress_config": {
                "read_timeout_in_seconds": 300,
            },
            "service_cidr": "10.8.0.0/16,10.244.0.0/16,10.245.0.1/16",
            "service_runtime_network_resource_group": "my-service-runtime-network-rg",
            "service_runtime_subnet_id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork/subnets/serviceRuntime",
        },
        "vnet_addons": {
            "data_plane_public_endpoint": True,
            "log_stream_public_endpoint": True,
        },
    },
    resource_group_name="myResourceGroup",
    service_name="myservice",
    sku={
        "name": "S0",
        "tier": "Standard",
    },
    tags={
        "key1": "value1",
    })
package main

import (
	appplatform "github.com/pulumi/pulumi-azure-native-sdk/appplatform/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := appplatform.NewService(ctx, "service", &appplatform.ServiceArgs{
			Location: pulumi.String("eastus"),
			Properties: &appplatform.ClusterResourcePropertiesArgs{
				NetworkProfile: &appplatform.NetworkProfileArgs{
					AppNetworkResourceGroup: pulumi.String("my-app-network-rg"),
					AppSubnetId:             pulumi.String("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork/subnets/apps"),
					IngressConfig: &appplatform.IngressConfigArgs{
						ReadTimeoutInSeconds: pulumi.Int(300),
					},
					ServiceCidr:                        pulumi.String("10.8.0.0/16,10.244.0.0/16,10.245.0.1/16"),
					ServiceRuntimeNetworkResourceGroup: pulumi.String("my-service-runtime-network-rg"),
					ServiceRuntimeSubnetId:             pulumi.String("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork/subnets/serviceRuntime"),
				},
				VnetAddons: &appplatform.ServiceVNetAddonsArgs{
					DataPlanePublicEndpoint: pulumi.Bool(true),
					LogStreamPublicEndpoint: pulumi.Bool(true),
				},
			},
			ResourceGroupName: pulumi.String("myResourceGroup"),
			ServiceName:       pulumi.String("myservice"),
			Sku: &appplatform.SkuArgs{
				Name: pulumi.String("S0"),
				Tier: pulumi.String("Standard"),
			},
			Tags: pulumi.StringMap{
				"key1": pulumi.String("value1"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var service = new AzureNative.AppPlatform.Service("service", new()
    {
        Location = "eastus",
        Properties = new AzureNative.AppPlatform.Inputs.ClusterResourcePropertiesArgs
        {
            NetworkProfile = new AzureNative.AppPlatform.Inputs.NetworkProfileArgs
            {
                AppNetworkResourceGroup = "my-app-network-rg",
                AppSubnetId = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork/subnets/apps",
                IngressConfig = new AzureNative.AppPlatform.Inputs.IngressConfigArgs
                {
                    ReadTimeoutInSeconds = 300,
                },
                ServiceCidr = "10.8.0.0/16,10.244.0.0/16,10.245.0.1/16",
                ServiceRuntimeNetworkResourceGroup = "my-service-runtime-network-rg",
                ServiceRuntimeSubnetId = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork/subnets/serviceRuntime",
            },
            VnetAddons = new AzureNative.AppPlatform.Inputs.ServiceVNetAddonsArgs
            {
                DataPlanePublicEndpoint = true,
                LogStreamPublicEndpoint = true,
            },
        },
        ResourceGroupName = "myResourceGroup",
        ServiceName = "myservice",
        Sku = new AzureNative.AppPlatform.Inputs.SkuArgs
        {
            Name = "S0",
            Tier = "Standard",
        },
        Tags = 
        {
            { "key1", "value1" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.appplatform.Service;
import com.pulumi.azurenative.appplatform.ServiceArgs;
import com.pulumi.azurenative.appplatform.inputs.ClusterResourcePropertiesArgs;
import com.pulumi.azurenative.appplatform.inputs.NetworkProfileArgs;
import com.pulumi.azurenative.appplatform.inputs.IngressConfigArgs;
import com.pulumi.azurenative.appplatform.inputs.ServiceVNetAddonsArgs;
import com.pulumi.azurenative.appplatform.inputs.SkuArgs;
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 service = new Service("service", ServiceArgs.builder()
            .location("eastus")
            .properties(ClusterResourcePropertiesArgs.builder()
                .networkProfile(NetworkProfileArgs.builder()
                    .appNetworkResourceGroup("my-app-network-rg")
                    .appSubnetId("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork/subnets/apps")
                    .ingressConfig(IngressConfigArgs.builder()
                        .readTimeoutInSeconds(300)
                        .build())
                    .serviceCidr("10.8.0.0/16,10.244.0.0/16,10.245.0.1/16")
                    .serviceRuntimeNetworkResourceGroup("my-service-runtime-network-rg")
                    .serviceRuntimeSubnetId("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork/subnets/serviceRuntime")
                    .build())
                .vnetAddons(ServiceVNetAddonsArgs.builder()
                    .dataPlanePublicEndpoint(true)
                    .logStreamPublicEndpoint(true)
                    .build())
                .build())
            .resourceGroupName("myResourceGroup")
            .serviceName("myservice")
            .sku(SkuArgs.builder()
                .name("S0")
                .tier("Standard")
                .build())
            .tags(Map.of("key1", "value1"))
            .build());

    }
}
resources:
  service:
    type: azure-native:appplatform:Service
    properties:
      location: eastus
      properties:
        networkProfile:
          appNetworkResourceGroup: my-app-network-rg
          appSubnetId: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork/subnets/apps
          ingressConfig:
            readTimeoutInSeconds: 300
          serviceCidr: 10.8.0.0/16,10.244.0.0/16,10.245.0.1/16
          serviceRuntimeNetworkResourceGroup: my-service-runtime-network-rg
          serviceRuntimeSubnetId: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork/subnets/serviceRuntime
        vnetAddons:
          dataPlanePublicEndpoint: true
          logStreamPublicEndpoint: true
      resourceGroupName: myResourceGroup
      serviceName: myservice
      sku:
        name: S0
        tier: Standard
      tags:
        key1: value1

The networkProfile property defines subnet placement and network configuration. The appSubnetId and serviceRuntimeSubnetId place application instances and platform components in separate subnets. The serviceCidr reserves IP ranges for internal service communication. The vnetAddons property controls whether public endpoints remain accessible for management operations.

Beyond these examples

These snippets focus on specific service-level features: tier selection, maintenance scheduling and VNet injection, and Container Apps and Tanzu marketplace integration. They’re intentionally minimal rather than full Spring application deployments.

The examples may reference pre-existing infrastructure such as resource groups, virtual networks and subnets (for VNet injection), and Container Apps managed environments (for StandardGen2). They focus on configuring the service rather than provisioning everything around it.

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

  • Application deployment and configuration
  • Custom domains and TLS certificates
  • Monitoring and diagnostic settings
  • Service registry and config server setup

These omissions are intentional: the goal is to illustrate how each service feature is wired, not provide drop-in Spring application modules. See the Azure Spring Apps Service resource reference for all available configuration options.

Let's deploy Azure Spring Cloud Services

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Resource Configuration & Immutability
What properties can't I change after creating the service?
The resourceGroupName and serviceName properties are immutable and cannot be modified after creation. Changing these requires recreating the resource.
What's the difference between Standard, Enterprise, and StandardGen2 tiers?
Standard tier (S0/Standard) is the base offering. Enterprise tier (E0/Enterprise) requires marketplaceResource configuration for VMware Tanzu integration. StandardGen2 tier (S0/StandardGen2) integrates with Azure Container Apps using managedEnvironmentId.
Networking & VNet Integration
How do I inject my service into a VNet?
Configure networkProfile with appSubnetId, serviceRuntimeSubnetId, and serviceCidr. You can optionally specify appNetworkResourceGroup and serviceRuntimeNetworkResourceGroup for network resource organization.
Can I enable public endpoints for a VNet-injected service?
Yes, use vnetAddons with dataPlanePublicEndpoint and logStreamPublicEndpoint set to true to enable public access to the data plane and log streaming.
What's the ingress timeout configuration for VNet-injected services?
Configure ingressConfig.readTimeoutInSeconds within networkProfile. The example shows a value of 300 seconds.
Maintenance & Operations
How do I schedule maintenance windows?
Set maintenanceScheduleConfiguration with frequency set to Weekly, specify the day (e.g., Sunday), and set the hour (e.g., 10 for 10:00 AM).
API Versions & Advanced Configuration
How do I use a different Azure API version?
Generate a local SDK package using the CLI command pulumi package add azure-native appplatform [ApiVersion]. Available versions include 2023-05-01-preview, 2023-07-01-preview, 2023-09-01-preview, 2023-11-01-preview, 2023-12-01, and 2024-05-01-preview.
How do I configure the Enterprise tier with VMware Tanzu?
Use SKU tier Enterprise (E0) and configure marketplaceResource with plan (e.g., tanzu-asc-ent-mtr), product (e.g., azure-spring-cloud-vmware-tanzu-2), and publisher (e.g., vmware-inc).

Using a different cloud?

Explore compute guides for other cloud providers: