The aws:organizations/policyAttachment:PolicyAttachment resource, part of the Pulumi AWS provider, attaches an AWS Organizations policy to an account, organizational unit, or organization root. This guide focuses on three attachment scopes: individual accounts, organizational units, and the organization root.
Policy attachments reference existing policies and organization structure. The examples are intentionally small. Combine them with your own policy definitions and organization hierarchy.
Attach a policy to an individual account
Teams often apply policies to specific member accounts to enforce tagging standards or restrict service usage.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const account = new aws.organizations.PolicyAttachment("account", {
policyId: example.id,
targetId: "123456789012",
});
import pulumi
import pulumi_aws as aws
account = aws.organizations.PolicyAttachment("account",
policy_id=example["id"],
target_id="123456789012")
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/organizations"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := organizations.NewPolicyAttachment(ctx, "account", &organizations.PolicyAttachmentArgs{
PolicyId: pulumi.Any(example.Id),
TargetId: pulumi.String("123456789012"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var account = new Aws.Organizations.PolicyAttachment("account", new()
{
PolicyId = example.Id,
TargetId = "123456789012",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.organizations.PolicyAttachment;
import com.pulumi.aws.organizations.PolicyAttachmentArgs;
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 account = new PolicyAttachment("account", PolicyAttachmentArgs.builder()
.policyId(example.id())
.targetId("123456789012")
.build());
}
}
resources:
account:
type: aws:organizations:PolicyAttachment
properties:
policyId: ${example.id}
targetId: '123456789012'
The targetId property specifies the AWS account ID where the policy applies. The policyId references an existing Organizations policy. Account-level attachments affect only the specified account, not its children in the organization hierarchy.
Attach a policy to the organization root
Root-level attachments establish baseline controls that affect every account in the organization.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const root = new aws.organizations.PolicyAttachment("root", {
policyId: example.id,
targetId: exampleAwsOrganizationsOrganization.roots[0].id,
});
import pulumi
import pulumi_aws as aws
root = aws.organizations.PolicyAttachment("root",
policy_id=example["id"],
target_id=example_aws_organizations_organization["roots"][0]["id"])
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/organizations"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := organizations.NewPolicyAttachment(ctx, "root", &organizations.PolicyAttachmentArgs{
PolicyId: pulumi.Any(example.Id),
TargetId: pulumi.Any(exampleAwsOrganizationsOrganization.Roots[0].Id),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var root = new Aws.Organizations.PolicyAttachment("root", new()
{
PolicyId = example.Id,
TargetId = exampleAwsOrganizationsOrganization.Roots[0].Id,
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.organizations.PolicyAttachment;
import com.pulumi.aws.organizations.PolicyAttachmentArgs;
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 root = new PolicyAttachment("root", PolicyAttachmentArgs.builder()
.policyId(example.id())
.targetId(exampleAwsOrganizationsOrganization.roots()[0].id())
.build());
}
}
resources:
root:
type: aws:organizations:PolicyAttachment
properties:
policyId: ${example.id}
targetId: ${exampleAwsOrganizationsOrganization.roots[0].id}
When you attach a policy to the organization root, it applies to all accounts. The targetId references the root ID from your organization structure. Root attachments create organization-wide guardrails that cannot be bypassed by individual accounts.
Attach a policy to an organizational unit
Organizational units group accounts by function or environment, allowing policy application to entire departments.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const unit = new aws.organizations.PolicyAttachment("unit", {
policyId: example.id,
targetId: exampleAwsOrganizationsOrganizationalUnit.id,
});
import pulumi
import pulumi_aws as aws
unit = aws.organizations.PolicyAttachment("unit",
policy_id=example["id"],
target_id=example_aws_organizations_organizational_unit["id"])
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/organizations"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := organizations.NewPolicyAttachment(ctx, "unit", &organizations.PolicyAttachmentArgs{
PolicyId: pulumi.Any(example.Id),
TargetId: pulumi.Any(exampleAwsOrganizationsOrganizationalUnit.Id),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var unit = new Aws.Organizations.PolicyAttachment("unit", new()
{
PolicyId = example.Id,
TargetId = exampleAwsOrganizationsOrganizationalUnit.Id,
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.organizations.PolicyAttachment;
import com.pulumi.aws.organizations.PolicyAttachmentArgs;
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 unit = new PolicyAttachment("unit", PolicyAttachmentArgs.builder()
.policyId(example.id())
.targetId(exampleAwsOrganizationsOrganizationalUnit.id())
.build());
}
}
resources:
unit:
type: aws:organizations:PolicyAttachment
properties:
policyId: ${example.id}
targetId: ${exampleAwsOrganizationsOrganizationalUnit.id}
The targetId references an organizational unit ID. Policies attached to an OU apply to all accounts within that OU and any nested OUs. This enables department-level or environment-level policy enforcement without managing individual account attachments.
Beyond these examples
These snippets focus on specific attachment scopes: account, root, and OU-level attachments. They’re intentionally minimal rather than complete policy governance solutions.
The examples reference pre-existing infrastructure such as AWS Organizations policies (Service Control Policies, Tag Policies, etc.) and organization structure (accounts, OUs, root). They focus on creating attachments rather than defining policy content or organization structure.
To keep things focused, common attachment patterns are omitted, including:
- skipDestroy for preserving required policy attachments
- Policy creation and content definition
- Multiple policy attachments to the same target
These omissions are intentional: the goal is to illustrate how policy attachments are wired, not provide drop-in governance modules. See the Organizations PolicyAttachment resource reference for all available configuration options.
Let's attach AWS Organizations Policies
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Lifecycle & State Management
skipDestroy is set to true, destroying the resource removes it from Pulumi state without detaching the policy from the target. This is useful when you need to preserve the attachment to meet AWS’s minimum requirement of one attached policy.policyId and targetId are immutable. Changing either property forces Pulumi to replace the resource with a new attachment.targetId:policyId when importing. For example, to import an attachment to account 123456789012 with policy p-12345678, use 123456789012:p-12345678.