feat: setup AWS infrastructure directory and checklist
This commit is contained in:
@@ -0,0 +1,388 @@
|
||||
# Terraform configuration for Syslog Solution LLC AWS Organization
|
||||
# Infrastructure as Code for business AWS setup
|
||||
|
||||
terraform {
|
||||
required_version = ">= 1.0"
|
||||
required_providers {
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = "~> 6.0"
|
||||
}
|
||||
}
|
||||
|
||||
# Optional: S3 backend for state management (uncomment when ready)
|
||||
# backend "s3" {
|
||||
# bucket = "syslog-terraform-state"
|
||||
# key = "organization/terraform.tfstate"
|
||||
# region = "us-east-1"
|
||||
# encrypt = true
|
||||
# dynamodb_table = "terraform-locks"
|
||||
# }
|
||||
}
|
||||
|
||||
# Provider configuration for management account
|
||||
provider "aws" {
|
||||
region = var.aws_region
|
||||
alias = "management"
|
||||
|
||||
# Use AWS profile or credentials from environment variables
|
||||
profile = var.aws_profile
|
||||
|
||||
default_tags {
|
||||
tags = {
|
||||
Project = "Syslog Solution LLC"
|
||||
Environment = "Management"
|
||||
ManagedBy = "Terraform"
|
||||
Owner = "Syslog Solution LLC"
|
||||
BusinessUnit = "Infrastructure"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Data source to get current caller identity (for reference)
|
||||
data "aws_caller_identity" "management" {
|
||||
provider = aws.management
|
||||
}
|
||||
|
||||
# Create AWS Organization
|
||||
resource "aws_organizations_organization" "syslog" {
|
||||
provider = aws.management
|
||||
|
||||
feature_set = "ALL" # ALL or CONSOLIDATED_BILLING
|
||||
|
||||
# Enable AWS service access for key services
|
||||
aws_service_access_principals = [
|
||||
"cloudtrail.amazonaws.com",
|
||||
"config.amazonaws.com",
|
||||
"sso.amazonaws.com",
|
||||
"ram.amazonaws.com",
|
||||
"servicecatalog.amazonaws.com",
|
||||
"member.org.stacksets.cloudformation.amazonaws.com"
|
||||
]
|
||||
|
||||
# Enable policy types
|
||||
enabled_policy_types = ["SERVICE_CONTROL_POLICY"]
|
||||
|
||||
tags = {
|
||||
Name = "Syslog Solution LLC Organization"
|
||||
Description = "AWS Organization for Syslog Solution LLC business"
|
||||
}
|
||||
}
|
||||
|
||||
# Get the root ID for creating OUs
|
||||
data "aws_organizations_organization" "syslog" {
|
||||
provider = aws.management
|
||||
depends_on = [aws_organizations_organization.syslog]
|
||||
}
|
||||
|
||||
# Create Organizational Units (OUs)
|
||||
resource "aws_organizations_organizational_unit" "management" {
|
||||
provider = aws.management
|
||||
name = "Management"
|
||||
parent_id = data.aws_organizations_organization.syslog.roots[0].id
|
||||
|
||||
tags = {
|
||||
Purpose = "Admin and IAM management"
|
||||
Tier = "Tier 0"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_organizations_organizational_unit" "security" {
|
||||
provider = aws.management
|
||||
name = "Security"
|
||||
parent_id = data.aws_organizations_organization.syslog.roots[0].id
|
||||
|
||||
tags = {
|
||||
Purpose = "Security tools and monitoring"
|
||||
Tier = "Tier 0"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_organizations_organizational_unit" "workloads" {
|
||||
provider = aws.management
|
||||
name = "Workloads"
|
||||
parent_id = data.aws_organizations_organization.syslog.roots[0].id
|
||||
|
||||
tags = {
|
||||
Purpose = "Application workloads"
|
||||
Tier = "Tier 1"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_organizations_organizational_unit" "sandbox" {
|
||||
provider = aws.management
|
||||
name = "Sandbox"
|
||||
parent_id = data.aws_organizations_organization.syslog.roots[0].id
|
||||
|
||||
tags = {
|
||||
Purpose = "Experimentation and testing"
|
||||
Tier = "Tier 2"
|
||||
}
|
||||
}
|
||||
|
||||
# Create member accounts
|
||||
resource "aws_organizations_account" "development" {
|
||||
provider = aws.management
|
||||
name = "Syslog Development"
|
||||
email = var.dev_account_email
|
||||
|
||||
# Parent OU - place in Workloads OU
|
||||
parent_id = aws_organizations_organizational_unit.workloads.id
|
||||
|
||||
# IAM user access to billing (optional)
|
||||
iam_user_access_to_billing = "ALLOW"
|
||||
|
||||
tags = {
|
||||
Environment = "Development"
|
||||
Purpose = "Development and testing"
|
||||
}
|
||||
|
||||
# Ignore role_name changes (managed by AWS)
|
||||
lifecycle {
|
||||
ignore_changes = [role_name]
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_organizations_account" "staging" {
|
||||
provider = aws.management
|
||||
name = "Syslog Staging"
|
||||
email = var.staging_account_email
|
||||
|
||||
# Parent OU - place in Workloads OU
|
||||
parent_id = aws_organizations_organizational_unit.workloads.id
|
||||
|
||||
# IAM user access to billing (optional)
|
||||
iam_user_access_to_billing = "ALLOW"
|
||||
|
||||
tags = {
|
||||
Environment = "Staging"
|
||||
Purpose = "Staging and pre-production"
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [role_name]
|
||||
}
|
||||
}
|
||||
|
||||
# Create IAM users in management account
|
||||
resource "aws_iam_user" "syslog_admin" {
|
||||
provider = aws.management
|
||||
name = "syslog-admin"
|
||||
path = "/syslog/"
|
||||
|
||||
tags = {
|
||||
Role = "Administrator"
|
||||
Description = "Full admin access for Syslog Solution LLC"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_iam_user" "syslog_developer" {
|
||||
provider = aws.management
|
||||
name = "syslog-developer"
|
||||
path = "/syslog/"
|
||||
|
||||
tags = {
|
||||
Role = "Developer"
|
||||
Description = "Developer access for AWS resources"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_iam_user" "syslog_cicd" {
|
||||
provider = aws.management
|
||||
name = "syslog-cicd"
|
||||
path = "/syslog/"
|
||||
|
||||
tags = {
|
||||
Role = "CI/CD"
|
||||
Description = "CI/CD pipeline service account"
|
||||
}
|
||||
}
|
||||
|
||||
# Create IAM groups
|
||||
resource "aws_iam_group" "syslog_admins" {
|
||||
provider = aws.management
|
||||
name = "SyslogAdmins"
|
||||
path = "/syslog/"
|
||||
}
|
||||
|
||||
resource "aws_iam_group" "syslog_developers" {
|
||||
provider = aws.management
|
||||
name = "SyslogDevelopers"
|
||||
path = "/syslog/"
|
||||
}
|
||||
|
||||
# Add users to groups
|
||||
resource "aws_iam_group_membership" "admin_membership" {
|
||||
provider = aws.management
|
||||
name = "admin-group-membership"
|
||||
users = [
|
||||
aws_iam_user.syslog_admin.name
|
||||
]
|
||||
group = aws_iam_group.syslog_admins.name
|
||||
}
|
||||
|
||||
resource "aws_iam_group_membership" "developer_membership" {
|
||||
provider = aws.management
|
||||
name = "developer-group-membership"
|
||||
users = [
|
||||
aws_iam_user.syslog_developer.name,
|
||||
aws_iam_user.syslog_cicd.name
|
||||
]
|
||||
group = aws_iam_group.syslog_developers.name
|
||||
}
|
||||
|
||||
# Create IAM policies
|
||||
resource "aws_iam_policy" "syslog_admin_policy" {
|
||||
provider = aws.management
|
||||
name = "SyslogAdminPolicy"
|
||||
path = "/syslog/"
|
||||
description = "Administrative policy for Syslog Solution LLC"
|
||||
|
||||
policy = jsonencode({
|
||||
Version = "2012-10-17"
|
||||
Statement = [
|
||||
{
|
||||
Effect = "Allow"
|
||||
Action = "*"
|
||||
Resource = "*"
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
resource "aws_iam_policy" "syslog_developer_policy" {
|
||||
provider = aws.management
|
||||
name = "SyslogDeveloperPolicy"
|
||||
path = "/syslog/"
|
||||
description = "Developer policy for AWS resources"
|
||||
|
||||
policy = jsonencode({
|
||||
Version = "2012-10-17"
|
||||
Statement = [
|
||||
{
|
||||
Effect = "Allow"
|
||||
Action = [
|
||||
"ec2:*",
|
||||
"s3:*",
|
||||
"lambda:*",
|
||||
"dynamodb:*",
|
||||
"rds:*",
|
||||
"cloudformation:*",
|
||||
"amplify:*",
|
||||
"bedrock:*",
|
||||
"sagemaker:*"
|
||||
]
|
||||
Resource = "*"
|
||||
},
|
||||
{
|
||||
Effect = "Allow"
|
||||
Action = [
|
||||
"iam:Get*",
|
||||
"iam:List*",
|
||||
"iam:PassRole"
|
||||
]
|
||||
Resource = "*"
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
# Attach policies to groups
|
||||
resource "aws_iam_group_policy_attachment" "admin_policy_attach" {
|
||||
provider = aws.management
|
||||
group = aws_iam_group.syslog_admins.name
|
||||
policy_arn = aws_iam_policy.syslog_admin_policy.arn
|
||||
}
|
||||
|
||||
resource "aws_iam_group_policy_attachment" "developer_policy_attach" {
|
||||
provider = aws.management
|
||||
group = aws_iam_group.syslog_developers.name
|
||||
policy_arn = aws_iam_policy.syslog_developer_policy.arn
|
||||
}
|
||||
|
||||
# Create SNS topic for billing alerts
|
||||
resource "aws_sns_topic" "billing_alerts" {
|
||||
provider = aws.management
|
||||
name = "syslog-billing-alerts"
|
||||
|
||||
tags = {
|
||||
Purpose = "Billing notifications"
|
||||
}
|
||||
}
|
||||
|
||||
# Subscribe email to SNS topic
|
||||
resource "aws_sns_topic_subscription" "billing_email" {
|
||||
provider = aws.management
|
||||
topic_arn = aws_sns_topic.billing_alerts.arn
|
||||
protocol = "email"
|
||||
endpoint = var.billing_alert_email
|
||||
}
|
||||
|
||||
# CloudWatch billing alarm
|
||||
resource "aws_cloudwatch_metric_alarm" "monthly_spend" {
|
||||
provider = aws.management
|
||||
alarm_name = "syslog-monthly-spend-over-${var.monthly_spend_threshold}"
|
||||
comparison_operator = "GreaterThanThreshold"
|
||||
evaluation_periods = "1"
|
||||
metric_name = "EstimatedCharges"
|
||||
namespace = "AWS/Billing"
|
||||
period = "21600" # 6 hours
|
||||
statistic = "Maximum"
|
||||
threshold = var.monthly_spend_threshold
|
||||
alarm_description = "Monthly AWS spend exceeded ${var.monthly_spend_threshold} USD"
|
||||
alarm_actions = [aws_sns_topic.billing_alerts.arn]
|
||||
|
||||
dimensions = {
|
||||
Currency = "USD"
|
||||
}
|
||||
|
||||
tags = {
|
||||
AlertType = "Billing"
|
||||
}
|
||||
}
|
||||
|
||||
# Create S3 bucket for Terraform state (optional - uncomment when ready)
|
||||
# resource "aws_s3_bucket" "terraform_state" {
|
||||
# provider = aws.management
|
||||
# bucket = "syslog-terraform-state-${data.aws_caller_identity.management.account_id}"
|
||||
#
|
||||
# tags = {
|
||||
# Purpose = "Terraform state storage"
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# resource "aws_s3_bucket_versioning" "terraform_state" {
|
||||
# provider = aws.management
|
||||
# bucket = aws_s3_bucket.terraform_state.id
|
||||
# versioning_configuration {
|
||||
# status = "Enabled"
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# resource "aws_s3_bucket_server_side_encryption_configuration" "terraform_state" {
|
||||
# provider = aws.management
|
||||
# bucket = aws_s3_bucket.terraform_state.id
|
||||
#
|
||||
# rule {
|
||||
# apply_server_side_encryption_by_default {
|
||||
# sse_algorithm = "AES256"
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# # DynamoDB table for state locking
|
||||
# resource "aws_dynamodb_table" "terraform_locks" {
|
||||
# provider = aws.management
|
||||
# name = "terraform-locks"
|
||||
# billing_mode = "PAY_PER_REQUEST"
|
||||
# hash_key = "LockID"
|
||||
#
|
||||
# attribute {
|
||||
# name = "LockID"
|
||||
# type = "S"
|
||||
# }
|
||||
#
|
||||
# tags = {
|
||||
# Purpose = "Terraform state locking"
|
||||
# }
|
||||
# }
|
||||
Reference in New Issue
Block a user