feat: Terraform Foundation - AWS Landing Zone

Enterprise-grade multi-tenant AWS cloud foundation.

Modules:
- GitHub OIDC for keyless CI/CD authentication
- IAM account settings and security baseline
- AWS Config Rules for compliance
- ABAC (Attribute-Based Access Control)
- SCPs (Service Control Policies)

Features:
- Multi-account architecture
- Cost optimization patterns
- Security best practices
- Comprehensive documentation

Tech: Terraform, AWS Organizations, IAM Identity Center
This commit is contained in:
2026-02-01 20:06:28 +00:00
commit 6136cde9bb
145 changed files with 30832 additions and 0 deletions

View File

@@ -0,0 +1,40 @@
# identity-center
Terraform module for AWS landing zone pattern.
Configure AWS IAM Identity Center (formerly AWS SSO).
## Planned Features
- [ ] Default permission sets (Admin, PowerUser, ReadOnly, Billing)
- [ ] Custom permission sets with managed + inline policies
- [ ] Group-to-account assignments
- [ ] SCIM provisioning setup
- [ ] MFA enforcement
- [ ] Session duration policies
## Planned Usage
```hcl
module "identity_center" {
source = "../modules/identity-center"
default_permission_sets = true
permission_sets = {
DatabaseAdmin = {
description = "Database administration access"
session_duration = "PT8H"
managed_policies = ["arn:aws:iam::aws:policy/AmazonRDSFullAccess"]
}
}
group_assignments = {
admins_prod = {
group_name = "AWS-Admins"
permission_set = "AdministratorAccess"
account_ids = ["111111111111", "222222222222"]
}
}
}
```

View File

@@ -0,0 +1,145 @@
################################################################################
# Identity Center Module
#
# Configures AWS IAM Identity Center (formerly AWS SSO):
# - Permission sets with managed and inline policies
# - Account assignments for groups
# - Default permission sets (Admin, PowerUser, ReadOnly, Billing)
################################################################################
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.0"
}
}
}
data "aws_ssoadmin_instances" "this" {}
locals {
instance_arn = tolist(data.aws_ssoadmin_instances.this.arns)[0]
identity_store_id = tolist(data.aws_ssoadmin_instances.this.identity_store_ids)[0]
# Default permission sets
default_permission_sets = var.create_default_permission_sets ? {
AdministratorAccess = {
description = "Full administrator access"
session_duration = "PT4H"
managed_policies = ["arn:aws:iam::aws:policy/AdministratorAccess"]
inline_policy = ""
}
PowerUserAccess = {
description = "Power user access (no IAM)"
session_duration = "PT4H"
managed_policies = ["arn:aws:iam::aws:policy/PowerUserAccess"]
inline_policy = ""
}
ReadOnlyAccess = {
description = "Read-only access"
session_duration = "PT8H"
managed_policies = ["arn:aws:iam::aws:policy/ReadOnlyAccess"]
inline_policy = ""
}
Billing = {
description = "Billing access"
session_duration = "PT4H"
managed_policies = ["arn:aws:iam::aws:policy/job-function/Billing"]
inline_policy = ""
}
ViewOnlyAccess = {
description = "View-only access (no data access)"
session_duration = "PT8H"
managed_policies = ["arn:aws:iam::aws:policy/job-function/ViewOnlyAccess"]
inline_policy = ""
}
} : {}
# Merge default and custom permission sets
all_permission_sets = merge(local.default_permission_sets, var.permission_sets)
}
################################################################################
# Permission Sets
################################################################################
resource "aws_ssoadmin_permission_set" "this" {
for_each = local.all_permission_sets
instance_arn = local.instance_arn
name = each.key
description = each.value.description
session_duration = each.value.session_duration
tags = merge(var.tags, {
Name = each.key
})
}
# Attach managed policies
resource "aws_ssoadmin_managed_policy_attachment" "this" {
for_each = {
for pair in flatten([
for ps_name, ps in local.all_permission_sets : [
for policy in ps.managed_policies : {
key = "${ps_name}-${replace(policy, "/.*//", "")}"
ps_name = ps_name
policy_arn = policy
}
]
]) : pair.key => pair
}
instance_arn = local.instance_arn
permission_set_arn = aws_ssoadmin_permission_set.this[each.value.ps_name].arn
managed_policy_arn = each.value.policy_arn
}
# Attach inline policies
resource "aws_ssoadmin_permission_set_inline_policy" "this" {
for_each = {
for name, ps in local.all_permission_sets : name => ps
if ps.inline_policy != ""
}
instance_arn = local.instance_arn
permission_set_arn = aws_ssoadmin_permission_set.this[each.key].arn
inline_policy = each.value.inline_policy
}
################################################################################
# Account Assignments
################################################################################
# Look up groups from Identity Store
data "aws_identitystore_group" "this" {
for_each = toset([for a in var.account_assignments : a.group_name])
identity_store_id = local.identity_store_id
alternate_identifier {
unique_attribute {
attribute_path = "DisplayName"
attribute_value = each.value
}
}
}
# Create account assignments
resource "aws_ssoadmin_account_assignment" "this" {
for_each = {
for a in var.account_assignments :
"${a.group_name}-${a.permission_set}-${a.account_id}" => a
}
instance_arn = local.instance_arn
permission_set_arn = aws_ssoadmin_permission_set.this[each.value.permission_set].arn
principal_id = data.aws_identitystore_group.this[each.value.group_name].group_id
principal_type = "GROUP"
target_id = each.value.account_id
target_type = "AWS_ACCOUNT"
}

View File

@@ -0,0 +1,28 @@
################################################################################
# Identity Center - Outputs
################################################################################
output "instance_arn" {
value = local.instance_arn
description = "Identity Center instance ARN"
}
output "identity_store_id" {
value = local.identity_store_id
description = "Identity Store ID"
}
output "permission_set_arns" {
value = { for k, v in aws_ssoadmin_permission_set.this : k => v.arn }
description = "Map of permission set names to ARNs"
}
output "sso_start_url" {
value = "https://${local.identity_store_id}.awsapps.com/start"
description = "SSO portal start URL"
}
output "assignment_count" {
value = length(aws_ssoadmin_account_assignment.this)
description = "Number of account assignments created"
}

View File

@@ -0,0 +1,36 @@
################################################################################
# Identity Center - Input Variables
################################################################################
variable "create_default_permission_sets" {
type = bool
default = true
description = "Create default permission sets (Admin, PowerUser, ReadOnly, Billing)"
}
variable "permission_sets" {
type = map(object({
description = string
session_duration = optional(string, "PT4H")
managed_policies = optional(list(string), [])
inline_policy = optional(string, "")
}))
default = {}
description = "Custom permission sets to create"
}
variable "account_assignments" {
type = list(object({
group_name = string
permission_set = string
account_id = string
}))
default = []
description = "Group to account/permission assignments"
}
variable "tags" {
type = map(string)
default = {}
description = "Tags to apply to resources"
}