DEV Community

Cover image for Terraforming Resource Control Policies
Dustin Whited for AWS Community Builders

Posted on

7 1

Terraforming Resource Control Policies

AWS released a new type of organizational authorizational policy called Resource Control Policies (RCPs). This policy is considered a "resource-centric" policy, complementary to Service Control Policies "principal-centric" preventative guardrails.

See the AWS release blog for more info about RCPs: https://aws.amazon.com/blogs/aws/introducing-resource-control-policies-rcps-a-new-authorization-policy/

Terraforming

One of the first questions I ask with a new AWS feature or service is "how do I automate it?" For RCPs, I asked a similar question and found that the AWS provider in Terraform had support as of version 5.76.0.

First, ensure you have the policy type enabled on your organization via "ALL" or "RESOURCE_CONTROL_POLICY" like shown below. This will enable RCPs as well as attach RCPFullAWSAccess.

resource "aws_organizations_organization" "org" {
  feature_set          = "ALL"
  enabled_policy_types = [
    "AISERVICES_OPT_OUT_POLICY",
    "SERVICE_CONTROL_POLICY",
    "RESOURCE_CONTROL_POLICY",
    ]
}
Enter fullscreen mode Exit fullscreen mode

Ensure your provider is up to 5.76. You could also use "~> 5.0".

See Version Constraints documentation for more info on how this works https://developer.hashicorp.com/terraform/language/expressions/version-constraints


terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "~> 5.76"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Now you can create a RCP. I'm using the confused deputy prevention example provided from aws-samples. Note that RCPs have similar limits to SCPs. You can only attach 5 per entity (OU and account), RCPFullAWSAccess counts against the limit, and they have a character limit of 5120 that includes whitespace.

data "aws_iam_policy_document" "rcp1" {
  statement {
    effect = "Deny"

    actions = [
      "s3:*",
      "sqs:*",
      "kms:*",
      "secretsmanager:*",
      "sts:*",
    ]

    resources = ["*"]

    principals {
      type        = "*"
      identifiers = ["*"]
    }

    condition {
      test     = "StringNotEqualsIfExists"
      variable = "aws:SourceOrgID"

      values = [
        aws_organizations_organization.org.id
      ]
    }

    condition {
      test     = "Null"
      variable = "aws:SourceAccount"

      values = [
        "false"
      ]
    }

    condition {
      test     = "Bool"
      variable = "aws:PrincipalIsAWSService"

      values = [
        "true"
      ]
    }
  }
}

resource "aws_organizations_policy" "rcp1" {
  name    = "rcp1"
  content = data.aws_iam_policy_document.rcp1.json
  type    = "RESOURCE_CONTROL_POLICY"
}
Enter fullscreen mode Exit fullscreen mode

If you are combining multiple RCPs into a single aws_iam_policy_document, you may want to use minified_json instead of json on the content argument.

resource "aws_organizations_policy" "rcp1" {
  name    = "rcp1"
  content = data.aws_iam_policy_document.rcp1.minified_json
  type    = "RESOURCE_CONTROL_POLICY"
}
Enter fullscreen mode Exit fullscreen mode

And finally, attach it to an entity. In this case, I am attaching it to an OU I have called "dev" under the organization root.

resource "aws_organizations_organizational_unit" "dev" {
  name      = "dev"
  parent_id = aws_organizations_organization.org.roots[0].id
}

resource "aws_organizations_policy_attachment" "rcp1_dev" {
  policy_id = aws_organizations_policy.rcp1.id
  target_id = aws_organizations_organizational_unit.dev.id
}
Enter fullscreen mode Exit fullscreen mode

It's very nice to see Terraform provider support so quickly for a new release, especially on governance features.

Happy RCP'ing!

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more

Top comments (0)

Best Practices for Running  Container WordPress on AWS (ECS, EFS, RDS, ELB) using CDK cover image

Best Practices for Running Container WordPress on AWS (ECS, EFS, RDS, ELB) using CDK

This post discusses the process of migrating a growing WordPress eShop business to AWS using AWS CDK for an easily scalable, high availability architecture. The detailed structure encompasses several pillars: Compute, Storage, Database, Cache, CDN, DNS, Security, and Backup.

Read full post

👋 Kindness is contagious

Dive into an ocean of knowledge with this thought-provoking post, revered deeply within the supportive DEV Community. Developers of all levels are welcome to join and enhance our collective intelligence.

Saying a simple "thank you" can brighten someone's day. Share your gratitude in the comments below!

On DEV, sharing ideas eases our path and fortifies our community connections. Found this helpful? Sending a quick thanks to the author can be profoundly valued.

Okay