194 lines
7.8 KiB
Markdown
Executable File

# Terraform AWS Base Infrastructure Module
## Overview
This comprehensive Terraform module provisions a complete AWS infrastructure foundation including VPC, subnets, EKS cluster, node groups, bastion host, and VPC flow logs. It provides a production-ready, scalable base infrastructure for running containerized workloads on Amazon EKS.
## Features
- Complete VPC setup with configurable CIDR blocks
- Dynamic subnet creation across multiple availability zones
- Public and private subnet configuration with NAT gateways
- VPC Flow Logs for network monitoring
- EC2 Bastion host for secure SSH access
- Amazon EKS cluster with configurable Kubernetes version
- EKS Node Groups with auto-scaling capabilities
- OIDC provider integration for IAM roles for service accounts
- Security groups and IAM roles properly configured
- CloudPosse naming conventions for consistent resource naming
## Resources Created
### Networking
- AWS VPC
- Internet Gateway
- NAT Gateways (one per AZ)
- Public and Private Subnets (dynamic across AZs)
- Route Tables
- VPC Flow Logs (CloudWatch Logs integration)
### Compute
- EC2 Bastion Server with Elastic IP
- EKS Cluster
- EKS Node Group with Auto Scaling
### Security
- Security Groups for bastion and EKS cluster
- IAM Roles and Policies for EKS cluster and worker nodes
- OIDC Identity Provider (optional)
### Monitoring
- VPC Flow Logs with CloudWatch Log Group
## Usage
```hcl
module "base_infrastructure" {
source = "git@github.com:webuildyourcloud/terraform-aws-base_infra.git"
# Required Variables
region = "us-east-1"
availability_zones = ["us-east-1a", "us-east-1b", "us-east-1c"]
vpc_cidr_block = "10.0.0.0/16"
# Naming Convention
prefix = "myorg"
stage = "prod"
name = "app"
delimiter = "-"
attributes = []
# Bastion Configuration
bastion_instance_type = "t3.micro"
bastion_ami = "ami-0c55b159cbfafe1f0"
keyname = "my-ssh-key"
security_groups = []
# EKS Configuration
kubernetes_version = "1.21"
instance_types = ["t3.medium"]
desired_size = 3
min_size = 2
max_size = 5
disk_size = 20
kubeconfig_path = "./kubeconfig"
oidc_provider_enabled = true
# Kubernetes Labels
kubernetes_labels = {
Environment = "production"
Team = "platform"
}
# Tags
tags = {
Environment = "production"
ManagedBy = "terraform"
}
}
```
## Variables
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|----------|
| region | AWS Region | `string` | n/a | yes |
| availability_zones | List of availability zones | `list(string)` | n/a | yes |
| vpc_cidr_block | VPC CIDR block | `string` | n/a | yes |
| prefix | Namespace for the organization | `string` | n/a | yes |
| stage | Stage (e.g., 'prod', 'staging', 'dev') | `string` | n/a | yes |
| name | Solution name | `string` | n/a | yes |
| delimiter | Delimiter between name components | `string` | `"-"` | no |
| attributes | Additional attributes | `list(string)` | `[]` | no |
| tags | Additional tags | `map(string)` | `{}` | no |
| bastion_instance_type | EC2 instance type for bastion | `string` | n/a | yes |
| bastion_ami | AMI ID for bastion host | `string` | n/a | yes |
| keyname | SSH key name | `string` | `""` | no |
| security_groups | Security groups allowed to connect to bastion | `list(string)` | n/a | yes |
| user_data | User data content for bastion | `list(string)` | `[]` | no |
| root_block_device_encrypted | Encrypt root block device | `bool` | `false` | no |
| root_block_device_volume_size | Root block device volume size (GiB) | `number` | `8` | no |
| metadata_http_endpoint_enabled | Enable metadata service | `bool` | `true` | no |
| metadata_http_put_response_hop_limit | HTTP PUT response hop limit | `number` | `1` | no |
| metadata_http_tokens_required | Require metadata session tokens | `bool` | `false` | no |
| associate_public_ip_address | Associate public IP to bastion | `bool` | `true` | no |
| kubernetes_version | Kubernetes version | `string` | `null` | no |
| desired_size | Desired number of worker nodes | `number` | n/a | yes |
| max_size | Maximum number of worker nodes | `number` | n/a | yes |
| min_size | Minimum number of worker nodes | `number` | n/a | yes |
| oidc_provider_enabled | Create IAM OIDC provider | `bool` | `true` | no |
| kubeconfig_path | Path to kubeconfig file | `string` | n/a | yes |
| disk_size | Disk size in GiB for worker nodes | `number` | n/a | yes |
| instance_types | Instance types for EKS nodes | `list(string)` | n/a | yes |
| kubernetes_labels | Kubernetes labels for node group | `map(string)` | n/a | yes |
| kubernetes_namespace | Kubernetes namespace for Fargate | `string` | `"kube-apps"` | no |
| aws_eks_update_kubeconfig_additional_arguments | Additional arguments for kubeconfig update | `string` | `null` | no |
## Outputs
| Name | Description |
|------|-------------|
| public_subnet_cidrs | Public subnet CIDRs |
| private_subnet_cidrs | Private subnet CIDRs |
| public_subnet_ids | Public subnet IDs |
| private_subnet_ids | Private subnet IDs |
| vpc_cidr_block | VPC CIDR block |
| vpc_id | VPC ID |
| security_groups | Security Group IDs of bastion |
| eks_cluster_id | EKS cluster name |
| eks_cluster_arn | EKS cluster ARN |
| eks_cluster_endpoint | Kubernetes API server endpoint |
| eks_cluster_version | Kubernetes server version |
| eks_cluster_identity_oidc_issuer | OIDC Identity issuer |
| eks_cluster_certificate_authority_data | EKS cluster CA certificate |
| eks_cluster_auth_token | Cluster authentication token |
| workers_security_group_ids | Worker nodes security group |
| eks_node_group_role_arn | Worker nodes IAM role ARN |
| eks_node_group_role_name | Worker nodes IAM role name |
| eks_node_group_id | EKS Node Group ID |
| eks_node_group_arn | EKS Node Group ARN |
| eks_node_group_resources | Node Group underlying resources |
| eks_node_group_status | Node Group status |
## Requirements
| Name | Version |
|------|---------|
| terraform | >= 0.13 |
| aws | ~> 3.27 |
## Dependencies
This module uses the following external modules:
- [cloudposse/terraform-null-label](https://github.com/cloudposse/terraform-null-label) - Resource naming
- [cloudposse/vpc/aws](https://registry.terraform.io/modules/cloudposse/vpc/aws) - VPC creation
- [umotif-public/vpc-flow-logs/aws](https://registry.terraform.io/modules/umotif-public/vpc-flow-logs/aws) - VPC Flow Logs
- [cloudposse/dynamic-subnets/aws](https://registry.terraform.io/modules/cloudposse/dynamic-subnets/aws) - Dynamic subnet creation
- [cloudposse/ec2-bastion-server/aws](https://registry.terraform.io/modules/cloudposse/ec2-bastion-server/aws) - Bastion host
- Custom modules:
- terraform-aws-eks-cluster
- terraform-aws-eks_node_group
## Important Notes
1. **SSH Key**: Ensure the SSH key specified in `keyname` exists in the target region before applying
2. **VPC CIDR**: Choose a CIDR block that doesn't conflict with other VPCs in your environment
3. **NAT Gateways**: This module creates NAT gateways which incur hourly charges
4. **EKS Cluster**: Initial cluster creation takes approximately 10-15 minutes
5. **OIDC Provider**: Enable OIDC provider for using IAM roles for Kubernetes service accounts
6. **Kubeconfig**: The module expects a path where it can write the kubeconfig file
7. **Security Groups**: Additional security groups can be attached to the bastion host via the `security_groups` variable
## Security Considerations
- VPC Flow Logs are enabled by default for network monitoring
- Bastion host is configured in public subnets with restricted security groups
- EKS cluster and worker nodes are deployed in private subnets
- IMDSv2 can be enforced via `metadata_http_tokens_required`
- Root volume encryption can be enabled via `root_block_device_encrypted`
## License
This module is provided as-is for use within your organization.