The aws:opensearch/serverlessSecurityPolicy:ServerlessSecurityPolicy resource, part of the Pulumi AWS provider, defines security policies that control encryption and network access for OpenSearch Serverless collections. This guide focuses on three capabilities: encryption policies with AWS-managed and customer-managed keys, network policies for public and VPC-restricted access, and wildcard patterns for multi-collection policies.
Security policies apply to OpenSearch Serverless collections and may reference KMS keys or VPC endpoints that must exist separately. The examples are intentionally small. Combine them with your own collection definitions and network infrastructure.
Encrypt a single collection with AWS-managed keys
Most deployments start by defining encryption policies that protect data at rest using AWS-managed keys.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.opensearch.ServerlessSecurityPolicy("example", {
name: "example",
type: "encryption",
description: "encryption security policy for example-collection",
policy: JSON.stringify({
Rules: [{
Resource: ["collection/example-collection"],
ResourceType: "collection",
}],
AWSOwnedKey: true,
}),
});
import pulumi
import json
import pulumi_aws as aws
example = aws.opensearch.ServerlessSecurityPolicy("example",
name="example",
type="encryption",
description="encryption security policy for example-collection",
policy=json.dumps({
"Rules": [{
"Resource": ["collection/example-collection"],
"ResourceType": "collection",
}],
"AWSOwnedKey": True,
}))
package main
import (
"encoding/json"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/opensearch"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
tmpJSON0, err := json.Marshal(map[string]interface{}{
"Rules": []map[string]interface{}{
map[string]interface{}{
"Resource": []string{
"collection/example-collection",
},
"ResourceType": "collection",
},
},
"AWSOwnedKey": true,
})
if err != nil {
return err
}
json0 := string(tmpJSON0)
_, err = opensearch.NewServerlessSecurityPolicy(ctx, "example", &opensearch.ServerlessSecurityPolicyArgs{
Name: pulumi.String("example"),
Type: pulumi.String("encryption"),
Description: pulumi.String("encryption security policy for example-collection"),
Policy: 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.OpenSearch.ServerlessSecurityPolicy("example", new()
{
Name = "example",
Type = "encryption",
Description = "encryption security policy for example-collection",
Policy = JsonSerializer.Serialize(new Dictionary<string, object?>
{
["Rules"] = new[]
{
new Dictionary<string, object?>
{
["Resource"] = new[]
{
"collection/example-collection",
},
["ResourceType"] = "collection",
},
},
["AWSOwnedKey"] = true,
}),
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.opensearch.ServerlessSecurityPolicy;
import com.pulumi.aws.opensearch.ServerlessSecurityPolicyArgs;
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 ServerlessSecurityPolicy("example", ServerlessSecurityPolicyArgs.builder()
.name("example")
.type("encryption")
.description("encryption security policy for example-collection")
.policy(serializeJson(
jsonObject(
jsonProperty("Rules", jsonArray(jsonObject(
jsonProperty("Resource", jsonArray("collection/example-collection")),
jsonProperty("ResourceType", "collection")
))),
jsonProperty("AWSOwnedKey", true)
)))
.build());
}
}
resources:
example:
type: aws:opensearch:ServerlessSecurityPolicy
properties:
name: example
type: encryption
description: encryption security policy for example-collection
policy:
fn::toJSON:
Rules:
- Resource:
- collection/example-collection
ResourceType: collection
AWSOwnedKey: true
The type property specifies “encryption” to create an encryption policy. The policy JSON defines Rules that target specific collections by name. Setting AWSOwnedKey to true uses AWS-managed encryption keys, which AWS rotates automatically.
Encrypt collections with customer-managed KMS keys
Organizations with compliance requirements often need control over encryption keys for rotation and access policies.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.opensearch.ServerlessSecurityPolicy("example", {
name: "example",
type: "encryption",
description: "encryption security policy using customer KMS key",
policy: JSON.stringify({
Rules: [{
Resource: ["collection/customer-managed-key-collection"],
ResourceType: "collection",
}],
AWSOwnedKey: false,
KmsARN: "arn:aws:kms:us-east-1:123456789012:key/93fd6da4-a317-4c17-bfe9-382b5d988b36",
}),
});
import pulumi
import json
import pulumi_aws as aws
example = aws.opensearch.ServerlessSecurityPolicy("example",
name="example",
type="encryption",
description="encryption security policy using customer KMS key",
policy=json.dumps({
"Rules": [{
"Resource": ["collection/customer-managed-key-collection"],
"ResourceType": "collection",
}],
"AWSOwnedKey": False,
"KmsARN": "arn:aws:kms:us-east-1:123456789012:key/93fd6da4-a317-4c17-bfe9-382b5d988b36",
}))
package main
import (
"encoding/json"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/opensearch"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
tmpJSON0, err := json.Marshal(map[string]interface{}{
"Rules": []map[string]interface{}{
map[string]interface{}{
"Resource": []string{
"collection/customer-managed-key-collection",
},
"ResourceType": "collection",
},
},
"AWSOwnedKey": false,
"KmsARN": "arn:aws:kms:us-east-1:123456789012:key/93fd6da4-a317-4c17-bfe9-382b5d988b36",
})
if err != nil {
return err
}
json0 := string(tmpJSON0)
_, err = opensearch.NewServerlessSecurityPolicy(ctx, "example", &opensearch.ServerlessSecurityPolicyArgs{
Name: pulumi.String("example"),
Type: pulumi.String("encryption"),
Description: pulumi.String("encryption security policy using customer KMS key"),
Policy: 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.OpenSearch.ServerlessSecurityPolicy("example", new()
{
Name = "example",
Type = "encryption",
Description = "encryption security policy using customer KMS key",
Policy = JsonSerializer.Serialize(new Dictionary<string, object?>
{
["Rules"] = new[]
{
new Dictionary<string, object?>
{
["Resource"] = new[]
{
"collection/customer-managed-key-collection",
},
["ResourceType"] = "collection",
},
},
["AWSOwnedKey"] = false,
["KmsARN"] = "arn:aws:kms:us-east-1:123456789012:key/93fd6da4-a317-4c17-bfe9-382b5d988b36",
}),
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.opensearch.ServerlessSecurityPolicy;
import com.pulumi.aws.opensearch.ServerlessSecurityPolicyArgs;
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 ServerlessSecurityPolicy("example", ServerlessSecurityPolicyArgs.builder()
.name("example")
.type("encryption")
.description("encryption security policy using customer KMS key")
.policy(serializeJson(
jsonObject(
jsonProperty("Rules", jsonArray(jsonObject(
jsonProperty("Resource", jsonArray("collection/customer-managed-key-collection")),
jsonProperty("ResourceType", "collection")
))),
jsonProperty("AWSOwnedKey", false),
jsonProperty("KmsARN", "arn:aws:kms:us-east-1:123456789012:key/93fd6da4-a317-4c17-bfe9-382b5d988b36")
)))
.build());
}
}
resources:
example:
type: aws:opensearch:ServerlessSecurityPolicy
properties:
name: example
type: encryption
description: encryption security policy using customer KMS key
policy:
fn::toJSON:
Rules:
- Resource:
- collection/customer-managed-key-collection
ResourceType: collection
AWSOwnedKey: false
KmsARN: arn:aws:kms:us-east-1:123456789012:key/93fd6da4-a317-4c17-bfe9-382b5d988b36
Setting AWSOwnedKey to false and providing a KmsARN switches to customer-managed keys. You control key rotation, access policies, and audit logging through KMS. The KMS key must exist before creating the policy.
Apply encryption to multiple collections with wildcards
When managing many collections with similar security requirements, wildcard patterns reduce policy duplication.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.opensearch.ServerlessSecurityPolicy("example", {
name: "example",
type: "encryption",
description: "encryption security policy for collections that begin with \"example\"",
policy: JSON.stringify({
Rules: [{
Resource: ["collection/example*"],
ResourceType: "collection",
}],
AWSOwnedKey: true,
}),
});
import pulumi
import json
import pulumi_aws as aws
example = aws.opensearch.ServerlessSecurityPolicy("example",
name="example",
type="encryption",
description="encryption security policy for collections that begin with \"example\"",
policy=json.dumps({
"Rules": [{
"Resource": ["collection/example*"],
"ResourceType": "collection",
}],
"AWSOwnedKey": True,
}))
package main
import (
"encoding/json"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/opensearch"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
tmpJSON0, err := json.Marshal(map[string]interface{}{
"Rules": []map[string]interface{}{
map[string]interface{}{
"Resource": []string{
"collection/example*",
},
"ResourceType": "collection",
},
},
"AWSOwnedKey": true,
})
if err != nil {
return err
}
json0 := string(tmpJSON0)
_, err = opensearch.NewServerlessSecurityPolicy(ctx, "example", &opensearch.ServerlessSecurityPolicyArgs{
Name: pulumi.String("example"),
Type: pulumi.String("encryption"),
Description: pulumi.String("encryption security policy for collections that begin with \"example\""),
Policy: 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.OpenSearch.ServerlessSecurityPolicy("example", new()
{
Name = "example",
Type = "encryption",
Description = "encryption security policy for collections that begin with \"example\"",
Policy = JsonSerializer.Serialize(new Dictionary<string, object?>
{
["Rules"] = new[]
{
new Dictionary<string, object?>
{
["Resource"] = new[]
{
"collection/example*",
},
["ResourceType"] = "collection",
},
},
["AWSOwnedKey"] = true,
}),
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.opensearch.ServerlessSecurityPolicy;
import com.pulumi.aws.opensearch.ServerlessSecurityPolicyArgs;
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 ServerlessSecurityPolicy("example", ServerlessSecurityPolicyArgs.builder()
.name("example")
.type("encryption")
.description("encryption security policy for collections that begin with \"example\"")
.policy(serializeJson(
jsonObject(
jsonProperty("Rules", jsonArray(jsonObject(
jsonProperty("Resource", jsonArray("collection/example*")),
jsonProperty("ResourceType", "collection")
))),
jsonProperty("AWSOwnedKey", true)
)))
.build());
}
}
resources:
example:
type: aws:opensearch:ServerlessSecurityPolicy
properties:
name: example
type: encryption
description: encryption security policy for collections that begin with "example"
policy:
fn::toJSON:
Rules:
- Resource:
- collection/example*
ResourceType: collection
AWSOwnedKey: true
The Resource array accepts wildcard patterns like “collection/example*” to match multiple collections. This extends the single-collection pattern by applying the same encryption settings to all collections whose names begin with “example”.
Allow public access to collections and dashboards
Network policies control whether collections and dashboards are accessible from the public internet or restricted to VPC endpoints.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.opensearch.ServerlessSecurityPolicy("example", {
name: "example",
type: "network",
description: "Public access",
policy: JSON.stringify([{
Description: "Public access to collection and Dashboards endpoint for example collection",
Rules: [
{
ResourceType: "collection",
Resource: ["collection/example-collection"],
},
{
ResourceType: "dashboard",
Resource: ["collection/example-collection"],
},
],
AllowFromPublic: true,
}]),
});
import pulumi
import json
import pulumi_aws as aws
example = aws.opensearch.ServerlessSecurityPolicy("example",
name="example",
type="network",
description="Public access",
policy=json.dumps([{
"Description": "Public access to collection and Dashboards endpoint for example collection",
"Rules": [
{
"ResourceType": "collection",
"Resource": ["collection/example-collection"],
},
{
"ResourceType": "dashboard",
"Resource": ["collection/example-collection"],
},
],
"AllowFromPublic": True,
}]))
package main
import (
"encoding/json"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/opensearch"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
tmpJSON0, err := json.Marshal([]map[string]interface{}{
map[string]interface{}{
"Description": "Public access to collection and Dashboards endpoint for example collection",
"Rules": []map[string]interface{}{
map[string]interface{}{
"ResourceType": "collection",
"Resource": []string{
"collection/example-collection",
},
},
map[string]interface{}{
"ResourceType": "dashboard",
"Resource": []string{
"collection/example-collection",
},
},
},
"AllowFromPublic": true,
},
})
if err != nil {
return err
}
json0 := string(tmpJSON0)
_, err = opensearch.NewServerlessSecurityPolicy(ctx, "example", &opensearch.ServerlessSecurityPolicyArgs{
Name: pulumi.String("example"),
Type: pulumi.String("network"),
Description: pulumi.String("Public access"),
Policy: 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.OpenSearch.ServerlessSecurityPolicy("example", new()
{
Name = "example",
Type = "network",
Description = "Public access",
Policy = JsonSerializer.Serialize(new[]
{
new Dictionary<string, object?>
{
["Description"] = "Public access to collection and Dashboards endpoint for example collection",
["Rules"] = new[]
{
new Dictionary<string, object?>
{
["ResourceType"] = "collection",
["Resource"] = new[]
{
"collection/example-collection",
},
},
new Dictionary<string, object?>
{
["ResourceType"] = "dashboard",
["Resource"] = new[]
{
"collection/example-collection",
},
},
},
["AllowFromPublic"] = true,
},
}),
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.opensearch.ServerlessSecurityPolicy;
import com.pulumi.aws.opensearch.ServerlessSecurityPolicyArgs;
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 ServerlessSecurityPolicy("example", ServerlessSecurityPolicyArgs.builder()
.name("example")
.type("network")
.description("Public access")
.policy(serializeJson(
jsonArray(jsonObject(
jsonProperty("Description", "Public access to collection and Dashboards endpoint for example collection"),
jsonProperty("Rules", jsonArray(
jsonObject(
jsonProperty("ResourceType", "collection"),
jsonProperty("Resource", jsonArray("collection/example-collection"))
),
jsonObject(
jsonProperty("ResourceType", "dashboard"),
jsonProperty("Resource", jsonArray("collection/example-collection"))
)
)),
jsonProperty("AllowFromPublic", true)
))))
.build());
}
}
resources:
example:
type: aws:opensearch:ServerlessSecurityPolicy
properties:
name: example
type: network
description: Public access
policy:
fn::toJSON:
- Description: Public access to collection and Dashboards endpoint for example collection
Rules:
- ResourceType: collection
Resource:
- collection/example-collection
- ResourceType: dashboard
Resource:
- collection/example-collection
AllowFromPublic: true
Setting type to “network” creates a network policy. The policy JSON defines Rules that specify ResourceType (collection or dashboard) and which collections to target. Setting AllowFromPublic to true enables internet access to both the collection API and the OpenSearch Dashboards interface.
Restrict access to VPC endpoints
Production deployments often require private network access to prevent exposure to the public internet.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.opensearch.ServerlessSecurityPolicy("example", {
name: "example",
type: "network",
description: "VPC access",
policy: JSON.stringify([{
Description: "VPC access to collection and Dashboards endpoint for example collection",
Rules: [
{
ResourceType: "collection",
Resource: ["collection/example-collection"],
},
{
ResourceType: "dashboard",
Resource: ["collection/example-collection"],
},
],
AllowFromPublic: false,
SourceVPCEs: ["vpce-050f79086ee71ac05"],
}]),
});
import pulumi
import json
import pulumi_aws as aws
example = aws.opensearch.ServerlessSecurityPolicy("example",
name="example",
type="network",
description="VPC access",
policy=json.dumps([{
"Description": "VPC access to collection and Dashboards endpoint for example collection",
"Rules": [
{
"ResourceType": "collection",
"Resource": ["collection/example-collection"],
},
{
"ResourceType": "dashboard",
"Resource": ["collection/example-collection"],
},
],
"AllowFromPublic": False,
"SourceVPCEs": ["vpce-050f79086ee71ac05"],
}]))
package main
import (
"encoding/json"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/opensearch"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
tmpJSON0, err := json.Marshal([]map[string]interface{}{
map[string]interface{}{
"Description": "VPC access to collection and Dashboards endpoint for example collection",
"Rules": []map[string]interface{}{
map[string]interface{}{
"ResourceType": "collection",
"Resource": []string{
"collection/example-collection",
},
},
map[string]interface{}{
"ResourceType": "dashboard",
"Resource": []string{
"collection/example-collection",
},
},
},
"AllowFromPublic": false,
"SourceVPCEs": []string{
"vpce-050f79086ee71ac05",
},
},
})
if err != nil {
return err
}
json0 := string(tmpJSON0)
_, err = opensearch.NewServerlessSecurityPolicy(ctx, "example", &opensearch.ServerlessSecurityPolicyArgs{
Name: pulumi.String("example"),
Type: pulumi.String("network"),
Description: pulumi.String("VPC access"),
Policy: 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.OpenSearch.ServerlessSecurityPolicy("example", new()
{
Name = "example",
Type = "network",
Description = "VPC access",
Policy = JsonSerializer.Serialize(new[]
{
new Dictionary<string, object?>
{
["Description"] = "VPC access to collection and Dashboards endpoint for example collection",
["Rules"] = new[]
{
new Dictionary<string, object?>
{
["ResourceType"] = "collection",
["Resource"] = new[]
{
"collection/example-collection",
},
},
new Dictionary<string, object?>
{
["ResourceType"] = "dashboard",
["Resource"] = new[]
{
"collection/example-collection",
},
},
},
["AllowFromPublic"] = false,
["SourceVPCEs"] = new[]
{
"vpce-050f79086ee71ac05",
},
},
}),
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.opensearch.ServerlessSecurityPolicy;
import com.pulumi.aws.opensearch.ServerlessSecurityPolicyArgs;
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 ServerlessSecurityPolicy("example", ServerlessSecurityPolicyArgs.builder()
.name("example")
.type("network")
.description("VPC access")
.policy(serializeJson(
jsonArray(jsonObject(
jsonProperty("Description", "VPC access to collection and Dashboards endpoint for example collection"),
jsonProperty("Rules", jsonArray(
jsonObject(
jsonProperty("ResourceType", "collection"),
jsonProperty("Resource", jsonArray("collection/example-collection"))
),
jsonObject(
jsonProperty("ResourceType", "dashboard"),
jsonProperty("Resource", jsonArray("collection/example-collection"))
)
)),
jsonProperty("AllowFromPublic", false),
jsonProperty("SourceVPCEs", jsonArray("vpce-050f79086ee71ac05"))
))))
.build());
}
}
resources:
example:
type: aws:opensearch:ServerlessSecurityPolicy
properties:
name: example
type: network
description: VPC access
policy:
fn::toJSON:
- Description: VPC access to collection and Dashboards endpoint for example collection
Rules:
- ResourceType: collection
Resource:
- collection/example-collection
- ResourceType: dashboard
Resource:
- collection/example-collection
AllowFromPublic: false
SourceVPCEs:
- vpce-050f79086ee71ac05
Setting AllowFromPublic to false and providing SourceVPCEs restricts access to specific VPC endpoints. Only traffic originating from the listed VPC endpoints can reach the collection and dashboard. The VPC endpoint must exist before creating the policy.
Configure different access rules per collection
Organizations often need different network policies for different teams, such as private access for internal analytics and public access for customer-facing dashboards.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.opensearch.ServerlessSecurityPolicy("example", {
name: "example",
type: "network",
description: "Mixed access for marketing and sales",
policy: JSON.stringify([
{
Description: "Marketing access",
Rules: [
{
ResourceType: "collection",
Resource: ["collection/marketing*"],
},
{
ResourceType: "dashboard",
Resource: ["collection/marketing*"],
},
],
AllowFromPublic: false,
SourceVPCEs: ["vpce-050f79086ee71ac05"],
},
{
Description: "Sales access",
Rules: [{
ResourceType: "collection",
Resource: ["collection/finance"],
}],
AllowFromPublic: true,
},
]),
});
import pulumi
import json
import pulumi_aws as aws
example = aws.opensearch.ServerlessSecurityPolicy("example",
name="example",
type="network",
description="Mixed access for marketing and sales",
policy=json.dumps([
{
"Description": "Marketing access",
"Rules": [
{
"ResourceType": "collection",
"Resource": ["collection/marketing*"],
},
{
"ResourceType": "dashboard",
"Resource": ["collection/marketing*"],
},
],
"AllowFromPublic": False,
"SourceVPCEs": ["vpce-050f79086ee71ac05"],
},
{
"Description": "Sales access",
"Rules": [{
"ResourceType": "collection",
"Resource": ["collection/finance"],
}],
"AllowFromPublic": True,
},
]))
package main
import (
"encoding/json"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/opensearch"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
tmpJSON0, err := json.Marshal([]interface{}{
map[string]interface{}{
"Description": "Marketing access",
"Rules": []map[string]interface{}{
map[string]interface{}{
"ResourceType": "collection",
"Resource": []string{
"collection/marketing*",
},
},
map[string]interface{}{
"ResourceType": "dashboard",
"Resource": []string{
"collection/marketing*",
},
},
},
"AllowFromPublic": false,
"SourceVPCEs": []string{
"vpce-050f79086ee71ac05",
},
},
map[string]interface{}{
"Description": "Sales access",
"Rules": []map[string]interface{}{
map[string]interface{}{
"ResourceType": "collection",
"Resource": []string{
"collection/finance",
},
},
},
"AllowFromPublic": true,
},
})
if err != nil {
return err
}
json0 := string(tmpJSON0)
_, err = opensearch.NewServerlessSecurityPolicy(ctx, "example", &opensearch.ServerlessSecurityPolicyArgs{
Name: pulumi.String("example"),
Type: pulumi.String("network"),
Description: pulumi.String("Mixed access for marketing and sales"),
Policy: 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.OpenSearch.ServerlessSecurityPolicy("example", new()
{
Name = "example",
Type = "network",
Description = "Mixed access for marketing and sales",
Policy = JsonSerializer.Serialize(new[]
{
new Dictionary<string, object?>
{
["Description"] = "Marketing access",
["Rules"] = new[]
{
new Dictionary<string, object?>
{
["ResourceType"] = "collection",
["Resource"] = new[]
{
"collection/marketing*",
},
},
new Dictionary<string, object?>
{
["ResourceType"] = "dashboard",
["Resource"] = new[]
{
"collection/marketing*",
},
},
},
["AllowFromPublic"] = false,
["SourceVPCEs"] = new[]
{
"vpce-050f79086ee71ac05",
},
},
new Dictionary<string, object?>
{
["Description"] = "Sales access",
["Rules"] = new[]
{
new Dictionary<string, object?>
{
["ResourceType"] = "collection",
["Resource"] = new[]
{
"collection/finance",
},
},
},
["AllowFromPublic"] = true,
},
}),
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.opensearch.ServerlessSecurityPolicy;
import com.pulumi.aws.opensearch.ServerlessSecurityPolicyArgs;
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 ServerlessSecurityPolicy("example", ServerlessSecurityPolicyArgs.builder()
.name("example")
.type("network")
.description("Mixed access for marketing and sales")
.policy(serializeJson(
jsonArray(
jsonObject(
jsonProperty("Description", "Marketing access"),
jsonProperty("Rules", jsonArray(
jsonObject(
jsonProperty("ResourceType", "collection"),
jsonProperty("Resource", jsonArray("collection/marketing*"))
),
jsonObject(
jsonProperty("ResourceType", "dashboard"),
jsonProperty("Resource", jsonArray("collection/marketing*"))
)
)),
jsonProperty("AllowFromPublic", false),
jsonProperty("SourceVPCEs", jsonArray("vpce-050f79086ee71ac05"))
),
jsonObject(
jsonProperty("Description", "Sales access"),
jsonProperty("Rules", jsonArray(jsonObject(
jsonProperty("ResourceType", "collection"),
jsonProperty("Resource", jsonArray("collection/finance"))
))),
jsonProperty("AllowFromPublic", true)
)
)))
.build());
}
}
resources:
example:
type: aws:opensearch:ServerlessSecurityPolicy
properties:
name: example
type: network
description: Mixed access for marketing and sales
policy:
fn::toJSON:
- Description: Marketing access
Rules:
- ResourceType: collection
Resource:
- collection/marketing*
- ResourceType: dashboard
Resource:
- collection/marketing*
AllowFromPublic: false
SourceVPCEs:
- vpce-050f79086ee71ac05
- Description: Sales access
Rules:
- ResourceType: collection
Resource:
- collection/finance
AllowFromPublic: true
A single network policy can contain multiple rule sets, each with different AllowFromPublic and SourceVPCEs settings. This example applies VPC-restricted access to collections matching “marketing*” and public access to the “finance” collection. Wildcard patterns and multiple rules combine to create flexible access controls.
Beyond these examples
These snippets focus on specific security policy features: encryption policies with AWS-managed and customer-managed keys, network policies for public and VPC-restricted access, and wildcard patterns for multi-collection policies. They’re intentionally minimal rather than full OpenSearch deployments.
The examples may reference pre-existing infrastructure such as KMS keys for customer-managed encryption and VPC endpoints for private network access. They focus on configuring security policies rather than provisioning the surrounding infrastructure.
To keep things focused, common security policy patterns are omitted, including:
- Data access policies (separate resource type)
- Policy versioning and updates
- Cross-account KMS key access
- Multiple VPC endpoint sources
These omissions are intentional: the goal is to illustrate how each security policy feature is wired, not provide drop-in OpenSearch modules. See the OpenSearch Serverless Security Policy resource reference for all available configuration options.
Let's configure AWS OpenSearch Serverless Security Policies
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Policy Types & Structure
Encryption Configuration
AWSOwnedKey: true) or customer-managed KMS keys (set AWSOwnedKey: false and provide KmsARN).Network Access Control
AllowFromPublic: true in the policy rules.AllowFromPublic: false and specify VPC endpoint IDs in the SourceVPCEs array.Resource Targeting
Resource array, such as collection/example* to match all collections starting with “example”.name/type, for example: pulumi import aws:opensearch/serverlessSecurityPolicy:ServerlessSecurityPolicy example example/encryption