The aws:organizations/policyAttachment:PolicyAttachment resource, part of the Pulumi AWS provider, attaches an AWS Organizations policy to a target: an account, organizational unit, or the organization root. This guide focuses on three attachment scopes: account-level, root-level, and OU-level attachment.
Policy attachments reference existing policies and organization structure elements. The examples are intentionally small. Combine them with your own policy definitions and organization hierarchy.
Attach a policy to an individual account
Organizations often apply policies to specific member accounts, such as enforcing tagging standards or restricting service usage for development accounts.
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 policyId references an existing policy, and targetId specifies the account number. Policies attached at the account level apply only to that account, overriding or supplementing inherited policies from parent OUs or the root.
Attach a policy to the organization root
Policies attached at the root level cascade to all accounts in the organization, providing baseline controls.
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}
The targetId references the organization’s root ID, extracted from the Organization resource. Root-level policies apply organization-wide and are inherited by all OUs and accounts unless overridden.
Attach a policy to an organizational unit
Organizational units group accounts by function or environment, allowing you to apply policies to entire teams without targeting individual accounts.
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 OU ID from an OrganizationalUnit resource. Policies attached to an OU apply to all accounts within that OU and any nested OUs, cascading down the hierarchy.
Beyond these examples
These snippets focus on specific attachment scopes: account, root, and OU-level attachment. They’re intentionally minimal rather than complete policy governance solutions.
The examples reference pre-existing infrastructure such as Organizations policies (Service Control Policies, Tag Policies, etc.) and organization structure (root, OUs, member accounts). They focus on attaching policies rather than creating them.
To keep things focused, common attachment patterns are omitted, including:
- Policy lifecycle management (skipDestroy)
- Policy creation and content definition
- Multiple policy attachments to the same target
- Conditional attachment based on account attributes
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
Policy Attachment Configuration
policyId and targetId are immutable. Changing either property requires replacing the resource.Lifecycle Management
skipDestroy to true removes the resource from Pulumi state without detaching the policy from AWS. Use this when you need to preserve the attachment to meet AWS’s minimum requirement of 1 attached policy.