> ## 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.

# Global AWS Resources

> Shared AWS infrastructure resources for Artos deployment across all environments

## 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:

```json theme={null}
{
  "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**:

1. **Cross-Account ECR Access**: Pull container images from the Artos-managed ECR registry
2. **SSM Session Manager**: Secure shell access to nodes without SSH keys

**Cross-Account ECR Policy**:

```json theme={null}
{
  "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**:

```json theme={null}
{
  "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

```hcl theme={null}
# 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`**

```hcl theme={null}
# 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

```bash theme={null}
# 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

```hcl theme={null}
# 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

```hcl theme={null}
# 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**:

```hcl theme={null}
# 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**:

1. **On Artos Side**: ECR repository policies must allow your AWS account to pull images
2. **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.

### Terraform State Management

**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**:

```hcl theme={null}
# 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**:

1. **First**: Deploy global resources module
2. **Second**: Deploy networking module (VPC, subnets, security groups)
3. **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**:

```bash theme={null}
# 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**:

```bash theme={null}
# 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**:

1. ECR repository policy does not allow your AWS account
2. IAM role policy has incorrect repository ARNs
3. Node instance profile not associated with IAM role

## Related Modules

The global resources module is referenced by:

* **[Networking Module](networking)**: Uses KMS key for VPC Flow Logs encryption
* **[EKS Module](eks)**: Uses IAM roles for cluster, nodes, and Fargate
* **[RDS Module](rds)**: Uses KMS key for database encryption and enhanced monitoring role
* **[S3 Module](s3)**: Uses KMS key for bucket encryption
* **[IAM Module](iam)**: References service roles for IRSA configuration
