Git Product home page Git Product logo

terraform-aws-ou-scp's Introduction

AWS OU SCP Terraform Module

Supports two main use cases:

  • Combines multiple Service Control Policy (SCP) statements - based on the module terraform-aws-org-scp (deprecated). Combining multiple policy statements into a single policy allows more than 5 policies to be be applied to a single Organizational Unit (OU).
  • Alternatively, creates a "Deny All Access" Service Control Policy.

Alternatively, enables creation of a "Deny All Access" Service Control Policy.

Policy options (listed by sid) are:

  • Deny leaving AWS Organizations (DenyLeavingOrgs)
  • Deny creating IAM users or access keys (DenyCreatingIAMUsers)
  • Deny deleting KMS Keys (DenyDeletingKMSKeys)
  • Deny deleting Route53 Hosted Zones (DenyDeletingRoute53Zones)
  • Deny deleting VPC Flow logs, Cloudwatch log groups, and Cloudwatch log streams (DenyDeletingCloudwatchLogs)
  • Deny root account (DenyRootAccount)
  • Protect S3 Buckets (ProtectS3Buckets)
  • Deny S3 Buckets Public Access (DenyS3BucketsPublicAccess)
  • Protect IAM Roles (ProtectIAMRoles)
  • Restrict EC2 Instance Types (LimitEC2InstanceTypes)
  • Restrict Regional Operations (LimitRegions)
  • Require S3 encryption (DenyIncorrectEncryptionHeader + DenyUnEncryptedObjectUploads)

Usage for combined policy statements

To include a policy in your combined policy block, set it to true. Otherwise omit the policy variable.

module "github_terraform_aws_ou_scp" {
  source = "trussworks/ou-scp/aws"
  target =  aws_organizations_organizational_unit.my_ou

  # don't allow all accounts to be able to leave the org
  deny_leaving_orgs             = true
  # applies to accounts that are not managing IAM users
  deny_creating_iam_users       = true
  # don't allow deleting KMS keys
  deny_deleting_kms_keys        = true
  # don't allow deleting Route53 zones
  deny_deleting_route53_zones   = true
  # don't allow deleting CloudWatch logs
  deny_deleting_cloudwatch_logs = true
  # don't allow access to the root user
  deny_root_account             = true

  protect_s3_buckets            = true
  # protect terraform statefile bucket
  protect_s3_bucket_resources   = [
    "arn:aws:s3:::prod-terraform-state-us-west-2",
    "arn:aws:s3:::prod-terraform-state-us-west-2/*"
  ]

  # don't allow public access to bucket
  deny_s3_buckets_public_access = true
  deny_s3_bucket_public_access_resources = [
    "arn:aws:s3:::log-delivery-august-2020"
  ]

  protect_iam_roles             = true
  # - protect OrganizationAccountAccessRole
  protect_iam_role_resources     = [
    "arn:aws:iam::*:role/OrganizationAccountAccessRole"
  ]

  # restrict EC2 instance types
  limit_ec2_instance_types   = true
  allowed_ec2_instance_types = ["t2.medium"]

  # restrict region-specific operations to us-west-2
  limit_regions                 = true
  # - restrict region-specific operations to us-west-2
  allowed_regions               = ["us-west-2"]

  # require s3 objects be encrypted
  require_s3_encryption = true

  # SCP policy tags
  tags = {
    managed_by = "terraform"
  }
}

Usage for a policy which denies all access

module "github_terraform_aws_ou_scp" {
  source = "trussworks/ou-scp/aws"
  target =  aws_organizations_organizational_unit.my_ou

  # don't allow any access at all
  deny_all=true
}

Requirements

Name Version
terraform >= 1.0
aws >= 3.0

Providers

Name Version
aws >= 3.0

Modules

No modules.

Resources

Name Type
aws_organizations_policy.generated resource
aws_organizations_policy_attachment.generated resource
aws_iam_policy_document.combined_policy_block data source
aws_iam_policy_document.deny_all_access data source

Inputs

Name Description Type Default Required
allowed_ec2_instance_types EC2 instances types allowed for use list(string) [ "" ] no
allowed_regions AWS Regions allowed for use (for use with the restrict regions SCP) list(string) [ "" ] no
deny_all If false, create a combined policy. If true, deny all access bool false no
deny_creating_iam_users DenyCreatingIAMUsers in the OU policy. bool false no
deny_deleting_cloudwatch_logs DenyDeletingCloudwatchLogs in the OU policy. bool false no
deny_deleting_kms_keys DenyDeletingKMSKeys in the OU policy. bool false no
deny_deleting_route53_zones DenyDeletingRoute53Zones in the OU policy. bool false no
deny_leaving_orgs DenyLeavingOrgs in the OU policy. bool false no
deny_root_account DenyRootAccount in the OU policy. bool false no
deny_s3_bucket_public_access_resources S3 bucket resource ARNs to block public access list(string) [ "" ] no
deny_s3_buckets_public_access DenyS3BucketsPublicAccess in the OU policy. bool false no
limit_ec2_instance_types LimitEC2InstanceTypes in the OU policy. bool false no
limit_regions LimitRegions in the OU policy. bool false no
protect_iam_role_resources IAM role resource ARNs to protect from modification and deletion list(string) [ "" ] no
protect_iam_roles ProtectIAMRoles in the OU policy. bool false no
protect_s3_bucket_resources S3 bucket resource ARNs to protect from bucket and object deletion list(string) [ "" ] no
protect_s3_buckets ProtectS3Buckets in the OU policy. bool false no
require_s3_encryption DenyIncorrectEncryptionHeader and DenyUnEncryptedObjectUploads in the OU policy bool false no
tags Tags applied to the SCP policy map(string) {} no
target OU resource to attach SCP object({ name = string id = string }) n/a yes

Outputs

No outputs.

Developer Setup

Install dependencies (macOS)

brew install pre-commit go terraform terraform-docs
pre-commit install --install-hooks

terraform-aws-ou-scp's People

Contributors

avanti-joshi avatar chrisgilmerproj avatar coryattruss avatar dependabot-preview[bot] avatar dustinchilson avatar eeeady avatar esacteksab avatar github-actions[bot] avatar linuxbozo avatar mbevc1 avatar mdawn avatar mdrummerboy09 avatar mr337 avatar pjdufour-dds avatar ralren avatar renovate-bot avatar renovate[bot] avatar rpdelaney avatar sheenamt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

terraform-aws-ou-scp's Issues

pricing:* needs to be in the not_actions when limiting regions

We have identified the AWS Console shows some errors since we moved a Sandbox AWS account to a new AWS Organization where we are implementing AWS Organization SCPs.

image

The OU is using this configuration:

module "aws_org_scp_ou_sandbox" {
  source    = "trussworks/ou-scp/aws"
  version   = "~> 1.4.0"

  target    = aws_organizations_organizational_unit.sandbox

  deny_leaving_orgs             = true
  deny_root_account             = true
  protect_iam_roles             = true
  protect_iam_role_resources    = [
    "arn:aws:iam::*:role/OrganizationAccountAccessRole"
  ]
  limit_regions                 = true
  allowed_regions               = ["us-east-2"]
  require_s3_encryption = true

}

Looks like the Pricing API is not a regional service so far and it's only available in us-east-1 and ap-south-1. For this reason, like it happens with IAM or Organizations, should not be restricted as part of the SCPs.
https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/using-pelong.html (see Service endpoint)

We are willing to send the PR upstream as soon as our time allows

Enforcing AWS S3 SSE

Hello,

We are using this Terraform module in order to enforce AWS SSE encryption in the org and we found an unexpected behaviour we would like to share with you.

We created an AWS S3 bucket with default AWS SSE using Amazon key (AWS-SSE). We also enabled require_s3_encryption = true and as result the following policy was added:

{
      "Sid": "DenyIncorrectEncryptionHeader",
      "Effect": "Deny",
      "Action": "s3:PutObject",
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "s3:x-amz-server-side-encryption": [
            "AES256",
            "aws:kms"
          ]
        }
      }
    },
    {
      "Sid": "DenyUnEncryptedObjectUploads",
      "Effect": "Deny",
      "Action": "s3:PutObject",
      "Resource": "*",
      "Condition": {
        "Null": {
          "s3:x-amz-server-side-encryption": [
            "true"
          ]
        }
      }

Our surprise is that a third party software that we run in AWS, as well as AWS CLI s3:PutObject operations, were failing.

The expected behaviour (our expected behaviour) was that given that the target AWS S3 bucket already has default AWS SSE enabled, the PutObject operations would succeed and would be allowed by the policy. Unfortunately, they are blocked.

We have been thinking on disabling this SCP, and instead, deny abt s3:CreateObject that does not have the correct setting of AWS SSE enabled. Unfortunately, this could be disabled afterwards, unless explicitely denied ๐Ÿคท .

What is your recommendation on the best and more resilient practices, especially when third-party software writes into S3 and we depend on the vendor to adapt the code to enable AWS SSE?

access-analyzer:* needs to be in the not_actions when limiting regions

Tried to raise a pull request but got a 403.

However, the issue is very simple. When limiting regions, I noticed that the Access Analyzer stopped working.

This can be solved by adding this to the not_actions like this:

  #
  # Restrict Regional Operations
  #

  dynamic "statement" {
    for_each = local.limit_regions_statement
    content {
      sid    = "LimitRegions"
      effect = "Deny"

      # These actions do not operate in a specific region, or only run in
      # a single region, so we don't want to try restricting them by region.
      not_actions = [
        "access-analyzer:*",  # <--- this has been added
        "iam:*",
        "organizations:*",
        "route53:*",
        "budgets:*",
        "waf:*",
        "cloudfront:*",
        "globalaccelerator:*",
        "importexport:*",
        "support:*",
        "sts:*"
      ]

      resources = ["*"]

      condition {
        test     = "StringNotEquals"
        variable = "aws:RequestedRegion"
        values   = var.allowed_regions
      }
    }
  }

Dependabot couldn't find a go.mod for this project

Dependabot couldn't find a go.mod for this project.

Dependabot requires a go.mod to evaluate your project's current Go dependencies. It had expected to find one at the path: /go.mod.

If this isn't a Go project, or if it is a library, you may wish to disable updates for it in the .dependabot/config.yml file in this repo.

View the update logs.

Add suport to multiple targets

Is your feature request related to a problem? Please describe.
No

Describe the solution you'd like
Add support for multiple targets. Currently, the module accepts a single parameter as target. In some cases, we may have multiple organizations in AWS and we want several of them to have the same policy.

Describe alternatives you've considered
We can deprecate the target variable and create a new one called targets that allos us to send a list of OUs

targets =  [aws_organizations_organizational_unit.my_ou1, aws_organizations_organizational_unit.my_ou2]

Region limit can't be used together with Control Tower

hey guys! I really like your module! just found one limitation and wants to share it with you as I don't know how to deal with it...

If you use region restriction and AWS Control Tower, then you won't be able to enroll new account in your AWS ORganization. Control tower says applied SCP is in conflict with Control Tower.

I guess it will be because control tower wants to enable all required services across all govern regions. And govern regions != region limited by scp.

In this light, I consider region limit in your module as "almost useless or difficult to use". But I can imagine some people can find these feature useful as not everyone uses Control Tower..so maybe we should add some warning into documentation, don't you think?

Unknown Target Value

I'd first like to say thank you for putting the initial work into this module. It looks like it will be really helpful! I'm running into an issue that I hope is easy to resolve..

The description of the required value for target is a little vague.. Is this module expecting the ARN, ID, a name tag of the desired OU you wish to apply these SCP's to or something else?

Since I already have a handful of OU's deployed to my organization, I want to perform a data lookup on a specific OU for testing.

data "aws_organizations_organization" "my_org" { }

data "aws_organizations_organizational_units" "my_ou" {
   parent_id = data.aws_organizations_organization.my_ord.roots[0].id
}
module "aws_govcloud_ou_scps" {
  source  = "trussworks/ou-scp/aws"
  version = "1.2.1"

  target = data.aws_organizations_organizational_units.my_ou
  .
  ..
  ...
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.