ℹ️ Infrastructure as Code (IaC) là gì?
Infrastructure as Code là thực hành quản lý và cung cấp hạ tầng máy tính thông qua các tệp định nghĩa có thể đọc được bằng máy, thay vì cấu hình phần cứng vật lý hoặc các công cụ cấu hình tương tác.
🚀 Xuất sắc Vận hành:
💰 Tối ưu Chi phí:
🔒 Bảo mật & Tuân thủ:
AWSTemplateFormatVersion: '2010-09-09'
Description: 'VPC production-ready với multi-AZ NAT Gateways, Flow Logs, và Security Groups'
Parameters:
VpcCidr:
Type: String
Default: '10.10.0.0/16'
Description: 'CIDR block cho VPC'
Environment:
Type: String
Default: 'prod'
AllowedValues: ['dev', 'staging', 'prod']
Description: 'Tên môi trường'
Resources:
# VPC
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCidr
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: !Sub '${Environment}-VPC'
- Key: Environment
Value: !Ref Environment
# Internet Gateway
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub '${Environment}-IGW'
InternetGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref VPC
# Public Subnets
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [0, !GetAZs '']
CidrBlock: !Select [0, !Cidr [!Ref VpcCidr, 4, 8]]
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub '${Environment}-Public-Subnet-AZ1'
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [1, !GetAZs '']
CidrBlock: !Select [1, !Cidr [!Ref VpcCidr, 4, 8]]
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub '${Environment}-Public-Subnet-AZ2'
# Private Subnets
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [0, !GetAZs '']
CidrBlock: !Select [2, !Cidr [!Ref VpcCidr, 4, 8]]
Tags:
- Key: Name
Value: !Sub '${Environment}-Private-Subnet-AZ1'
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [1, !GetAZs '']
CidrBlock: !Select [3, !Cidr [!Ref VpcCidr, 4, 8]]
Tags:
- Key: Name
Value: !Sub '${Environment}-Private-Subnet-AZ2'
# NAT Gateways
NatGateway1EIP:
Type: AWS::EC2::EIP
DependsOn: InternetGatewayAttachment
Properties:
Domain: vpc
Tags:
- Key: Name
Value: !Sub '${Environment}-NAT-EIP-AZ1'
NatGateway2EIP:
Type: AWS::EC2::EIP
DependsOn: InternetGatewayAttachment
Properties:
Domain: vpc
Tags:
- Key: Name
Value: !Sub '${Environment}-NAT-EIP-AZ2'
NatGateway1:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt NatGateway1EIP.AllocationId
SubnetId: !Ref PublicSubnet1
Tags:
- Key: Name
Value: !Sub '${Environment}-NAT-Gateway-AZ1'
NatGateway2:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt NatGateway2EIP.AllocationId
SubnetId: !Ref PublicSubnet2
Tags:
- Key: Name
Value: !Sub '${Environment}-NAT-Gateway-AZ2'
# Route Tables
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${Environment}-Public-Routes'
DefaultPublicRoute:
Type: AWS::EC2::Route
DependsOn: InternetGatewayAttachment
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
PublicSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PublicRouteTable
SubnetId: !Ref PublicSubnet1
PublicSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PublicRouteTable
SubnetId: !Ref PublicSubnet2
PrivateRouteTable1:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${Environment}-Private-Routes-AZ1'
DefaultPrivateRoute1:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable1
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NatGateway1
PrivateSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PrivateRouteTable1
SubnetId: !Ref PrivateSubnet1
PrivateRouteTable2:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${Environment}-Private-Routes-AZ2'
DefaultPrivateRoute2:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable2
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NatGateway2
PrivateSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PrivateRouteTable2
SubnetId: !Ref PrivateSubnet2
# Security Groups
PublicSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub '${Environment}-Public-SG'
GroupDescription: 'Security group cho tài nguyên public subnet'
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0 # Hạn chế trong production
Description: 'SSH access'
- IpProtocol: icmp
FromPort: -1
ToPort: -1
CidrIp: !Ref VpcCidr
Description: 'ICMP trong VPC'
Tags:
- Key: Name
Value: !Sub '${Environment}-Public-SG'
PrivateSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub '${Environment}-Private-SG'
GroupDescription: 'Security group cho tài nguyên private subnet'
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
SourceSecurityGroupId: !Ref PublicSecurityGroup
Description: 'SSH từ public subnet'
- IpProtocol: icmp
FromPort: -1
ToPort: -1
CidrIp: !Ref VpcCidr
Description: 'ICMP trong VPC'
Tags:
- Key: Name
Value: !Sub '${Environment}-Private-SG'
# VPC Flow Logs
VPCFlowLogRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: vpc-flow-logs.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: flowlogsDeliveryRolePolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
- logs:DescribeLogGroups
- logs:DescribeLogStreams
Resource: '*'
VPCFlowLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub '/aws/vpc/flowlogs/${Environment}'
RetentionInDays: 30
VPCFlowLog:
Type: AWS::EC2::FlowLog
Properties:
ResourceType: VPC
ResourceId: !Ref VPC
TrafficType: ALL
LogDestinationType: cloud-watch-logs
LogGroupName: !Ref VPCFlowLogGroup
DeliverLogsPermissionArn: !GetAtt VPCFlowLogRole.Arn
Tags:
- Key: Name
Value: !Sub '${Environment}-VPC-FlowLogs'
Outputs:
VPC:
Description: 'VPC ID'
Value: !Ref VPC
Export:
Name: !Sub '${Environment}-VPC-ID'
PublicSubnets:
Description: 'Public subnet IDs'
Value: !Join [',', [!Ref PublicSubnet1, !Ref PublicSubnet2]]
Export:
Name: !Sub '${Environment}-Public-Subnets'
PrivateSubnets:
Description: 'Private subnet IDs'
Value: !Join [',', [!Ref PrivateSubnet1, !Ref PrivateSubnet2]]
Export:
Name: !Sub '${Environment}-Private-Subnets'
PublicSecurityGroup:
Description: 'Public security group ID'
Value: !Ref PublicSecurityGroup
Export:
Name: !Sub '${Environment}-Public-SG'
PrivateSecurityGroup:
Description: 'Private security group ID'
Value: !Ref PrivateSecurityGroup
Export:
Name: !Sub '${Environment}-Private-SG'
# Triển khai stack
aws cloudformation create-stack \
--stack-name production-vpc \
--template-body file://vpc-template.yaml \
--parameters ParameterKey=Environment,ParameterValue=prod \
--capabilities CAPABILITY_IAM
# Giám sát triển khai
aws cloudformation describe-stacks \
--stack-name production-vpc \
--query 'Stacks[0].StackStatus'
# Cài đặt dependencies
npm install
# Bootstrap CDK (chỉ lần đầu)
cdk bootstrap
# Triển khai stack
cdk deploy ProductionVpcStack
# Xem outputs
cdk output ProductionVpcStack
# Khởi tạo Terraform
terraform init
# Lập kế hoạch triển khai
terraform plan
# Áp dụng cấu hình
terraform apply
# Xem outputs
terraform output
🔒 Bảo mật:
💰 Quản lý Chi phí:
⚡ Xuất sắc Vận hành:
🔄 Độ tin cậy:
Phương pháp Infrastructure as Code này đảm bảo các triển khai VPC của bạn nhất quán, có thể lặp lại và tuân theo các thực hành tốt nhất của AWS trong khi cho phép mở rộng nhanh chóng và quản lý môi trường.