NTC Guardrail Templates
- ntc-guardrail-templates
- 2.5.0
- AWS
- Templates
Description
NTC Guardrail Templates provide a set of best practice Service Control Policies (SCPs) and Resource Control Policies (RCP). These policies serve as guardrails to enforce security, compliance, and operational best practices across your AWS multi-account environment. By automating the deployment of SCPs and RCPs, this building block ensures consistent governance while allowing you to tailor policies to your organization’s specific needs.
NTC Guardrail Templates can be easily customized and then applied via NTC Organizations.
Usage
Loading the usage example from the implementation blueprint.
Requirements
The following requirements are needed by this module:
-
terraform (>= 1.10.0)
-
aws (>= 6.0)
Providers
The following providers are used by this module:
- aws (>= 6.0)
Modules
No modules.
Resources
The following resources are used by this module:
- aws_iam_policy_document.ntc_rcp (data source)
- aws_iam_policy_document.ntc_scp (data source)
- aws_partition.current (data source)
Required Inputs
No required inputs.
Optional Inputs
The following input variables are optional (have default values):
aiservices_opt_out_policy_templates
Description: List of templates which should be used to generate AI Services Opt-Out Policies.
Type:
list(object({
policy_name = string
policy_description = optional(string, "")
# unlike scp and rcp templates, ai services opt-out templates cannot be combined because each template defines the
# whole policy document. use "opt_out_all_services" or "opt_out_selected_services"
template_name = string
target_ou_paths = optional(list(string), [])
target_account_ids = optional(list(string), [])
# template specific parameters
# "opt_out_all_services": services which are excluded from the opt-out and remain opted in (e.g. ["rekognition"])
exclude_service_names = optional(list(string), [])
# "opt_out_selected_services": services which should be opted out (e.g. ["comprehend", "lex", "transcribe"])
service_names = optional(list(string), [])
}))
Default: []
resource_control_policy_templates
Description: List of templates which should be used to generate Resource Control Policies (RCP).
Type:
list(object({
policy_name = string
policy_description = optional(string, "")
template_names = list(string)
target_ou_paths = optional(list(string), [])
target_account_ids = optional(list(string), [])
# template specific parameters
org_id = optional(string, "")
enforced_service_actions = optional(list(string), [
"s3:*",
"sqs:*",
"kms:*",
"secretsmanager:*",
"sts:*",
])
s3_tls_minimum_version = optional(string, "1.2")
exclude_principal_arns = optional(list(string), [])
exclude_resource_arns = optional(list(string), [])
}))
Default: []
service_control_policy_templates
Description: List of templates which should be used to generate Service Control Policies (SCP).
Type:
list(object({
policy_name = string
policy_description = optional(string, null)
template_names = list(string)
target_ou_paths = optional(list(string), [])
target_account_ids = optional(list(string), [])
# template specific parameters
# defaults to "arn:<partition>:iam::*:role/OrganizationAccountAccessRole" of the current partition (e.g. aws, aws-eusc, aws-us-gov, aws-cn)
# set to [] to exempt no principals
exclude_principal_arns = optional(list(string), null)
exclude_bedrock_inference_profile_arns = optional(list(string), [])
# resource arns which are exempted from templates supporting resource exceptions.
# "deny_writes_to_external_bucket": s3 object arns of trusted external buckets e.g. buckets of external saas providers.
# "s3:PutObject" and "s3:ReplicateObject" are evaluated against object arns, so use "arn:aws:s3:::<bucket>/*"
# s3 express one zone directory buckets are evaluated against bucket arns, so use "arn:aws:s3express:<region>:<account>:bucket/<bucket>"
# aws service-owned buckets written via forward access sessions must be exempted explicitly as well
# (e.g. "arn:aws:s3:::*aws-data-exchange*/*" for aws data exchange)
exclude_resource_arns = optional(list(string), [])
# identity provider arns which are exempted from "deny_identity_provider_modification" in addition to eks oidc providers
# e.g. "arn:aws:iam::*:oidc-provider/token.actions.githubusercontent.com" for github actions
exclude_identity_provider_arns = optional(list(string), [])
# regions in which oidc providers of eks clusters are exempted from "deny_identity_provider_modification" (IRSA)
# e.g. ["eu-central-1", "eu-central-2"]. if empty, eks oidc providers are denied as well
eks_oidc_provider_regions = optional(list(string), [])
# account ids of share owners whose ram invitations can be accepted despite "deny_accepting_resource_shares_from_outside_org"
# e.g. accounts of the organization if ram sharing with aws organizations is not enabled or trusted third parties
trusted_resource_share_owner_account_ids = optional(list(string), [])
iam_arns_to_protect = optional(list(string), [])
blacklisted_services = optional(list(string), [])
tagged_resource_actions = optional(list(string), [])
tag_key = optional(string, "")
tag_values = optional(list(string), ["true"])
org_id = optional(string, "")
allowed_regions = optional(list(string), [])
whitelist_for_allowed_regions = optional(list(string), ["*"])
# actions which are exempted from "deny_outside_allowed_regions" in every region, regardless of "aws:RequestedRegion".
# only use this for harmless, region-agnostic read/discovery actions which are legitimately called from any region
# (e.g. a central networking account describing transit gateways/vpn gateways across all regions)
whitelist_for_other_regions = optional(list(string),
[
"ec2:DescribeRegions",
"ec2:DescribeTransitGateways",
"ec2:DescribeVpnGateways"
]
)
# regions which are partially opened for specific actions, in addition to "allowed_regions". in each mapped region
# only the listed actions (and "whitelist_for_other_regions") are exempted from "deny_outside_allowed_regions".
# use this for global services which pin their control plane to a specific region (most use "us-east-1", while
# globalaccelerator, networkmanager, route53-recovery-* and s3 multi-region access points use "us-west-2") and to
# allow selected services in a region (e.g. "lambda:*" in "us-east-1" for lambda@edge). an action can be listed
# for multiple regions, and patterns may overlap across regions (e.g. "lambda:*" in one region and "lambda:Get*"
# in another). overriding this input replaces the default map, so include the default entries you want to keep.
# for other partitions (e.g. aws-eusc) set the partition's global service region(s) or use an empty map
whitelist_for_specific_regions = optional(map(list(string)),
{
"us-east-1" = [
"a4b:*",
"account:Get*",
"account:List*",
"acm:*",
"aws-marketplace-management:*",
"aws-marketplace:*",
"aws-portal:*",
"billing:*",
"billingconductor:*",
"budgets:*",
"ce:*",
"chime:*",
"cloudfront:*",
"config:*",
"consolidatedbilling:*",
"cost-optimization-hub:*",
"cur:*",
"directconnect:*",
"ecr-public:GetAuthorizationToken",
"fms:*",
"freetier:*",
"health:*",
"iam:*",
"importexport:*",
"invoicing:*",
"kms:*",
"mobileanalytics:*",
"notifications-contacts:*",
"notifications:*",
"organizations:*",
"payments:*",
"pricing:*",
"route53:*",
"route53domains:*",
"s3:GetAccountPublic*",
"s3:ListAllMyBuckets",
"s3:PutAccountPublic*",
"savingsplans:*",
"shield:*",
"sts:*",
"support:*",
"supportplans:*",
"tax:*",
"trustedadvisor:*",
"waf-regional:*",
"waf:*",
"wafv2:*",
"wellarchitected:*"
]
"us-west-2" = [
"globalaccelerator:*",
"networkmanager:*",
"route53-recovery-cluster:*",
"route53-recovery-control-config:*",
"route53-recovery-readiness:*",
"s3:CreateMultiRegionAccessPoint",
"s3:DeleteMultiRegionAccessPoint",
"s3:DescribeMultiRegionAccessPointOperation",
"s3:GetMultiRegionAccessPoint",
"s3:GetMultiRegionAccessPointPolicy",
"s3:GetMultiRegionAccessPointPolicyStatus",
"s3:ListMultiRegionAccessPoints",
"s3:PutMultiRegionAccessPointPolicy"
]
}
)
}))
Default: []
service_principal_domain
Description: Domain of AWS service principals (e.g. "logging.s3.amazonaws.com") used in policy templates. Service principal names do not follow the partition dns suffix (e.g. aws-eusc also uses "amazonaws.com"), so only change this if a partition uses a different service principal domain.
Type: string
Default: "amazonaws.com"
Outputs
The following outputs are exported:
aiservices_opt_out_policies
Description: AI Services Opt-Out Policies grouped by policy name.
resource_control_policies
Description: Resource Control Policies (RCPs) grouped by policy name.
service_control_policies
Description: Service Control Policies (SCPs) grouped by policy name.