Note, this module is not intended to be used outside of the organization, as the template provides a consistent blueprint for the provisioning of accounts with the Appvia AWS estate.
Please refer to one of the application, platform or sandbox pipelines for an example of how to use this module.
Tenants are able to provision notifications within the designated region. This first step to ensure notifications is enabled.
notifications = {
email = {
addresses = ["MY_EMAIL_ADDRESS"]
}
slack = {
webhook = "MY_SLACK_WEBHOOK"
}
}
The notifications can used to send notifications to users via email or slack, for events related to costs, security and budgets.
Additional service control policies can be applied to the account. This is useful for ensuring that the account is compliant with the organization's security policies, specific to the accounts requirements.
You can configure additional service control policies using the var.service_control_policies
variable, such as the below example
data "aws_iam_policy_document" "deny_s3" {
statement {
effect = "Deny"
actions = ["s3:*"]
resources = ["*"]
}
}
module "account" {
service_control_policies = {
"MY_POLICY_NAME" = {
name = "deny-s3"
policy = data.aws_iam_policy_document.deny_s3.json
}
}
}
The IAM password policy can be configured to enforce password policies on the account. This is useful for ensuring that the account is compliant with the organization's security policies, specific to the accounts requirements.
iam_password_policy = {
enabled = true
allow_users_to_change_password = true
hard_expiry = false
max_password_age = 90
minimum_password_length = 8
password_reuse_prevention = 24
require_lowercase_characters = true
require_numbers = true
require_symbols = true
require_uppercase_characters = true
}
The IAM access analyzer can be configured to analyze access to resources within your account and produce findings related to excessive permissions and or permissions which carry a high risk.
iam_access_analyzer = {
enabled = true
analyzer_name = "lza-iam-access-analyzer" # optional
analyzer_type = "ORGANIZATION" # optional but default
}
The EBS encryption can be configured to encrypt all EBS volumes within the account. The feature ensures all volumes are automatically encrypted.
ebs_encryption = {
enabled = true
create_kms_key = true
key_alias = "lza/ebs/default"
}
The S3 block public access can be configured to block public access to S3 buckets within the account. The feature ensures all buckets are automatically blocked from public access.
s3_block_public_access = {
enabled = true
enable_block_public_policy = true
enable_block_public_acls = true
enable_ignore_public_acls = true
enable_restrict_public_buckets = true
}
This module can ensure a set of IAM policies are created within the account. This is useful for ensuring that the account is preloaded with any required policy sets.
You can configure additional IAM policies using the var.iam_policies
variable, such as the below example
module "account" {
iam_policies = {
"deny_s3" = {
name = "deny-s3"
description = "Used to deny access to S3"
policy = data.aws_iam_policy_document.deny_s3.json
}
"deny_s3_with_prefix" = {
name_prefix = "deny-s3-"
policy = data.aws_iam_policy_document.deny_s3.json
description = "Used to deny access to S3"
path = "/"
}
}
}
This module can ensure a set of IAM roles are created within the account. This is useful for ensuring that the account is compliant with the organization's security policies, specific to the accounts requirements. Note, the IAM role have an automatic dependency on any IAM policies defined above to ensure ordering.
You can configure additional IAM roles using the var.iam_roles
variable, such as the below example
module "account" {
iam_roles = {
"s3_administrator" = {
name = "MY_ROLE_NAME"
assume_roles = ["arn:aws:iam::123456789012:role/role-name"]
description = "Administrator role for S3"
path = "/"
permissions_boundary_arn = null
permissions_arns = [
"arn:aws:iam::aws:policy/AmazonS3FullAccess"
]
#policies = [data.aws_iam_policy_document.deny_s3.json]
}
"ec2_instance_profile" {
name = "lza-ssm-instance-profile"
assume_services = ["ec2.amazonaws.com"]
description = "Instance profiles for ec2 compute machine"
path = "/"
permissions_arns = [
"arn:aws:iam::aws:policy/AmazonSSMDirectoryServiceAccess",
"arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore",
"arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy",
]
}
"kms_admin" = {
name = "kms-admin"
assume_accounts = ["123456789012"]
description = "Administrator role for KMS"
path = "/"
permissions_arns = [
"arn:aws:iam::aws:policy/AmazonKMSFullAccess"
]
}
}
}
This module provides the ability for tenants to manage the assignment of prescribed roles to users and groups within the account. The sso_assignment
module is used to manage the assignment of roles to users and groups within the account.
Note, the roles permitted for assignment can be found within local.sso_permitted_permission_sets
, an example of the permitted roles can be found below:
sso_permitted_permission_sets = {
"devops_engineer" = "DevOpsEngineer"
"finops_engineer" = "FinOpsEngineer"
"network_engineer" = "NetworkEngineer"
"network_viewer" = "NetworkViewer"
"platform_engineer" = "PlatformEngineer"
"security_auditor" = "SecurityAuditor"
}
This maps the exposed name used in the var.rbac
to the name of the role within the AWS Identity Center.
Tenants can assign roles to users and groups by providing a map of users and groups to roles within the var.rbac
variable. An example of this can be found below:
rbac = {
"devops_engineer" = {
users = ["MY_SSO_USER"]
groups = ["MY_SSO_GROUP"]
}
}
Tenants are able to receive budgets notifications related to the services. Once notifications have been configured they will automatically receive daily, weekly or monthly reports and notifications on where they sit in the budget.
Tenants are able to provision anomaly detection rules within the designated region. This is useful for ensure cost awareness and alerting on any unexpected costs.
cost_anomaly_detection = {
enabled = true
monitors = [
{
name = lower("lza-${local.region}")
frequency = "IMMEDIATE"
threshold_expression = [
{
and = {
dimension = {
key = "ANOMALY_TOTAL_IMPACT_ABSOLUTE"
match_options = ["GREATER_THAN_OR_EQUAL"]
values = ["100"]
}
}
},
{
and = {
dimension = {
key = "ANOMALY_TOTAL_IMPACT_PERCENTAGE"
match_options = ["GREATER_THAN_OR_EQUAL"]
values = ["50"]
}
}
}
]
specification = jsonencode({
"And" : [
{
"Dimensions" : {
"Key" : "REGION"
"Values" : [local.region]
}
}
]
})
}
]
}
Tenants are able to provision networks within the designated region, while allowing the platform to decide how these are wired up into the network topology of the organization i.e. ensuring the are using IPAM, connected to the transit gateway, egress via the central vpc and so forth.
All networks are defined within the var.networks
variable, an example of this can be found below:
networks = {
my_vpc_name = {
subnets = {
private = {
netmask = 28
}
database = {
netmask = 22
}
}
vpc = {
availability_zones = 2
enable_ipam = true
enable_transit_gateway = true
}
}
my_second_vpc = {
subnets = {
private = {
netmask = 28
}
}
vpc = {
enable_ipam = true
enable_transit_gateway = true
}
}
}
When network have defined the enable_transit_gateway
boolean it is the responsibility of the consumer of this module to have defined the correct transit gateway id and any default routing requirements.
Assuming the following configuration
module "my_account" {
...
networks = {
dev = {
vpc = {
enable_transit_gateway = true
ipam_pool_name = "development"
netmask = 21
}
transit_gateway = {
gateway_id = "tgw-1234567890"
gateway_routes = {
private = "10.0.0.0/8"
}
}
subnets = {
private = {
netmask = 24
}
}
},
}
We can also create transit gateway route table associations by extending the above configuration
module "my_account" {
...
networks = {
dev = {
vpc = {
enable_transit_gateway = true
ipam_pool_name = "development"
netmask = 21
}
transit_gateway = {
gateway_id = "tgw-1234567890"
gateway_routes = {
private = "10.0.0.0/8"
}
gateway_route_table_id = "rtb-1234567890"
}
}
}
}
The terraform-docs
utility is used to generate this README. Follow the below steps to update:
- Make changes to the
.terraform-docs.yml
file - Fetch the
terraform-docs
binary (https://terraform-docs.io/user-guide/installation/) - Run
terraform-docs markdown table --output-file ${PWD}/README.md --output-mode inject .
Name | Version |
---|---|
archive | ~> 2.0 |
aws | >= 5.0.0 |
aws.identity | >= 5.0.0 |
aws.management | >= 5.0.0 |
aws.network | >= 5.0.0 |
aws.tenant | >= 5.0.0 |
Name | Description | Type | Default | Required |
---|---|---|---|---|
environment | The environment in which to provision resources | string |
n/a | yes |
git_repository | The git repository to use for the account | string |
n/a | yes |
home_region | The home region in which to provision global resources | string |
n/a | yes |
owner | The owner of the product, and injected into all resource tags | string |
n/a | yes |
product | The name of the product to provision resources and inject into all resource tags | string |
n/a | yes |
region | The region we are provisioning the resources for the landing zone | string |
n/a | yes |
tags | A collection of tags to apply to resources | map(string) |
n/a | yes |
central_dns | Configuration for the hub used to centrally resolved dns requests | object({ |
{ |
no |
cost_anomaly_detection | A collection of cost anomaly detection monitors to apply to the account | object({ |
{ |
no |
cost_center | The cost center of the product, and injected into all resource tags | string |
null |
no |
dns | A collection of DNS zones to provision and associate with networks | map(object({ |
{} |
no |
ebs_encryption | A collection of EBS encryption settings to apply to the account | object({ |
null |
no |
iam_access_analyzer | The IAM access analyzer configuration to apply to the account | object({ |
{ |
no |
iam_password_policy | The IAM password policy to apply to the account | object({ |
{ |
no |
iam_policies | A collection of IAM policies to apply to the account | map(object({ |
{} |
no |
iam_roles | A collection of IAM roles to apply to the account | map(object({ |
{} |
no |
identity_center_permitted_roles | A map of permitted SSO roles, with the name of the permitted SSO role as the key, and value the permissionset | map(string) |
{ |
no |
kms_administrator | Configuration for the default kms administrator role to use for the account | object({ |
{ |
no |
kms_key | Configuration for the default kms encryption key to use for the account (per region) | object({ |
{ |
no |
macie | A collection of Macie settings to apply to the account | object({ |
null |
no |
networks | A collection of networks to provision within the designated region | map(object({ |
{} |
no |
notifications | Configuration for the notifications to the owner of the account | object({ |
{ |
no |
rbac | Provides the ability to associate one of more groups with a sso role in the account | map(object({ |
{} |
no |
s3_block_public_access | A collection of S3 public block access settings to apply to the account | object({ |
{ |
no |
service_control_policies | Provides the ability to associate one of more service control policies with an account | map(object({ |
{} |
no |
Name | Description |
---|---|
account_id | The account id where the pipeline is running |
environment | The environment name for the tenant |
networks | A map of the network name to network details |
private_hosted_zones | A map of the private hosted zones |
private_hosted_zones_by_id | A map of the hosted zone name to id |
sns_notification_arn | The SNS topic ARN for notifications |
tags | The tags to apply to all resources |
tenant_account_id | The region of the tenant account |
vpc_ids | A map of the network name to vpc id |