Documentation Index
Fetch the complete documentation index at: https://docs.artosai.com/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The global AWS resources module provisions foundational infrastructure components that are shared across all environments (if multiple enviornments in one account) (development, staging, production). These resources are created once per account and referenced by environment-specific modules, ensuring consistency, security, and centralized management.
Why Global Resources?
Global resources provide:
- Centralized Security: Single KMS key and IAM roles for encryption and access control
- Audit Compliance: Unified CloudTrail logging for all API activity
- Resource Reusability: IAM roles and policies shared across multiple modules
- Consistency: Standardized configuration across all environments
- Simplified Management: Update policies and permissions in one place
Core Components
1. KMS Encryption Key
A customer-managed KMS key that encrypts data at rest for all Artos resources, including EKS secrets, RDS databases, S3 buckets, CloudTrail logs, and Secrets Manager entries.
Key Features
| Feature | Configuration | Purpose |
|---|
| Automatic Key Rotation | Enabled (annual) | Rotates encryption keys automatically for enhanced security |
| Deletion Protection | 7-day window | Prevents accidental deletion with a recovery period |
| Multi-Service Access | EKS, RDS, S3, CloudTrail, Secrets Manager | Single key for all encryption needs |
| Key Alias | alias/{project}-{environment}-kms-key | Human-readable identifier for the key |
Service Permissions
The KMS key policy grants encryption/decryption permissions to multiple AWS services:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNT_ID:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow EKS Service",
"Effect": "Allow",
"Principal": {
"Service": "eks.amazonaws.com"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*"
},
{
"Sid": "Allow RDS Service",
"Effect": "Allow",
"Principal": {
"Service": "rds.amazonaws.com"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*"
}
// Additional statements for S3, CloudTrail, Secrets Manager
]
}
What This Means: The KMS key can be used by AWS services on your behalf to encrypt/decrypt data without requiring manual intervention. The root account retains full administrative access to manage the key.
2. IAM Roles for EKS
The module creates three primary IAM roles for different EKS compute types, each with specific permissions for their function.
EKS Cluster Service Role
Purpose: Allows the EKS control plane to manage AWS resources on your behalf.
| Property | Value |
|---|
| Role Name | {project}-{environment}-eks-service-role |
| Trust Policy | eks.amazonaws.com |
| Managed Policy | AmazonEKSClusterPolicy |
What It Does:
- Creates and manages Elastic Network Interfaces (ENIs) in your VPC
- Manages security groups for cluster-VPC communication
- Creates CloudWatch log streams for cluster logging
- Describes EC2 resources to validate cluster configuration
EKS Node Group Role
Purpose: Grants EC2 worker nodes permissions to join the cluster, pull container images, and access AWS services.
| Property | Value |
|---|
| Role Name | {project}-{environment}-eks-node-group-role |
| Trust Policy | ec2.amazonaws.com |
| Managed Policies | AmazonEKSWorkerNodePolicy, AmazonEKS_CNI_Policy, AmazonEC2ContainerRegistryReadOnly, AmazonSSMManagedInstanceCore |
Additional Permissions:
- Cross-Account ECR Access: Pull container images from the Artos-managed ECR registry
- SSM Session Manager: Secure shell access to nodes without SSH keys
Cross-Account ECR Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"ecr:DescribeRepositories",
"ecr:DescribeImages"
],
"Resource": [
"arn:aws:ecr:*:<artos_ecr_aws_account>:repository/development/*",
"arn:aws:ecr:*:<artos_ecr_aws_account>:repository/thirdparty/*"
]
}
]
}
Why This Matters: Nodes can pull pre-built Artos container images from the centralized ECR registry without requiring image copies or manual transfers.
EKS Fargate Role
Purpose: Allows Fargate profiles to execute pods and pull container images.
| Property | Value |
|---|
| Role Name | {project}-{environment}-eks-fargate-role |
| Trust Policy | eks-fargate-pods.amazonaws.com |
| Managed Policy | AmazonEKSFargatePodExecutionRolePolicy |
Additional Permissions:
- Cross-Account ECR Access: Same as node group role for image pulling
Fargate vs. Node Groups: Fargate pods run on AWS-managed infrastructure (serverless), while node groups run on customer-managed EC2 instances. The Fargate role is only used when Fargate profiles are configured.
RDS Enhanced Monitoring Role
Purpose: Allows RDS to publish detailed monitoring metrics to CloudWatch.
| Property | Value |
|---|
| Role Name | {project}-{environment}-rds-enhanced-monitoring-role |
| Trust Policy | monitoring.rds.amazonaws.com |
| Managed Policy | AmazonRDSEnhancedMonitoringRole |
What It Does: Enables RDS instances to send OS-level metrics (CPU, memory, disk I/O, network) to CloudWatch at 1-60 second intervals for detailed performance analysis.
3. CloudTrail Audit Logging
AWS CloudTrail records all API calls made in your AWS account, providing a complete audit trail for security analysis, compliance, and troubleshooting.
CloudTrail Configuration
| Setting | Value | Purpose |
|---|
| Multi-Region Trail | Enabled | Captures API calls from all AWS regions |
| Global Service Events | Enabled | Logs IAM, STS, CloudFront events |
| Event Selector | All management events + S3 data events | Records resource creation/modification |
| Encryption | KMS (using global KMS key) | Encrypts log files at rest |
| Log Storage | S3 bucket with versioning | Immutable audit log |
What CloudTrail Captures
Management Events (who did what):
- EKS cluster creation/modification
- RDS database parameter changes
- IAM role assumption
- Security group rule changes
- S3 bucket policy updates
Data Events (data access):
- S3 object uploads/downloads to CloudTrail bucket
- API calls to Artos services
CloudTrail S3 Bucket
The module creates a dedicated S3 bucket for storing CloudTrail logs:
| Feature | Configuration |
|---|
| Bucket Name | {project}-{environment}-cloudtrail-logs-{random} |
| Versioning | Enabled |
| Encryption | KMS (using global KMS key) |
| Force Destroy | Disabled (logs are retained even if Terraform is destroyed) |
| Bucket Policy | Allows CloudTrail service to write logs |
Bucket Policy Example:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AWSCloudTrailAclCheck",
"Effect": "Allow",
"Principal": {
"Service": "cloudtrail.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::bucket-name"
},
{
"Sid": "AWSCloudTrailWrite",
"Effect": "Allow",
"Principal": {
"Service": "cloudtrail.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::bucket-name/*",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
}
]
}
Why This Policy: The AWSCloudTrailAclCheck statement allows CloudTrail to verify bucket permissions, while AWSCloudTrailWrite permits log file uploads with the bucket-owner-full-control ACL to ensure you maintain ownership of log files.
Module Configuration
Basic Configuration
# terraform.tfvars
project_name = "genai-artos"
environment = "production"
aws_region = "us-east-1"
terraform_state_bucket = "artos-terraform-state"
tags = {
system_owner = "platform-team@company.com"
system_admin = "devops@company.com"
created_by = "Terraform"
cost_center = "engineering"
application = "artos-backend"
}
Backend Configuration
The module uses S3 backend for Terraform state storage. Create a backend configuration file for each environment:
File: backend-global-production-us-east-1.hcl
# Backend configuration for production environment in us-east-1
# Usage: terraform init -backend-config=backend-global-production-us-east-1.hcl
bucket = "artos-terraform-state"
key = "global/production/us-east-1/terraform.tfstate"
region = "us-east-1"
Initialization and Deployment
# Initialize Terraform with backend configuration
terraform init -backend-config=backend-global-production-us-east-1.hcl
# Review planned changes
terraform plan
# Apply global resources
terraform apply
# View outputs (KMS key ARN, IAM role ARNs, CloudTrail ARN)
terraform output
Using Global Resources in Environment Modules
Global resources are referenced by environment-specific modules (networking, EKS, RDS, S3) using Terraform data sources or outputs from remote state.
Example: Referencing KMS Key in RDS Module
# Environment module references global KMS key
data "terraform_remote_state" "global" {
backend = "s3"
config = {
bucket = "artos-terraform-state"
key = "global/production/us-east-1/terraform.tfstate"
region = "us-east-1"
}
}
# Use KMS key in RDS cluster
resource "aws_rds_cluster" "main" {
cluster_identifier = "artos-production"
engine = "aurora-postgresql"
storage_encrypted = true
kms_key_id = data.terraform_remote_state.global.outputs.kms_key_arn
# ... other configuration
}
Example: Referencing IAM Roles in EKS Module
# Reference global IAM roles
resource "aws_eks_cluster" "main" {
name = "artos-production"
role_arn = data.terraform_remote_state.global.outputs.eks_service_role_arn
# ... other configuration
}
resource "aws_eks_node_group" "main" {
cluster_name = aws_eks_cluster.main.name
node_role_arn = data.terraform_remote_state.global.outputs.eks_node_group_role_arn
# ... other configuration
}
resource "aws_eks_fargate_profile" "main" {
cluster_name = aws_eks_cluster.main.name
fargate_profile_name = "artos-fargate"
pod_execution_role_arn = data.terraform_remote_state.global.outputs.eks_fargate_role_arn
# ... other configuration
}
Module Outputs
The global resources module exports the following outputs for use by other modules:
| Output Name | Description | Example Value |
|---|
kms_key_id | KMS key ID | 12345678-1234-1234-1234-123456789012 |
kms_key_arn | KMS key ARN | arn:aws:kms:us-east-1:123456789012:key/12345678-... |
eks_service_role_arn | EKS cluster service role ARN | arn:aws:iam::123456789012:role/artos-prod-eks-service-role |
eks_node_group_role_arn | EKS node group role ARN | arn:aws:iam::123456789012:role/artos-prod-eks-node-group-role |
eks_fargate_role_arn | EKS Fargate role ARN | arn:aws:iam::123456789012:role/artos-prod-eks-fargate-role |
rds_enhanced_monitoring_role_arn | RDS monitoring role ARN | arn:aws:iam::123456789012:role/artos-prod-rds-enhanced-monitoring-role |
cloudtrail_arn | CloudTrail ARN | arn:aws:cloudtrail:us-east-1:123456789012:trail/artos-prod-cloudtrail |
Security Best Practices
1. KMS Key Management
Key Rotation:
- Automatic key rotation is enabled by default (annual rotation)
- Rotation is transparent to applications (AWS handles re-encryption)
- Historical key material is retained for decrypting old data
Access Control:
- Only the root account has full administrative access
- Service principals have minimal required permissions (encrypt/decrypt only)
- Consider creating separate KMS keys for highly sensitive data
2. IAM Role Security
Principle of Least Privilege:
- Each role has only the permissions required for its specific function
- Cross-account ECR access is limited to specific repositories
- SSM Session Manager replaces SSH for secure node access
Trust Policies:
- Trust policies restrict role assumption to specific AWS services
- No direct user access to service roles (principle of least privilege)
Monitoring:
- All role assumptions are logged in CloudTrail
- Set up CloudWatch alarms for unexpected role usage
3. CloudTrail Audit Logging
Log Integrity:
- Versioning enabled on log bucket prevents accidental deletion
- KMS encryption protects log confidentiality
- S3 Object Lock (optional) provides immutable audit logs
Access Control:
- CloudTrail bucket policy restricts write access to CloudTrail service only
- Separate IAM policy required to read logs (not granted by default)
- Consider enabling S3 Access Logging for the CloudTrail bucket
Alerting:
# Example: CloudWatch alarm for CloudTrail logging disabled
resource "aws_cloudwatch_metric_alarm" "cloudtrail_disabled" {
alarm_name = "cloudtrail-logging-disabled"
comparison_operator = "LessThanThreshold"
evaluation_periods = "1"
metric_name = "IsLogging"
namespace = "CloudTrailMetrics"
period = "300"
statistic = "Average"
threshold = "1"
alarm_description = "CloudTrail logging has been disabled"
alarm_actions = [aws_sns_topic.alerts.arn]
}
Operational Considerations
Cross-Account ECR Access
The global IAM roles include policies for pulling images from the Artos-managed ECR registry. This enables:
Centralized Image Management:
- Artos team maintains pre-built, tested container images
- Automatic security patching and updates
- Version-controlled image releases
Required Configuration:
- On Artos Side: ECR repository policies must allow your AWS account to pull images
- On Customer Side: IAM roles (created by this module) grant nodes permission to pull images. These updates can also be added to each ECR repository.
Backend Configuration:
- Global resources use S3 backend for state storage
- State file contains sensitive data (ARNs, resource IDs)
- Enable S3 versioning and encryption on state bucket
- The environment specific state files will be different for than the global tfstate files for each environment.
State Locking:
# Add DynamoDB table for state locking
terraform {
backend "s3" {
bucket = "artos-terraform-state"
key = "global/production/us-east-1/global.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-state-lock"
encrypt = true
}
}
Resource Dependencies
Deployment Order:
- First: Deploy global resources module
- Second: Deploy networking module (VPC, subnets, security groups)
- Third: Deploy environment-specific modules (EKS, RDS, S3, etc.)
Why This Order: Environment modules reference global resource outputs (KMS key ARN, IAM role ARNs) via remote state, so global resources must exist first.
Troubleshooting
Issue: KMS Key Access Denied
Symptom: Services (EKS, RDS) cannot encrypt/decrypt data using KMS key.
Solution:
# Verify KMS key policy includes service principal
aws kms get-key-policy --key-id <KEY_ID> --policy-name default
# Check CloudTrail for denied KMS API calls
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=Decrypt \
--max-results 10
Issue: Cross-Account ECR Pull Failures
Symptom: EKS pods cannot pull images from Artos ECR registry.
Solution:
# Verify IAM role policy is attached to node group role
aws iam list-attached-role-policies --role-name <NODE_GROUP_ROLE_NAME>
aws iam get-role-policy --role-name <NODE_GROUP_ROLE_NAME> --policy-name cross-account-ecr
# Test ECR authentication from node
kubectl run test-pod --image=<artos_ecr_aws_account>.dkr.ecr.us-east-1.amazonaws.com/development/test:latest
kubectl describe pod test-pod # Check for ImagePullBackOff errors
Common Causes:
- ECR repository policy does not allow your AWS account
- IAM role policy has incorrect repository ARNs
- Node instance profile not associated with IAM role
The global resources module is referenced by:
- Networking Module: Uses KMS key for VPC Flow Logs encryption
- EKS Module: Uses IAM roles for cluster, nodes, and Fargate
- RDS Module: Uses KMS key for database encryption and enhanced monitoring role
- S3 Module: Uses KMS key for bucket encryption
- IAM Module: References service roles for IRSA configuration