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 FREEFrequently Asked Questions
Versioning & Updates
content. The versionNumber increments automatically.content, contentType, applicationId, configurationProfileId, and description. Any change requires creating a new version.Configuration Types & Formats
flags (definitions), values (current state), and version fields.application/json for both freeform and feature flag configurations.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
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).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: