Create AWS AppConfig Hosted Configuration Versions

The aws:appconfig/hostedConfigurationVersion:HostedConfigurationVersion resource, part of the Pulumi AWS provider, creates an immutable version of configuration data stored in AppConfig, whether freeform JSON or structured feature flags. This guide focuses on three capabilities: freeform JSON configuration, feature flag definitions with typed attributes, and multi-variant targeting rules.

Configuration versions belong to an AppConfig application and configuration profile that must exist first. The examples are intentionally small. Combine them with your own AppConfig application, configuration profile, and deployment strategy.

Store freeform JSON configuration data

Applications often need to version arbitrary configuration that doesn’t fit a predefined schema.

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

const example = new aws.appconfig.HostedConfigurationVersion("example", {
    applicationId: exampleAwsAppconfigApplication.id,
    configurationProfileId: exampleAwsAppconfigConfigurationProfile.configurationProfileId,
    description: "Example Freeform Hosted Configuration Version",
    contentType: "application/json",
    content: JSON.stringify({
        foo: "bar",
        fruit: [
            "apple",
            "pear",
            "orange",
        ],
        isThingEnabled: true,
    }),
});
import pulumi
import json
import pulumi_aws as aws

example = aws.appconfig.HostedConfigurationVersion("example",
    application_id=example_aws_appconfig_application["id"],
    configuration_profile_id=example_aws_appconfig_configuration_profile["configurationProfileId"],
    description="Example Freeform Hosted Configuration Version",
    content_type="application/json",
    content=json.dumps({
        "foo": "bar",
        "fruit": [
            "apple",
            "pear",
            "orange",
        ],
        "isThingEnabled": True,
    }))
package main

import (
	"encoding/json"

	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/appconfig"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		tmpJSON0, err := json.Marshal(map[string]interface{}{
			"foo": "bar",
			"fruit": []string{
				"apple",
				"pear",
				"orange",
			},
			"isThingEnabled": true,
		})
		if err != nil {
			return err
		}
		json0 := string(tmpJSON0)
		_, err = appconfig.NewHostedConfigurationVersion(ctx, "example", &appconfig.HostedConfigurationVersionArgs{
			ApplicationId:          pulumi.Any(exampleAwsAppconfigApplication.Id),
			ConfigurationProfileId: pulumi.Any(exampleAwsAppconfigConfigurationProfile.ConfigurationProfileId),
			Description:            pulumi.String("Example Freeform Hosted Configuration Version"),
			ContentType:            pulumi.String("application/json"),
			Content:                pulumi.String(json0),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.AppConfig.HostedConfigurationVersion("example", new()
    {
        ApplicationId = exampleAwsAppconfigApplication.Id,
        ConfigurationProfileId = exampleAwsAppconfigConfigurationProfile.ConfigurationProfileId,
        Description = "Example Freeform Hosted Configuration Version",
        ContentType = "application/json",
        Content = JsonSerializer.Serialize(new Dictionary<string, object?>
        {
            ["foo"] = "bar",
            ["fruit"] = new[]
            {
                "apple",
                "pear",
                "orange",
            },
            ["isThingEnabled"] = true,
        }),
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.appconfig.HostedConfigurationVersion;
import com.pulumi.aws.appconfig.HostedConfigurationVersionArgs;
import static com.pulumi.codegen.internal.Serialization.*;
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 HostedConfigurationVersion("example", HostedConfigurationVersionArgs.builder()
            .applicationId(exampleAwsAppconfigApplication.id())
            .configurationProfileId(exampleAwsAppconfigConfigurationProfile.configurationProfileId())
            .description("Example Freeform Hosted Configuration Version")
            .contentType("application/json")
            .content(serializeJson(
                jsonObject(
                    jsonProperty("foo", "bar"),
                    jsonProperty("fruit", jsonArray(
                        "apple", 
                        "pear", 
                        "orange"
                    )),
                    jsonProperty("isThingEnabled", true)
                )))
            .build());

    }
}
resources:
  example:
    type: aws:appconfig:HostedConfigurationVersion
    properties:
      applicationId: ${exampleAwsAppconfigApplication.id}
      configurationProfileId: ${exampleAwsAppconfigConfigurationProfile.configurationProfileId}
      description: Example Freeform Hosted Configuration Version
      contentType: application/json
      content:
        fn::toJSON:
          foo: bar
          fruit:
            - apple
            - pear
            - orange
          isThingEnabled: true

The content property holds your JSON configuration as a string. The contentType specifies the MIME type; use “application/json” for JSON data. Each version is immutable once created, so changes require creating a new version.

Define feature flags with typed attributes

Feature flag systems need structured definitions with metadata and typed attributes.

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

const example = new aws.appconfig.HostedConfigurationVersion("example", {
    applicationId: exampleAwsAppconfigApplication.id,
    configurationProfileId: exampleAwsAppconfigConfigurationProfile.configurationProfileId,
    description: "Example Feature Flag Configuration Version",
    contentType: "application/json",
    content: JSON.stringify({
        flags: {
            foo: {
                name: "foo",
                _deprecation: {
                    status: "planned",
                },
            },
            bar: {
                name: "bar",
                attributes: {
                    someAttribute: {
                        constraints: {
                            type: "string",
                            required: true,
                        },
                    },
                    someOtherAttribute: {
                        constraints: {
                            type: "number",
                            required: true,
                        },
                    },
                },
            },
        },
        values: {
            foo: {
                enabled: "true",
            },
            bar: {
                enabled: "true",
                someAttribute: "Hello World",
                someOtherAttribute: 123,
            },
        },
        version: "1",
    }),
});
import pulumi
import json
import pulumi_aws as aws

example = aws.appconfig.HostedConfigurationVersion("example",
    application_id=example_aws_appconfig_application["id"],
    configuration_profile_id=example_aws_appconfig_configuration_profile["configurationProfileId"],
    description="Example Feature Flag Configuration Version",
    content_type="application/json",
    content=json.dumps({
        "flags": {
            "foo": {
                "name": "foo",
                "_deprecation": {
                    "status": "planned",
                },
            },
            "bar": {
                "name": "bar",
                "attributes": {
                    "someAttribute": {
                        "constraints": {
                            "type": "string",
                            "required": True,
                        },
                    },
                    "someOtherAttribute": {
                        "constraints": {
                            "type": "number",
                            "required": True,
                        },
                    },
                },
            },
        },
        "values": {
            "foo": {
                "enabled": "true",
            },
            "bar": {
                "enabled": "true",
                "someAttribute": "Hello World",
                "someOtherAttribute": 123,
            },
        },
        "version": "1",
    }))
package main

import (
	"encoding/json"

	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/appconfig"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		tmpJSON0, err := json.Marshal(map[string]interface{}{
			"flags": map[string]interface{}{
				"foo": map[string]interface{}{
					"name": "foo",
					"_deprecation": map[string]interface{}{
						"status": "planned",
					},
				},
				"bar": map[string]interface{}{
					"name": "bar",
					"attributes": map[string]interface{}{
						"someAttribute": map[string]interface{}{
							"constraints": map[string]interface{}{
								"type":     "string",
								"required": true,
							},
						},
						"someOtherAttribute": map[string]interface{}{
							"constraints": map[string]interface{}{
								"type":     "number",
								"required": true,
							},
						},
					},
				},
			},
			"values": map[string]interface{}{
				"foo": map[string]interface{}{
					"enabled": "true",
				},
				"bar": map[string]interface{}{
					"enabled":            "true",
					"someAttribute":      "Hello World",
					"someOtherAttribute": 123,
				},
			},
			"version": "1",
		})
		if err != nil {
			return err
		}
		json0 := string(tmpJSON0)
		_, err = appconfig.NewHostedConfigurationVersion(ctx, "example", &appconfig.HostedConfigurationVersionArgs{
			ApplicationId:          pulumi.Any(exampleAwsAppconfigApplication.Id),
			ConfigurationProfileId: pulumi.Any(exampleAwsAppconfigConfigurationProfile.ConfigurationProfileId),
			Description:            pulumi.String("Example Feature Flag Configuration Version"),
			ContentType:            pulumi.String("application/json"),
			Content:                pulumi.String(json0),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.AppConfig.HostedConfigurationVersion("example", new()
    {
        ApplicationId = exampleAwsAppconfigApplication.Id,
        ConfigurationProfileId = exampleAwsAppconfigConfigurationProfile.ConfigurationProfileId,
        Description = "Example Feature Flag Configuration Version",
        ContentType = "application/json",
        Content = JsonSerializer.Serialize(new Dictionary<string, object?>
        {
            ["flags"] = new Dictionary<string, object?>
            {
                ["foo"] = new Dictionary<string, object?>
                {
                    ["name"] = "foo",
                    ["_deprecation"] = new Dictionary<string, object?>
                    {
                        ["status"] = "planned",
                    },
                },
                ["bar"] = new Dictionary<string, object?>
                {
                    ["name"] = "bar",
                    ["attributes"] = new Dictionary<string, object?>
                    {
                        ["someAttribute"] = new Dictionary<string, object?>
                        {
                            ["constraints"] = new Dictionary<string, object?>
                            {
                                ["type"] = "string",
                                ["required"] = true,
                            },
                        },
                        ["someOtherAttribute"] = new Dictionary<string, object?>
                        {
                            ["constraints"] = new Dictionary<string, object?>
                            {
                                ["type"] = "number",
                                ["required"] = true,
                            },
                        },
                    },
                },
            },
            ["values"] = new Dictionary<string, object?>
            {
                ["foo"] = new Dictionary<string, object?>
                {
                    ["enabled"] = "true",
                },
                ["bar"] = new Dictionary<string, object?>
                {
                    ["enabled"] = "true",
                    ["someAttribute"] = "Hello World",
                    ["someOtherAttribute"] = 123,
                },
            },
            ["version"] = "1",
        }),
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.appconfig.HostedConfigurationVersion;
import com.pulumi.aws.appconfig.HostedConfigurationVersionArgs;
import static com.pulumi.codegen.internal.Serialization.*;
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 HostedConfigurationVersion("example", HostedConfigurationVersionArgs.builder()
            .applicationId(exampleAwsAppconfigApplication.id())
            .configurationProfileId(exampleAwsAppconfigConfigurationProfile.configurationProfileId())
            .description("Example Feature Flag Configuration Version")
            .contentType("application/json")
            .content(serializeJson(
                jsonObject(
                    jsonProperty("flags", jsonObject(
                        jsonProperty("foo", jsonObject(
                            jsonProperty("name", "foo"),
                            jsonProperty("_deprecation", jsonObject(
                                jsonProperty("status", "planned")
                            ))
                        )),
                        jsonProperty("bar", jsonObject(
                            jsonProperty("name", "bar"),
                            jsonProperty("attributes", jsonObject(
                                jsonProperty("someAttribute", jsonObject(
                                    jsonProperty("constraints", jsonObject(
                                        jsonProperty("type", "string"),
                                        jsonProperty("required", true)
                                    ))
                                )),
                                jsonProperty("someOtherAttribute", jsonObject(
                                    jsonProperty("constraints", jsonObject(
                                        jsonProperty("type", "number"),
                                        jsonProperty("required", true)
                                    ))
                                ))
                            ))
                        ))
                    )),
                    jsonProperty("values", jsonObject(
                        jsonProperty("foo", jsonObject(
                            jsonProperty("enabled", "true")
                        )),
                        jsonProperty("bar", jsonObject(
                            jsonProperty("enabled", "true"),
                            jsonProperty("someAttribute", "Hello World"),
                            jsonProperty("someOtherAttribute", 123)
                        ))
                    )),
                    jsonProperty("version", "1")
                )))
            .build());

    }
}
resources:
  example:
    type: aws:appconfig:HostedConfigurationVersion
    properties:
      applicationId: ${exampleAwsAppconfigApplication.id}
      configurationProfileId: ${exampleAwsAppconfigConfigurationProfile.configurationProfileId}
      description: Example Feature Flag Configuration Version
      contentType: application/json
      content:
        fn::toJSON:
          flags:
            foo:
              name: foo
              _deprecation:
                status: planned
            bar:
              name: bar
              attributes:
                someAttribute:
                  constraints:
                    type: string
                    required: true
                someOtherAttribute:
                  constraints:
                    type: number
                    required: true
          values:
            foo:
              enabled: 'true'
            bar:
              enabled: 'true'
              someAttribute: Hello World
              someOtherAttribute: 123
          version: '1'

The flags section defines available flags with optional deprecation status. The values section sets each flag’s state and attribute values. The attributes block enforces type constraints; here, someAttribute must be a string and someOtherAttribute must be a number. The version field tracks the schema version.

Target feature flags to specific users

Advanced deployments enable flags conditionally based on user identity.

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

const example = new aws.appconfig.HostedConfigurationVersion("example", {
    applicationId: exampleAwsAppconfigApplication.id,
    configurationProfileId: exampleAwsAppconfigConfigurationProfile.configurationProfileId,
    description: "Example Multi-variant Feature Flag Configuration Version",
    contentType: "application/json",
    content: JSON.stringify({
        flags: {
            loggingenabled: {
                name: "loggingEnabled",
            },
        },
        values: {
            loggingenabled: {
                _variants: std.concat({
                    input: [
                        .map(userId => ({
                            enabled: true,
                            name: `usersWithLoggingEnabled_${userId}`,
                            rule: `(or (eq $userId "${userId}"))`,
                        })),
                        [{
                            enabled: false,
                            name: "Default",
                        }],
                    ],
                }).then(invoke => invoke.result),
            },
        },
        version: "1",
    }),
});
import pulumi
import json
import pulumi_aws as aws
import pulumi_std as std

example = aws.appconfig.HostedConfigurationVersion("example",
    application_id=example_aws_appconfig_application["id"],
    configuration_profile_id=example_aws_appconfig_configuration_profile["configurationProfileId"],
    description="Example Multi-variant Feature Flag Configuration Version",
    content_type="application/json",
    content=json.dumps({
        "flags": {
            "loggingenabled": {
                "name": "loggingEnabled",
            },
        },
        "values": {
            "loggingenabled": {
                "_variants": std.concat(input=[
                    [{
                        "enabled": True,
                        "name": f"usersWithLoggingEnabled_{user_id}",
                        "rule": f"(or (eq $userId \"{user_id}\"))",
                    } for userId in appcfg_enable_logging_user_ids],
                    [{
                        "enabled": False,
                        "name": "Default",
                    }],
                ]).result,
            },
        },
        "version": "1",
    }))
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Pulumi;
using Aws = Pulumi.Aws;
using Std = Pulumi.Std;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.AppConfig.HostedConfigurationVersion("example", new()
    {
        ApplicationId = exampleAwsAppconfigApplication.Id,
        ConfigurationProfileId = exampleAwsAppconfigConfigurationProfile.ConfigurationProfileId,
        Description = "Example Multi-variant Feature Flag Configuration Version",
        ContentType = "application/json",
        Content = JsonSerializer.Serialize(new Dictionary<string, object?>
        {
            ["flags"] = new Dictionary<string, object?>
            {
                ["loggingenabled"] = new Dictionary<string, object?>
                {
                    ["name"] = "loggingEnabled",
                },
            },
            ["values"] = new Dictionary<string, object?>
            {
                ["loggingenabled"] = new Dictionary<string, object?>
                {
                    ["_variants"] = Std.Concat.Invoke(new()
                    {
                        Input = new[]
                        {
                            .Select(userId => 
                            {
                                return 
                                {
                                    { "enabled", true },
                                    { "name", $"usersWithLoggingEnabled_{userId}" },
                                    { "rule", $"(or (eq $userId \"{userId}\"))" },
                                };
                            }).ToList(),
                            new[]
                            {
                                
                                {
                                    { "enabled", false },
                                    { "name", "Default" },
                                },
                            },
                        },
                    }).Apply(invoke => invoke.Result),
                },
            },
            ["version"] = "1",
        }),
    });

});

The _variants array defines multiple flag states with targeting rules. Each variant specifies whether the flag is enabled and a rule expression that determines when it applies. Rules use AppConfig’s expression syntax to match user attributes; here, flags enable for specific user IDs and default to disabled for everyone else.

Beyond these examples

These snippets focus on specific configuration version features: freeform JSON configuration, feature flag definitions with typed attributes, and multi-variant targeting rules. They’re intentionally minimal rather than full configuration management systems.

The examples reference pre-existing infrastructure such as AppConfig application (applicationId) and AppConfig configuration profile (configurationProfileId). They focus on versioning configuration data rather than provisioning the surrounding AppConfig resources.

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

  • Description metadata (description property)
  • Version number management (versionNumber is output-only)
  • Content validation against profile validators
  • Deployment strategies and rollout configuration

These omissions are intentional: the goal is to illustrate how each configuration format is structured, not provide drop-in configuration management modules. See the AppConfig HostedConfigurationVersion resource reference for all available configuration options.

Let's create AWS AppConfig Hosted Configuration Versions

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Configuration Basics & Immutability
Can I update a hosted configuration version after creation?
No. All properties (applicationId, configurationProfileId, content, contentType, description) are immutable. To update configuration data, create a new HostedConfigurationVersion resource.
What content types are supported for hosted configurations?
Any standard MIME type. The examples use application/json for JSON-formatted configurations.
Content Formats & Structure
How do I structure freeform configuration content?
Use any valid JSON structure in the content property. The freeform example demonstrates arbitrary key-value pairs, arrays, and boolean values.
What's the difference between freeform and feature flag configurations?
Freeform configurations use arbitrary JSON structures. Feature flag configurations require a specific schema with flags, values, and version keys to define toggleable features.
Feature Flags
How do I create feature flag configurations?

Structure your JSON content with three keys:

  1. flags - Define each flag with a name and optional attributes/constraints
  2. values - Set the enabled state and attribute values for each flag
  3. version - Specify the configuration version (e.g., “1”)
What are multi-variant feature flags and how do I use them?
Multi-variant feature flags support multiple conditional variants using the _variants array. Each variant includes an enabled state, name, and optional rule for conditional evaluation (e.g., user-based targeting).

Using a different cloud?

Explore integration guides for other cloud providers: