docker-erpnext/documentation/deployment-guides/aws-managed/00-prerequisites-managed.md
Brian Tan Seng 8894bbf56e ⏺ Perfect! I have successfully created the complete AWS equivalent of the GCP managed services
deployment documentation. Here's a summary of what was created:

  📁 AWS Managed Services Documentation Structure

  Main Documentation Files:

  1. README.md - Comprehensive overview and decision guide
  2. 00-prerequisites-managed.md - AWS setup, VPC, security, and managed services
  3. 01-ecs-managed-deployment.md - Amazon ECS with Fargate deployment
  4. 02-eks-managed-deployment.md - Amazon EKS deployment
  5. 03-production-managed-setup.md - Production hardening and advanced features

  Kubernetes Manifests (kubernetes-manifests/):

  - namespace.yaml - Namespace with resource quotas and network policies
  - storage.yaml - EFS and EBS storage classes and PVCs
  - configmap.yaml - Application configuration and Nginx config
  - secrets.yaml - External Secrets Operator integration with AWS Secrets Manager
  - erpnext-backend.yaml - Backend deployment with RDS connectivity
  - erpnext-frontend.yaml - Frontend deployment with load balancing
  - erpnext-workers.yaml - Worker deployments for different queues
  - ingress.yaml - AWS Load Balancer Controller ingress configuration
  - jobs.yaml - Site creation and backup automation jobs

  Deployment Scripts (scripts/):

  - deploy-ecs.sh - Automated ECS deployment script
  - deploy-eks.sh - Automated EKS deployment script

  🔄 Key AWS Managed Services Used:

  Instead of GCP → AWS Equivalent:
  - Cloud SQL → Amazon RDS for MySQL
  - Memorystore → Amazon MemoryDB for Redis
  - Cloud Run → Amazon ECS with Fargate
  - GKE → Amazon EKS
  - Cloud Storage → Amazon S3
  - Secret Manager → AWS Secrets Manager
  - VPC Access Connector → VPC Endpoints/NAT Gateway

  🎯 Key Features Included:

  Production-Ready Features:

  -  High Availability - Multi-AZ RDS and MemoryDB deployment
  -  Auto-scaling - ECS Service Auto Scaling and EKS HPA
  -  Security - VPC isolation, IAM roles, WAF, encryption
  -  Monitoring - CloudWatch, X-Ray, custom metrics
  -  Backup & DR - Automated backups, cross-region replication
  -  Cost Optimization - Reserved instances, spot instances, right-sizing

  Deployment Options:

  - 🚀 Amazon ECS with Fargate - Serverless containers, minimal ops
  - ⚙️ Amazon EKS - Full Kubernetes with advanced features
  - 🛡️ Production Hardening - WAF, enhanced monitoring, security

  Automation Scripts:

  - 📜 One-click deployment scripts for both ECS and EKS
  - 🔧 Infrastructure as Code approach
  - 📊 Cost estimation and optimization guidance

  The documentation provides a complete migration path from GCP to AWS with equivalent managed
  services, maintaining the same level of reliability and operational efficiency while
  leveraging AWS-native services and best practices.
2025-08-22 19:15:03 +08:00

705 lines
21 KiB
Markdown

# AWS Prerequisites for ERPNext with Managed Services
## Overview
This guide covers the prerequisites and initial setup required for deploying ERPNext on Amazon Web Services (AWS) using managed database services: Amazon RDS for MySQL and Amazon MemoryDB for Redis. This approach provides better reliability, security, and operational efficiency compared to self-hosted databases.
## 🔧 Required Tools
### 1. AWS CLI
```bash
# Install AWS CLI v2
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
# Configure AWS CLI
aws configure
# Enter your Access Key ID, Secret Access Key, Default region, and output format
```
### 2. kubectl (Kubernetes CLI) - For EKS Option
```bash
# Install kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
# Verify installation
kubectl version --client
```
### 3. eksctl (EKS CLI) - For EKS Option
```bash
# Install eksctl
curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv /tmp/eksctl /usr/local/bin
# Verify installation
eksctl version
```
### 4. Docker (for local testing and ECS)
```bash
# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh
# Enable Docker BuildKit
export DOCKER_BUILDKIT=1
```
### 5. AWS ECS CLI - For ECS Option
```bash
# Install ECS CLI
sudo curl -Lo /usr/local/bin/ecs-cli https://amazon-ecs-cli.s3.amazonaws.com/ecs-cli-linux-amd64-latest
sudo chmod +x /usr/local/bin/ecs-cli
# Verify installation
ecs-cli --version
```
### 6. Helm (for EKS Kubernetes package management)
```bash
# Install Helm
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# Verify installation
helm version
```
## 🏗️ AWS Account Setup
### 1. Create or Configure AWS Account
```bash
# Verify AWS account and permissions
aws sts get-caller-identity
# Set default region
export AWS_DEFAULT_REGION=us-east-1
aws configure set default.region us-east-1
# Verify configuration
aws configure list
```
### 2. Enable Required AWS Services
```bash
# Verify access to required services
aws ec2 describe-regions --output table
aws rds describe-db-instances --output table
aws elasticache describe-cache-clusters --output table
aws ecs list-clusters --output table
aws eks list-clusters --output table
```
### 3. Create IAM Policies and Roles
```bash
# Create IAM policy for ERPNext managed services
cat > erpnext-managed-policy.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds:*",
"elasticache:*",
"ecs:*",
"eks:*",
"ec2:*",
"iam:PassRole",
"logs:*",
"cloudwatch:*",
"secretsmanager:*",
"ssm:*"
],
"Resource": "*"
}
]
}
EOF
# Create the policy
aws iam create-policy \
--policy-name ERPNextManagedPolicy \
--policy-document file://erpnext-managed-policy.json
# Create service role for ECS tasks
cat > ecs-task-role-trust.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
aws iam create-role \
--role-name ERPNextECSTaskRole \
--assume-role-policy-document file://ecs-task-role-trust.json
# Attach policies to ECS task role
aws iam attach-role-policy \
--role-name ERPNextECSTaskRole \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
aws iam attach-role-policy \
--role-name ERPNextECSTaskRole \
--policy-arn $(aws iam list-policies --query "Policies[?PolicyName=='ERPNextManagedPolicy'].Arn" --output text)
```
## 🔐 Security Setup
### 1. VPC and Networking Configuration
```bash
# Create VPC for ERPNext deployment
aws ec2 create-vpc \
--cidr-block 10.0.0.0/16 \
--tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=erpnext-vpc}]'
# Get VPC ID
VPC_ID=$(aws ec2 describe-vpcs \
--filters "Name=tag:Name,Values=erpnext-vpc" \
--query "Vpcs[0].VpcId" --output text)
# Create Internet Gateway
aws ec2 create-internet-gateway \
--tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=erpnext-igw}]'
IGW_ID=$(aws ec2 describe-internet-gateways \
--filters "Name=tag:Name,Values=erpnext-igw" \
--query "InternetGateways[0].InternetGatewayId" --output text)
# Attach Internet Gateway to VPC
aws ec2 attach-internet-gateway \
--vpc-id $VPC_ID \
--internet-gateway-id $IGW_ID
# Create subnets
# Public subnet for load balancers
aws ec2 create-subnet \
--vpc-id $VPC_ID \
--cidr-block 10.0.1.0/24 \
--availability-zone us-east-1a \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=erpnext-public-subnet-1a}]'
aws ec2 create-subnet \
--vpc-id $VPC_ID \
--cidr-block 10.0.2.0/24 \
--availability-zone us-east-1b \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=erpnext-public-subnet-1b}]'
# Private subnets for application
aws ec2 create-subnet \
--vpc-id $VPC_ID \
--cidr-block 10.0.10.0/24 \
--availability-zone us-east-1a \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=erpnext-private-subnet-1a}]'
aws ec2 create-subnet \
--vpc-id $VPC_ID \
--cidr-block 10.0.11.0/24 \
--availability-zone us-east-1b \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=erpnext-private-subnet-1b}]'
# Database subnets
aws ec2 create-subnet \
--vpc-id $VPC_ID \
--cidr-block 10.0.20.0/24 \
--availability-zone us-east-1a \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=erpnext-db-subnet-1a}]'
aws ec2 create-subnet \
--vpc-id $VPC_ID \
--cidr-block 10.0.21.0/24 \
--availability-zone us-east-1b \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=erpnext-db-subnet-1b}]'
```
### 2. Route Tables and NAT Gateway
```bash
# Get subnet IDs
PUBLIC_SUBNET_1A=$(aws ec2 describe-subnets \
--filters "Name=tag:Name,Values=erpnext-public-subnet-1a" \
--query "Subnets[0].SubnetId" --output text)
PUBLIC_SUBNET_1B=$(aws ec2 describe-subnets \
--filters "Name=tag:Name,Values=erpnext-public-subnet-1b" \
--query "Subnets[0].SubnetId" --output text)
PRIVATE_SUBNET_1A=$(aws ec2 describe-subnets \
--filters "Name=tag:Name,Values=erpnext-private-subnet-1a" \
--query "Subnets[0].SubnetId" --output text)
PRIVATE_SUBNET_1B=$(aws ec2 describe-subnets \
--filters "Name=tag:Name,Values=erpnext-private-subnet-1b" \
--query "Subnets[0].SubnetId" --output text)
# Create NAT Gateway
aws ec2 allocate-address \
--domain vpc \
--tag-specifications 'ResourceType=elastic-ip,Tags=[{Key=Name,Value=erpnext-nat-eip}]'
NAT_EIP=$(aws ec2 describe-addresses \
--filters "Name=tag:Name,Values=erpnext-nat-eip" \
--query "Addresses[0].AllocationId" --output text)
aws ec2 create-nat-gateway \
--subnet-id $PUBLIC_SUBNET_1A \
--allocation-id $NAT_EIP \
--tag-specifications 'ResourceType=nat-gateway,Tags=[{Key=Name,Value=erpnext-nat}]'
NAT_ID=$(aws ec2 describe-nat-gateways \
--filter "Name=tag:Name,Values=erpnext-nat" \
--query "NatGateways[0].NatGatewayId" --output text)
# Create route tables
# Public route table
aws ec2 create-route-table \
--vpc-id $VPC_ID \
--tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=erpnext-public-rt}]'
PUBLIC_RT=$(aws ec2 describe-route-tables \
--filters "Name=tag:Name,Values=erpnext-public-rt" \
--query "RouteTables[0].RouteTableId" --output text)
# Private route table
aws ec2 create-route-table \
--vpc-id $VPC_ID \
--tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=erpnext-private-rt}]'
PRIVATE_RT=$(aws ec2 describe-route-tables \
--filters "Name=tag:Name,Values=erpnext-private-rt" \
--query "RouteTables[0].RouteTableId" --output text)
# Add routes
aws ec2 create-route \
--route-table-id $PUBLIC_RT \
--destination-cidr-block 0.0.0.0/0 \
--gateway-id $IGW_ID
aws ec2 create-route \
--route-table-id $PRIVATE_RT \
--destination-cidr-block 0.0.0.0/0 \
--nat-gateway-id $NAT_ID
# Associate subnets with route tables
aws ec2 associate-route-table \
--subnet-id $PUBLIC_SUBNET_1A \
--route-table-id $PUBLIC_RT
aws ec2 associate-route-table \
--subnet-id $PUBLIC_SUBNET_1B \
--route-table-id $PUBLIC_RT
aws ec2 associate-route-table \
--subnet-id $PRIVATE_SUBNET_1A \
--route-table-id $PRIVATE_RT
aws ec2 associate-route-table \
--subnet-id $PRIVATE_SUBNET_1B \
--route-table-id $PRIVATE_RT
```
### 3. Security Groups
```bash
# Create security group for ALB
aws ec2 create-security-group \
--group-name erpnext-alb-sg \
--description "Security group for ERPNext Application Load Balancer" \
--vpc-id $VPC_ID \
--tag-specifications 'ResourceType=security-group,Tags=[{Key=Name,Value=erpnext-alb-sg}]'
ALB_SG=$(aws ec2 describe-security-groups \
--filters "Name=tag:Name,Values=erpnext-alb-sg" \
--query "SecurityGroups[0].GroupId" --output text)
# Create security group for application
aws ec2 create-security-group \
--group-name erpnext-app-sg \
--description "Security group for ERPNext Application" \
--vpc-id $VPC_ID \
--tag-specifications 'ResourceType=security-group,Tags=[{Key=Name,Value=erpnext-app-sg}]'
APP_SG=$(aws ec2 describe-security-groups \
--filters "Name=tag:Name,Values=erpnext-app-sg" \
--query "SecurityGroups[0].GroupId" --output text)
# Create security group for database
aws ec2 create-security-group \
--group-name erpnext-db-sg \
--description "Security group for ERPNext Database" \
--vpc-id $VPC_ID \
--tag-specifications 'ResourceType=security-group,Tags=[{Key=Name,Value=erpnext-db-sg}]'
DB_SG=$(aws ec2 describe-security-groups \
--filters "Name=tag:Name,Values=erpnext-db-sg" \
--query "SecurityGroups[0].GroupId" --output text)
# Configure security group rules
# ALB security group
aws ec2 authorize-security-group-ingress \
--group-id $ALB_SG \
--protocol tcp \
--port 80 \
--cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress \
--group-id $ALB_SG \
--protocol tcp \
--port 443 \
--cidr 0.0.0.0/0
# Application security group
aws ec2 authorize-security-group-ingress \
--group-id $APP_SG \
--protocol tcp \
--port 8000 \
--source-group $ALB_SG
aws ec2 authorize-security-group-ingress \
--group-id $APP_SG \
--protocol tcp \
--port 9000 \
--source-group $ALB_SG
# Database security group
aws ec2 authorize-security-group-ingress \
--group-id $DB_SG \
--protocol tcp \
--port 3306 \
--source-group $APP_SG
aws ec2 authorize-security-group-ingress \
--group-id $DB_SG \
--protocol tcp \
--port 6379 \
--source-group $APP_SG
```
## 💾 Managed Database Services Setup
### 1. RDS MySQL Instance
```bash
# Create DB subnet group
DB_SUBNET_1A=$(aws ec2 describe-subnets \
--filters "Name=tag:Name,Values=erpnext-db-subnet-1a" \
--query "Subnets[0].SubnetId" --output text)
DB_SUBNET_1B=$(aws ec2 describe-subnets \
--filters "Name=tag:Name,Values=erpnext-db-subnet-1b" \
--query "Subnets[0].SubnetId" --output text)
aws rds create-db-subnet-group \
--db-subnet-group-name erpnext-db-subnet-group \
--db-subnet-group-description "Subnet group for ERPNext database" \
--subnet-ids $DB_SUBNET_1A $DB_SUBNET_1B \
--tags Key=Name,Value=erpnext-db-subnet-group
# Create RDS MySQL instance
aws rds create-db-instance \
--db-instance-identifier erpnext-db \
--db-instance-class db.t3.medium \
--engine mysql \
--engine-version 8.0.35 \
--master-username admin \
--master-user-password YourSecureDBPassword123! \
--allocated-storage 100 \
--storage-type gp3 \
--storage-encrypted \
--vpc-security-group-ids $DB_SG \
--db-subnet-group-name erpnext-db-subnet-group \
--backup-retention-period 7 \
--backup-window 03:00-04:00 \
--maintenance-window sun:04:00-sun:05:00 \
--auto-minor-version-upgrade \
--deletion-protection \
--enable-performance-insights \
--performance-insights-retention-period 7 \
--tags Key=Name,Value=erpnext-db
# Wait for instance to be available
aws rds wait db-instance-available --db-instance-identifier erpnext-db
# Create ERPNext database
aws rds create-db-instance \
--db-instance-identifier erpnext-db \
--allocated-storage 100 \
--db-instance-class db.t3.medium \
--engine mysql \
--master-username admin \
--master-user-password YourSecureDBPassword123! \
--vpc-security-group-ids $DB_SG \
--db-subnet-group-name erpnext-db-subnet-group
```
### 2. MemoryDB for Redis Instance
```bash
# Create MemoryDB subnet group
aws memorydb create-subnet-group \
--subnet-group-name erpnext-redis-subnet-group \
--description "Subnet group for ERPNext Redis" \
--subnet-ids $DB_SUBNET_1A $DB_SUBNET_1B \
--tags Key=Name,Value=erpnext-redis-subnet-group
# Create MemoryDB user
aws memorydb create-user \
--user-name erpnext-redis-user \
--authentication-mode Type=password,Passwords=YourSecureRedisPassword123! \
--access-string "on ~* &* +@all" \
--tags Key=Name,Value=erpnext-redis-user
# Create MemoryDB ACL
aws memorydb create-acl \
--acl-name erpnext-redis-acl \
--user-names erpnext-redis-user \
--tags Key=Name,Value=erpnext-redis-acl
# Create MemoryDB cluster
aws memorydb create-cluster \
--cluster-name erpnext-redis \
--node-type db.t4g.small \
--engine-version 6.2 \
--num-shards 1 \
--num-replicas-per-shard 1 \
--acl-name erpnext-redis-acl \
--subnet-group-name erpnext-redis-subnet-group \
--security-group-ids $DB_SG \
--maintenance-window sun:05:00-sun:06:00 \
--sns-topic-arn arn:aws:sns:us-east-1:$(aws sts get-caller-identity --query Account --output text):erpnext-notifications \
--tls-enabled \
--tags Key=Name,Value=erpnext-redis
# Wait for cluster to be available
aws memorydb describe-clusters \
--cluster-name erpnext-redis \
--query "Clusters[0].Status" --output text
```
### 3. AWS Systems Manager Parameter Store for Configuration
```bash
# Store database configuration
aws ssm put-parameter \
--name "/erpnext/database/host" \
--value $(aws rds describe-db-instances \
--db-instance-identifier erpnext-db \
--query "DBInstances[0].Endpoint.Address" --output text) \
--type "String" \
--description "ERPNext Database Host"
aws ssm put-parameter \
--name "/erpnext/database/port" \
--value "3306" \
--type "String" \
--description "ERPNext Database Port"
aws ssm put-parameter \
--name "/erpnext/database/name" \
--value "erpnext" \
--type "String" \
--description "ERPNext Database Name"
aws ssm put-parameter \
--name "/erpnext/database/username" \
--value "admin" \
--type "String" \
--description "ERPNext Database Username"
# Store Redis configuration
aws ssm put-parameter \
--name "/erpnext/redis/host" \
--value $(aws memorydb describe-clusters \
--cluster-name erpnext-redis \
--query "Clusters[0].ClusterEndpoint.Address" --output text) \
--type "String" \
--description "ERPNext Redis Host"
aws ssm put-parameter \
--name "/erpnext/redis/port" \
--value "6379" \
--type "String" \
--description "ERPNext Redis Port"
```
## 🔑 AWS Secrets Manager for Sensitive Data
```bash
# Store database password
aws secretsmanager create-secret \
--name "erpnext/database/password" \
--description "ERPNext Database Password" \
--secret-string "YourSecureDBPassword123!" \
--tags '[{"Key":"Application","Value":"ERPNext"},{"Key":"Environment","Value":"Production"}]'
# Store Redis password
aws secretsmanager create-secret \
--name "erpnext/redis/password" \
--description "ERPNext Redis Password" \
--secret-string "YourSecureRedisPassword123!" \
--tags '[{"Key":"Application","Value":"ERPNext"},{"Key":"Environment","Value":"Production"}]'
# Store ERPNext admin password
aws secretsmanager create-secret \
--name "erpnext/admin/password" \
--description "ERPNext Admin Password" \
--secret-string "YourSecureAdminPassword123!" \
--tags '[{"Key":"Application","Value":"ERPNext"},{"Key":"Environment","Value":"Production"}]'
# Store API credentials
aws secretsmanager create-secret \
--name "erpnext/api/credentials" \
--description "ERPNext API Credentials" \
--secret-string '{"api_key":"your-api-key-here","api_secret":"your-api-secret-here"}' \
--tags '[{"Key":"Application","Value":"ERPNext"},{"Key":"Environment","Value":"Production"}]'
```
## 📊 CloudWatch and Monitoring Setup
```bash
# Create CloudWatch log groups
aws logs create-log-group \
--log-group-name /aws/ecs/erpnext-backend \
--retention-in-days 7
aws logs create-log-group \
--log-group-name /aws/ecs/erpnext-frontend \
--retention-in-days 7
aws logs create-log-group \
--log-group-name /aws/ecs/erpnext-worker \
--retention-in-days 7
# Create SNS topic for alerts
aws sns create-topic \
--name erpnext-alerts \
--tags Key=Application,Value=ERPNext
# Subscribe email to alerts (replace with your email)
aws sns subscribe \
--topic-arn arn:aws:sns:us-east-1:$(aws sts get-caller-identity --query Account --output text):erpnext-alerts \
--protocol email \
--notification-endpoint your-email@yourdomain.com
```
## 🔍 Verification Checklist
Before proceeding to deployment, verify:
```bash
# Check AWS credentials and region
aws sts get-caller-identity
aws configure get region
# Verify VPC and subnets
aws ec2 describe-vpcs --filters "Name=tag:Name,Values=erpnext-vpc"
aws ec2 describe-subnets --filters "Name=vpc-id,Values=$VPC_ID"
# Check security groups
aws ec2 describe-security-groups --filters "Name=vpc-id,Values=$VPC_ID"
# Verify RDS instance
aws rds describe-db-instances --db-instance-identifier erpnext-db
# Check MemoryDB cluster
aws memorydb describe-clusters --cluster-name erpnext-redis
# Verify secrets
aws secretsmanager list-secrets --filters Key=tag-key,Values=Application Key=tag-value,Values=ERPNext
# Check IAM roles
aws iam get-role --role-name ERPNextECSTaskRole
# Verify CloudWatch log groups
aws logs describe-log-groups --log-group-name-prefix /aws/ecs/erpnext
```
## 💡 Cost Optimization for Managed Services
### 1. RDS Optimization
```bash
# Use appropriate instance types
# Development: db.t3.micro or db.t3.small
# Production: db.t3.medium or larger
# Enable storage autoscaling
aws rds modify-db-instance \
--db-instance-identifier erpnext-db \
--max-allocated-storage 1000 \
--apply-immediately
# Use Reserved Instances for production (1-3 year terms)
aws rds describe-reserved-db-instances-offerings \
--db-instance-class db.t3.medium \
--engine mysql
```
### 2. MemoryDB Optimization
```bash
# Right-size cluster based on memory usage
# Start with db.t4g.small and scale based on usage
# Monitor memory utilization and adjust
# Use Multi-AZ only for production
# Single-AZ for development/testing environments
```
### 3. Network Cost Optimization
```bash
# Use same AZ for services to minimize data transfer costs
# Monitor VPC Flow Logs for inter-AZ traffic
# Consider VPC endpoints for AWS services if needed
```
## 🚨 Security Best Practices for Managed Services
### 1. Network Security
- **VPC isolation**: All managed services use private subnets
- **Security groups**: Restrictive access between tiers
- **No public access**: Database and Redis not accessible from internet
### 2. Access Control
```bash
# Enable RDS IAM database authentication
aws rds modify-db-instance \
--db-instance-identifier erpnext-db \
--enable-iam-database-authentication \
--apply-immediately
# Create IAM database user
aws rds create-db-instance-read-replica \
--db-instance-identifier erpnext-db-read-replica \
--source-db-instance-identifier erpnext-db \
--db-instance-class db.t3.small
```
### 3. Encryption
- **Encryption at rest**: Enabled by default for both services
- **Encryption in transit**: SSL/TLS enforced
- **Secrets management**: AWS Secrets Manager for credentials
## 📚 Additional Resources
- [Amazon RDS Documentation](https://docs.aws.amazon.com/rds/)
- [Amazon MemoryDB Documentation](https://docs.aws.amazon.com/memorydb/)
- [Amazon ECS Documentation](https://docs.aws.amazon.com/ecs/)
- [Amazon EKS Documentation](https://docs.aws.amazon.com/eks/)
- [AWS VPC Documentation](https://docs.aws.amazon.com/vpc/)
## ➡️ Next Steps
After completing prerequisites:
1. **ECS with Managed Services**: Follow `01-ecs-managed-deployment.md`
2. **EKS with Managed Services**: Follow `02-eks-managed-deployment.md`
3. **Production Hardening**: See `03-production-managed-setup.md`
---
**⚠️ Important Notes**:
- Managed services incur continuous costs even when not in use
- Plan your backup and disaster recovery strategy
- Monitor costs regularly using AWS Cost Explorer
- Keep track of all resources created for billing purposes
- Use AWS Config for compliance and governance