What is SCP in AWS?

AWS Service Control Policies, or SCPs, are a feature provided by AWS Organizations to manage permissions for accounts within an organization. They act as guardrails, defining what actions are allowed or denied across all accounts. Unlike IAM policies, SCPs do not grant permissions directly. Instead, they set boundaries for what actions can be performed, regardless of the permissions specified in the account’s IAM policies.

For example, if an SCP denies the ability to delete S3 buckets, no user, role, or service in the affected accounts can delete a bucket, even if their IAM policy allows it. This makes sure that rules are followed across all accounts within that organization.

Without SCPs, a developer might accidentally delete an S3 bucket holding data like customer payment details, source code, or financial records. SCPs also protect audit and monitoring logs stored in S3, which are important for auditing. By enforcing these rules, SCPs make sure that resources remain secure and compliant.

How SCPs Work in AWS Organizations?

SCPs are managed at the organizational level and can be attached to organizational units (OUs), the root of the organization, or directly to specific AWS accounts. By default, every account in AWS Organizations has at least one SCP, known as the FullAWSAccess policy. This policy allows all actions unless any additional SCPs or account-level IAM policies limit them.

When you attach an SCP to an organizational unit, the policy automatically applies to all accounts within that organization. This includes any new accounts that are added later. SCPs serve as permission boundaries, meaning they define the maximum set of actions that accounts are allowed to perform. For an action to succeed, it must be allowed by both the SCP and the IAM policies in the account.

For example, if an SCP denies the creation of EC2 instances in a specific region, no IAM policy within an account governed by that SCP can override the restriction. This makes sure that the policies set at the organizational level are consistently enforced across all accounts.

How SCPs Differ from IAM Policies?

While both SCPs and IAM policies are used to manage permissions, they serve different purposes. IAM policies control what individual users, roles, or services can do within an account. SCPs, on the other hand, operate at a higher level, setting the maximum permissions available for accounts in the organization.

Consider a scenario where an IAM policy in an account allows users to create EC2 instances of any type. If an SCP attached to that account restricts instance types to only t2.micro, users will only be able to create t2.micro instances. Even though the IAM policy allows broader permissions, the SCP sets the upper limit of what is possible.

This layered approach is important for organizations with multiple accounts. SCPs act as a safeguard, making sure that key restrictions are applied consistently and cannot be bypassed, even by account administrators as well.

How Terraform Simplifies SCP Management

Now, managing these SCPs through the AWS Console can be slow and difficult as the number of accounts increases within the organization. Terraform makes this simple by letting you define and manage SCPs as code.

With Terraform, you can write SCPs in code and use versioning in a remote backend to track changes and updates as well. For example, you can create an SCP to restrict EC2 instance types to t2.micro and apply it to specific account groups like development environments. If updates are needed, such as adding a new instance type, you can modify the code and deploy the changes across all accounts easily.

Using Terraform makes managing SCPs faster, more reliable, and scalable, helping you maintain a secure and organized cloud environment.

Use Cases for AWS SCPs

Now that we understand what SCPs are and how they work, let’s look at some practical ways they can be used within an organization. 

  • Restricting Resource Creation to Specific Regions: Organizations often have compliance or regulatory requirements to keep their data within specific regions. For example, an organization working in Europe may need to make sure that all resources are created in ‘eu-west-1’ to comply with GDPR. An SCP can enforce this by denying actions that attempt to create resources in other regions like us-east-1 or ap-southeast-1. This makes sure that all accounts, regardless of their purpose, stick to the region-specific policy.
  • Preventing the Use of Costly Instance Types: Cloud costs can get out of hand if expensive resources are used without proper control. For example, GPU instances like p4d or large memory instances like r5.24xlarge are usually unnecessary in the development or testing environments. With SCPs, you can block such costly instance types and allow only more affordable options like t2.micro or t3.medium. This way, you can keep costs low while still giving teams the resources they need.
  • Enforcing Encryption for S3 Buckets: Now, protecting the data that is stored in S3 buckets is also important to make sure that it remains secure and meets the organization’s compliance standards. SCPs can enforce server-side encryption for all S3 buckets within the organization. For example, an SCP can block the creation of buckets unless encryption, such as AES-256 or AWS KMS, is enabled. This ensures data, like customer payment details or any type of financial records, is always encrypted.
  • Limiting IAM Role Creation: IAM roles are used to manage permissions, but allowing anyone within your team to create roles without any control can cause problems. For example, if a developer creates a role with too many permissions, it could give access to resources that should stay restricted. An SCP can block the creation of new roles or allow only specific administrators to create them. This makes sure that roles are created carefully and only by those who are authorized to manage permissions.

These use cases show how SCPs can help enforce policies, prevent misconfigurations, and maintain consistent governance across all the AWS accounts within that organization.

Planning and Structuring SCPs for Your Organization

Now that we’ve explored how SCPs work and their use cases, let’s look at how to plan and structure them for your AWS Organization. 

Proper planning makes SCPs easier to manage, scalable, and effective as your AWS environment scales. This involves grouping accounts into Organizational Units (OUs), knowing when to use SCPs instead of IAM policies, and organizing SCPs using Terraform.

Grouping Accounts into Organizational Units (OUs)

The first step in planning SCPs is grouping accounts into Organizational Units (OUs). OUs let you organize accounts by purpose, like production, development, or testing, and apply policies to each group as needed. For example:

  • Production OU: Apply strict SCPs that block unapproved regions, enforce encryption, and prevent costly instance types to ensure security and cost control.
  • Development OU: Apply flexible SCPs that allow some freedom for experimentation but still enforce basic rules, such as mandatory encryption.
  • Testing OU: Allow wider permissions but block unnecessary or expensive resources to keep costs under control.

This grouping makes sure that your SCPs are applied consistently across similar accounts, making management easier as new accounts are added to the organization. It’s also important to know when to use SCPs and when IAM policies are a better fit.

  • Use SCPs for broad, organization-wide rules. For example, blocking certain regions, requiring encryption, or restricting instance types. SCPs act as guardrails that apply to everyone in the account and cannot be bypassed.
  • Use IAM policies for more specific permissions within an account, like granting developers access to EC2 instances or S3 buckets.

For example, an SCP can enforce encryption across all accounts, while an IAM policy can define which users in a specific account can access encrypted buckets. This combination provides both control at the organization level and flexibility within accounts.

Hands-On: Using Terraform to Manage AWS SCPs

Now in this section, we will create and manage AWS Service Control Policies (SCPs) using Terraform. The goal here is to implement a policy that restricts EC2 instance launches, allowing only t2.micro instances and denying all others. This SCP will then be attached to an Organizational Unit (OU) in AWS Organizations, and we will validate its effectiveness by testing both allowed and denied instance types.

Defining the SCP Policy

The SCP itself is written in a JSON format that specifies what actions are allowed or denied across accounts in an OU. In this case, we’re creating a policy called allow-only-t2-nano.json. This policy blocks any attempt to launch EC2 instances unless the instance type is t2.micro.

Here’s the content of the SCP:

{ "Version": "2012-10-17", "Statement": [ { "Sid": "RequireMicroInstanceType", "Effect": "Deny", "Action": "ec2:RunInstances", "Resource": [ "arn:aws:ec2:*:*:instance/*" ], "Condition": { "StringNotEquals": { "ec2:InstanceType": "t2.micro" } } } ] }

This policy uses the Deny effect to prevent the ec2:RunInstances action unless the condition ec2:InstanceType equals t2.micro. This makes sure that no other instance types can be launched, providing strict control over resource usage.

Setting Up Terraform Configuration

Now, to automate the creation and attachment of an SCP to an Organizational Unit (OU), start by defining the necessary configuration in your Terraform file. The main.tf file will handle the creation of the SCP and its attachment to the specified OU.

Here's the code for main.tf:

terraform { required_providers { aws = { source = "hashicorp/aws" version = ">= 2.0.0" } } required_version = ">= 1.3.0" } provider "aws" { region = "us-east-1" } resource "aws_organizations_policy" "scp" { for_each = var.scps name = each.key description = each.value.description content = file(each.value.file) type = "SERVICE_CONTROL_POLICY" } resource "aws_organizations_policy_attachment" "scp_attachment" { for_each = var.scps policy_id = aws_organizations_policy.scp[each.key].id target_id = var.organization_unit_id }

In this configuration, the aws_organizations_policy resource creates the SCP, while the aws_organizations_policy_attachment resource attaches the SCP to the specified OU. The variables scps and organization_unit_id are used to provide inputs for the SCP details and the target OU ID.

Next, define a variables.tf file to store the input variables required for the Terraform configuration. This file specifies the SCP details, including the policy description, file path, and the target OU ID.

variable "scps" { default = { allow-only-t2-nano = { description = "Allow only t2.micro instances" file = "allow-only-t2-nano.json" } } } variable "organization_unit_id" { default = "r-52xi" }

The scps variable contains the details of the SCP to be created, while the organization_unit_id variable identifies the OU to which the SCP will be attached.

Applying the Terraform Configuration

Run terraform init to initialize the environment and then use terraform apply to create and attach the SCP to the specified OU. Once applied, the SCP will be active and enforce the defined restrictions across the accounts in the OU.

Verifying the SCP

Once the SCP is successfully applied, the next step is to test its effectiveness by attempting to launch EC2 instances with both allowed and denied instance types. This will ensure that the policy works as intended across the Organizational Unit (OU).

Testing Allowed Instance Type

Start by launching an EC2 instance of type t2.micro in an account within the OU. Since the SCP explicitly permits this instance type, the operation should succeed.

The instance of type t2.micro will launch successfully. As shown above, Terraform applied the SCP, and a t2.micro instance was created without any issues. This confirms that the SCP allows the defined instance type.

Testing Denied Instance Type

Next, attempt to launch an EC2 instance of type t2.nano. Since the SCP explicitly denies any instance type other than t2.micro, this action should fail.

This failure confirms that the SCP is successfully blocking the creation of instance types other than t2.micro. 

With the SCP applied and tested, we have successfully enforced strict control over EC2 instance launches using Terraform and AWS Organizations. By automating SCP creation and attachment, you ensure consistent governance across your AWS accounts within the organization.

Now, managing AWS Service Control Policies (SCPs) through the AWS console can be slow as your environments scale. Terraform made this easier by automating SCP creation as code. However, even with Terraform, keeping policies consistent and compliant can still take time.

Firefly takes this a step further. With its Guardrails feature, Firefly provides a no-code way to enforce rules, removing the need to write or manage Terraform files. It makes cloud governance faster, easier, and more reliable.

Using Firefly for Workflow Guardrails

Firefly Guardrails allow you to set up automated rules that enforce policies and best practices across your cloud infrastructure. Instead of managing policies through console or writing Terraform configurations, you can use an intuitive interface to define, scope, and enforce rules. If changes violate these rules, Firefly blocks deployments and alerts your team to make sure that your cloud environment remains compliant.

Guardrails are built to automate three key areas: enforcing policies, promoting best practices, and maintaining compliance. For example, you can block deployments of unapproved EC2 instance types, ensure S3 buckets have encryption enabled, or enforce resource tagging to keep cloud costs under control. If a deployment violates these standards, Firefly stops it and immediately notifies the team, preventing misconfigurations before they are deployed.

Creating a Guardrail is simple with Firefly’s no-code Guardrails Wizard. You begin by choosing the type of rule to create, whether for enforcing resource policies, controlling costs, or ensuring compliance. 

Once the rule type is set, you can define the scope, where the rule applies by targeting specific workspaces, repositories, branches, or labels.

You can exclude specific items if needed or use wildcards to apply the rule broadly, such as across all production workspaces.

For example, let’s say you need to enforce a rule that allows only t2.micro EC2 instances to be launched. With Firefly, you define this rule as a policy within the Guardrails Wizard, specifying the scope to include production environments and exclude development branches. 

After defining the rule, you set its criteria; what the Guardrail will enforce and assign a severity level. Firefly makes sure that the rule is applied across the specified environments, blocking any non-compliant EC2 instances and alerting your team if a violation occurs.

Firefly also simplifies communication by sending notifications to your preferred channels. If a Guardrail is triggered, your team can receive alerts through Slack, email, or other integrations, making sure that issues are caught and resolved quickly. 

This eliminates the need for digging through logs to identify policy violations.

With Guardrails, Firefly makes policy enforcement easy and automatic. You don’t need to manage Terraform configuration files, fix misconfigurations, or worry about inconsistent policies. Firefly takes care of everything, applying rules across your cloud setup and keeping everything aligned with your organization’s standards.

Moving from manual SCP management to Terraform and now to Firefly, cloud governance becomes faster and simpler. Firefly helps your team focus on building, while Guardrails work in the background to keep your environment secure, compliant, and well-organized.