In this challenge, you will see how you can apply policies using Sentinel Policy-as-Code.
Within Terraform Cloud/Enterprise, click on your organization -> Organization Settings
https://app.terraform.io/app/YOUR_ORG_NAME/settings/policies
First we need a place to store our policies, namely a Policy Set.
On the left menu, click the "Policy set" tab.
Click "Connect a new policy set"
As Sentinel Policies are code they are typically saved to Version Control, so we can select the code repository in our VCS providers in which our Sentinel policies reside. We are going to add a VCS connection later, so we will select No VCS Connection
at this time.
Create the following policy:
Create the following policy:
Name: GlobalWorkspacePolicies
Description: Global policies.
Scope of Policies: Select -> "Policies enforced on all workspaces"
Click "Connect policy set"
Now lets create a Policy to enforce governance.
Under Policies
- click "Create new policy"
Create the following policy:
Policy Name: RequireMandatoryTags
Description: Policy Enforcing Mandatory Tags and Allowed Sizes
Policy Enforcement: advisory (logging only)
Policy Code:
# Imports mock data
import "tfplan/v2" as tfplan
# Get all AWS instances from all modules
ec2_instances = filter tfplan.resource_changes as _, rc {
rc.type is "aws_instance" and
(rc.change.actions contains "create" or rc.change.actions is ["update"])
}
# Mandatory Instance Tags
mandatory_tags = [
"Name",
]
# Allowed Types
allowed_types = [
"t2.micro",
"t2.small",
"t2.medium",
]
# Rule to enforce "Name" tag on all instances
mandatory_instance_tags = rule {
all ec2_instances as _, instance {
all mandatory_tags as mt {
instance.change.after.tags contains mt
}
}
}
# Rule to restrict instance types
instance_type_allowed = rule {
all ec2_instances as _, instance {
instance.change.after.instance_type in allowed_types
}
}
# Main rule that requires other rules to be true
main = rule {
(instance_type_allowed and mandatory_instance_tags) else true
}
Policy Sets: Select the Policy Set we just created "GlobalWorkspacePolicies". (And be sure to click the add button to the right to Add policy set
) and then click Create Policy
Note: be sure to discard any existing plans.
Navigate to your "webserver-aws-dev" workspace and queue a plan.
Will see the plan was successful along with a pass with the policy. This is because we are setting the required size and tags correctly inside our module. This is the benefit of using approved private modules that are in accordance with our security policies.
Update the Sentinel Policy to now make the Bogus
tag mandatory. This is something our server module doesn't account for.
# Imports mock data
import "tfplan/v2" as tfplan
# Get all AWS instances from all modules
ec2_instances = filter tfplan.resource_changes as _, rc {
rc.type is "aws_instance" and
(rc.change.actions contains "create" or rc.change.actions is ["update"])
}
# Mandatory Instance Tags
mandatory_tags = [
"Name",
"Bogus",
]
# Allowed Types
allowed_types = [
"t2.micro",
"t2.small",
"t2.medium",
]
# Rule to enforce "Name" tag on all instances
mandatory_instance_tags = rule {
all ec2_instances as _, instance {
all mandatory_tags as mt {
instance.change.after.tags contains mt
}
}
}
# Rule to restrict instance types
instance_type_allowed = rule {
all ec2_instances as _, instance {
instance.change.after.instance_type in allowed_types
}
}
# Main rule that requires other rules to be true
main = rule {
(instance_type_allowed and mandatory_instance_tags) else true
}
Will see the plan was successful, but there was a policy failure, however the option to Apply is still available. Why is that?
Discard the plan.
Navigate back the policy definition (/settings/policies)
Update the Policy Enforcement to be hard-mandatory
.
Queue a plan for the workspace.
This time the the run fails due to the hard enforcement.
- Write another Sentinel Policy restricting availablity zones to launch EC2 instances.