How to make AWS SCPs By Terraform
Prerequirsite:-
IAM user with Administrator Permission
AWS cli and Do AWS configure{Enter access key and secrets key here (iam user)}
Install Terraform
How to install terraform in Linux
sudo apt-get update && sudo apt-get install -y gnupg software-properties-common
wget -O- https://apt.releases.hashicorp.com/gpg | \
gpg --dearmor | \
sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg > /dev/null
gpg --no-default-keyring \
--keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg \
--fingerprint
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
https://apt.releases.hashicorp.com $(lsb_release -cs) main" | \
sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update
sudo apt-get install terraform
For SCPs You have to make some files
main.tf
output.tf
terraform.tfvars
variable.tf
policies/scp_policies.json
provider "aws" {
region = var.aws_region
}
resource "aws_organizations_policy" "custom_scp_policy" {
name = "CustomSCP"
description = "A custom SCP policy"
content = file("${path.module}/policies/scp_policy.json")
type = "SERVICE_CONTROL_POLICY"
}
resource "aws_organizations_policy_attachment" "custom_scp_policy_attachment" {
policy_id = aws_organizations_policy.custom_scp_policy.id
target_id = var.target_id
}
Creates an AWS Organizations policy.
The policy is named "CustomSCP" and has a description.
The policy content is loaded from a file (
scp_policy.json
) located in thepolicies
directory within the module path.The type of policy is
SERVICE_CONTROL_POLICY
.Attaches the previously created policy to a target.
The
policy_id
is referenced from theaws_organizations_policy
resource.The
target_id
is provided by thetarget_id
variable and determines where the policy is applied (e.g., an AWS account or organizational unit).
output.tf
output "scp_policy_id" {
description = "The ID of the created SCP policy"
value = aws_organizations_policy.custom_scp_policy.id
}
Output Declaration:
Outputs the ID of the created Service Control Policy (SCP) so it can be used elsewhere.
The
description
provides context about what the output represents.The
value
references theid
of theaws_organizations_policy
resource.
terraform.tfvars
aws_region = "eu-west-1"
target_id = "590183704217" # Replace with your AWS account ID or organizational unit ID
Variable Values:
Sets the values for the variables defined in
variable.tf
.aws_region
specifies the AWS region (e.g.,eu-west-1
).target_id
is the AWS account ID or organizational unit ID to which the SCP policy will be attached.
variable.tf
variable "aws_region" {
description = "The AWS region to deploy in"
default = "eu-west-1"
}
variable "target_id" {
description = "The ID of the AWS account or organizational unit to attach the SCP to"
type = string
}
Variable Declaration:
aws_region
:Description: Specifies the AWS region for deployment.
Default Value:
eu-west-1
, which can be overridden byterraform.tfvars
.
target_id
:Description: Specifies the ID of the target (AWS account or organizational unit) for the SCP policy attachment.
Type:
string
, as it will hold a string representing the ID.
Summary
main.tf
: Contains the primary Terraform configuration for creating and attaching an AWS Organizations policy.output.tf
: Defines outputs to expose information about the created policy.terraform.tfvars
: Provides specific values for variables used in the configuration.variable.tf
: Declares the variables used in the configuration, including descriptions and default values.
Make a folder policies/scp_policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
"StringNotEquals": {
"ec2:MetadataHttpTokens": "required"
}
}
},
{
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
"NumericGreaterThan": {
"ec2:MetadataHttpPutResponseHopLimit": "3"
}
}
},
{
"Effect": "Deny",
"Action": "*",
"Resource": "*",
"Condition": {
"NumericLessThan": {
"ec2:RoleDelivery": "2.0"
}
}
},
{
"Effect": "Deny",
"Action": "ec2:ModifyInstanceMetadataOptions",
"Resource": "*"
}
]
}
Adding a New Policy
If you want to add another policy to your setup, you need to:
Create a new policy JSON file in the
policies
folder, e.g.,scp_policy_2.json
.Update
main.tf
:Add a new
aws_organizations_policy
resource that references the new policy file.Add a new
aws_organizations_policy_attachment
resource for the new policy.
Example for a New Policy
Assume you create scp_policy_2.json
with similar or different content. Update main.tf
as follows:
hclCopy code# Define the new policy
resource "aws_organizations_policy" "custom_scp_policy_2" {
name = "CustomSCP2"
description = "The second custom SCP policy"
content = file("${path.module}/policies/scp_policy_2.json")
type = "SERVICE_CONTROL_POLICY"
}
# Attach the new policy
resource "aws_organizations_policy_attachment" "custom_scp_policy_attachment_2" {
policy_id = aws_organizations_policy.custom_scp_policy_2.id
target_id = var.target_id
}
Summary
Subscribe to my newsletter
Read articles from Sarthak Tyagi directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by