Intro
Hashicorp Terraform and OpenTofu are well-established tools for the descriptive provisioning of cloud resources.
These tools offer modularity, effective drift detection and remediation, robust testing features, and straightforward import of existing resources.
However, when implementing AWS account baselining and hardening, managing individual providers for each AWS account-region combination presents certain challenges.
This blog post outlines how ACAI PROVISIO can help you overcome these challenges to fully leverage Terraform.
Requirements
The requirements for the solution included:
- Composability: It shall be possible to specify individual Packages using Terraform’s native HCL.
- Precise Deployment: It shall be possible to define AWS Account Clusters and specify which Packages should be deployed to each cluster, ensuring targeted and efficient security enhancements.
Solution Architecture
The Deployment Manifest combines Packages with AWS Account Clusters to specify the individual baseline for each AWS Account, as illustrated below:
Further details on this deployment architecture are visualized here:
Rendering the Packages
The following code will render the ACAI PROVISIO packages (Step 2 in the diagram).
For example, the package terraform-aws-acai-acf-account-hardening will be applied with two different settings: once with default EBS encryption enabled and once with it disabled, for baselining the Core Image Factory account.
module "account_hardening_default" {
source = "git::https://github.com/acai-consulting/terraform-aws-acai-acf-account-hardening.git?ref=main"
provisio_settings = {
provisio_regions = local.platform_settings.governance.org_mgmt
}
account_hardening_settings = local.platform_settings.security.account_hardening
}
module "account_hardening_without_ebs" {
source = "git::https://github.com/acai-consulting/terraform-aws-acai-acf-account-hardening.git?ref=main"
provisio_settings = {
provisio_package_name = "account-hardening-without-ebs"
provisio_regions = local.platform_settings.governance.org_mgmt
}
account_hardening_settings = merge(
local.platform_settings.security.account_hardening,
{
ebs_encryption = false
}
)
}
module "acf_configservice" {
source = "git::https://github.com/acai-consulting/terraform-aws-acf-configservice.git//member/acai-provisio?ref=main"
provisio_settings = {
provisio_regions = local.platform_settings.governance.org_mgmt
import_resources = true
}
member_settings = local.platform_settings.security.semper.member
}
module "acai_semper" {
source = "git::https://github.com/acai-consulting/terraform-aws-acai-semper.git//member/acai-provisio?ref=fmain"
provisio_settings = {
provisio_regions = local.platform_settings.governance.org_mgmt
import_resources = true
}
member_settings = local.platform_settings.security.semper.member
}
...
Specifying the Deployment Targets
The following code specifies various AWS Account Clusters based on the ACF Account Cache convention (Step 3 in the diagram):
AWS Account Clusters:
- non_image_factory: All AWS Accounts except the Core Image Factory Account
- image_factory: The Core Image Factory Account
- backup_targets: All AWS Accounts except the Core Backup Account
- workload_prod: All AWS Accounts with account-tags “type” = “Workload” and “environment” = ‘Prod’
locals {
non_image_factory = jsonencode(
{
"exclude" = {
"accountId" = [
"183295430209" # ACAI Lab Core Image Factory Account ID
]
}
})
image_factory = jsonencode(
{
"exclude" = "*",
"forceInclude" = {
"accountId" = [
"183295430209" # ACAI Lab Core Image Factory Account ID
]
}
})
backup_targets = jsonencode(
{
"exclude" = "*",
"forceInclude" = {
"accountId" = [
{
"contains-not" = "211125437884" # ACAI Lab Core Backup Account ID
}
]
"accountTags" = {
"environment" = "Prod"
}
}
})
workload_prod = jsonencode(
{
"exclude" = "*",
"forceInclude" = {
"accountTags" = {
"type" = "Workload"
"environment" = "Prod"
}
}
})
}
The overview of the ACF Account Cache of the ACAI AWS Lab is shown here as JSON: link
Specifying the Deployment of the Packages
The following code details the package deployment strategy (Step 4 in the diagram).
It will lead to the following account baselining:
- account-baselining-default: will provision the specified provisio_packages to all AWS Accounts in your AWS Organization
- account-hardening-non-image-factory: will provision the account-hardening provisio_package to the non_image_factory AWS Account Cluster
- account-hardening-image-factory: will provision the account-hardening-without-ebs provisio_package to the image_factory AWS Account Cluster
- aws-backup: will provision the acf-backup provisio_package to the backup_targets AWS Account Cluster
- workload-prod: will provision the acf-auto-remediation provisio_package to the workload_prod AWS Account Cluster
locals {
package_deployment = [
{
deployment_name = "account-baselining-default"
provisio_packages = [
"acf-configservice",
"acai-semper",
"acf-image-factory"
]
},
{
deployment_name = "account-hardening-non-image-factory"
account_scope = local.non_image_factory
provisio_packages = [
"account-hardening"
]
},
{
deployment_name = "account-hardening-image-factory"
account_scope = local.image_factory
provisio_packages = [
"account-hardening-without-ebs"
]
},
{
deployment_name = "aws-backup"
account_scope = local.backup_targets
provisio_packages = [
"acf-backup"
]
},
{
deployment_name = "workload-prod"
account_scope = local.workload_prod
provisio_packages = [
"acf-auto-remediation"
]
}
]
}
Deploy ACAI PROVISIO
Deploying the ACF Account Cache and ACAI PROVISIO is the final step in maintaining the baseline and hardening of the AWS accounts across your AWS Organization:
# ---------------------------------------------------------------------------------------------------------------------
# ¦ ACF ACCOUNT CACHE
# ---------------------------------------------------------------------------------------------------------------------
module "context_cache" {
source = "git::https://github.com/acai-consulting/terraform-aws-acf-account-cache.git?ref=1.3.0"
settings = {
org_reader_role_arn = local.org_reader_role_arn
}
providers = {
aws = aws.Act_891376920850_Baselining
}
}
# ---------------------------------------------------------------------------------------------------------------------
# ¦ ACAI PROVISIO
# ---------------------------------------------------------------------------------------------------------------------
module "account_baseline" {
source = "git::https://github.com/acai-consulting/terraform-aws-acai-provisio.git?ref=1.0.0"
provisio_settings = {
org_reader_role_arn = local.org_reader_role_arn
core_provisio = {
account_cache = {
existing_ddb_name = module.context_cache.ddb_name
existing_permission_policy_arn = module.context_cache.cache_lambda_permission_policy_arn
}
}
}
provisio_baselining_specification = {
terraform_version = "1.5.7"
provider_aws_version = "5.40"
provisio_regions = local.platform_settings.governance.org_mgmt
package_specification = [
module.account_hardening_default,
module.account_hardening_without_ebs,
module.acf_configservice,
module.acf_imagefactory,
module.acf_backup,
module.acai_semper,
]
package_deployment = local.package_deployment
}
providers = {
aws = aws.Act_891376920850_Baselining
}
}
Conclusion
With ACAI PROVISIO and the strategies outlined above, you can efficiently maintain the security and governance of your entire AWS Organization.
ACAI Consulting specializes in AWS Multi-Account Security and Governance. If you have any questions, feel free to get in touch with us at: blog@acai.gmbh