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. This guide focuses on three capabilities: freeform JSON configuration, structured feature flags, and user-targeted flag variants.

Configuration versions belong to an AppConfig application and configuration profile that must exist before creating versions. The examples are intentionally small. Combine them with your own application setup and deployment strategies.

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, typically “application/json”. Each version is immutable; changes require creating a new version. The applicationId and configurationProfileId link this version to its parent resources.

Define feature flags with attributes and constraints

Feature flag systems need structured schemas to define flags, their attributes, and validation rules.

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 and their schemas. The attributes property specifies typed fields with constraints (type, required). The values section sets runtime state: which flags are enabled and their attribute values. The version field tracks the schema version. This structure provides type safety and validation for feature flag data.

Target feature flags to specific users with variants

Advanced deployments enable flags for specific user segments while keeping them disabled for others.

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 has a name, enabled state, and optional rule expression. Rules use AppConfig’s expression syntax to match user attributes (e.g., eq $userId "123"). The first matching variant applies; the last variant typically serves as the default with no rule.

Beyond these examples

These snippets focus on specific configuration version features: freeform JSON configuration, structured feature flags with attributes, and user-targeted flag variants. They’re intentionally minimal rather than full configuration management systems.

The examples reference pre-existing infrastructure such as AppConfig applications and configuration profiles. They focus on creating configuration versions rather than provisioning the surrounding AppConfig resources.

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

  • Configuration validation schemas
  • Deployment strategies and rollout controls
  • Configuration retrieval and client integration
  • Version lifecycle management

These omissions are intentional: the goal is to illustrate how each configuration version feature is wired, 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

Versioning & Updates
Can I update an existing configuration version?
No, configuration versions are immutable. To make changes, create a new version with updated content. The versionNumber increments automatically.
What properties are immutable after creation?
All key properties are immutable: content, contentType, applicationId, configurationProfileId, and description. Any change requires creating a new version.
Configuration Types & Formats
What's the difference between freeform and feature flag configurations?
Freeform configurations use arbitrary JSON structure for any configuration data. Feature flag configurations require a specific schema with flags (definitions), values (current state), and version fields.
What content types are supported?
Any standard MIME type is supported. The examples use application/json for both freeform and feature flag configurations.
How do I structure a freeform configuration?
Set contentType to application/json and provide any valid JSON in the content field. The structure is flexible and not validated against a schema.
Feature Flags
How do I create a feature flag configuration?
Use contentType: "application/json" with JSON containing three required fields: flags (flag definitions with names and optional attributes), values (current flag states), and version (schema version string).
How do I create multi-variant feature flags?
In the values section, use the _variants field with an array of variant objects. Each variant includes enabled, name, and optionally rule for targeting specific users or conditions.

Using a different cloud?

Explore integration guides for other cloud providers: