2026-08-06 03:51:36 +00:00
|
|
|
import * as cdk from 'aws-cdk-lib';
|
|
|
|
|
import { Construct } from 'constructs';
|
|
|
|
|
import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
2026-08-06 06:06:39 +00:00
|
|
|
import * as iam from 'aws-cdk-lib/aws-iam';
|
2026-08-06 03:51:36 +00:00
|
|
|
|
|
|
|
|
export class AwsCdkStack extends cdk.Stack {
|
|
|
|
|
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
|
|
|
|
|
super(scope, id, props);
|
|
|
|
|
|
|
|
|
|
// 1. Look up the existing Default VPC (Free, avoids NAT Gateway charges)
|
|
|
|
|
const vpc = ec2.Vpc.fromLookup(this, 'DefaultVpc', {
|
|
|
|
|
isDefault: true,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 2. Create a Security Group for the Mail Server
|
|
|
|
|
const securityGroup = new ec2.SecurityGroup(this, 'MailServerSG', {
|
|
|
|
|
vpc,
|
|
|
|
|
description: 'Security Group for self-hosted mail server',
|
|
|
|
|
allowAllOutbound: true,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Allow SSH
|
|
|
|
|
securityGroup.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(22), 'Allow SSH access');
|
|
|
|
|
|
|
|
|
|
// Mail Protocols (SMTP, SMTPS, Submission)
|
|
|
|
|
securityGroup.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(25), 'Allow SMTP');
|
|
|
|
|
securityGroup.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(465), 'Allow SMTPS');
|
|
|
|
|
securityGroup.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(587), 'Allow SMTP Submission');
|
|
|
|
|
|
|
|
|
|
// Mail Protocols (IMAP, IMAPS)
|
|
|
|
|
securityGroup.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(143), 'Allow IMAP');
|
|
|
|
|
securityGroup.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(993), 'Allow IMAPS');
|
|
|
|
|
|
|
|
|
|
// Web Traffic (HTTP, HTTPS for Admin UI & Webmail / SSL certificates)
|
|
|
|
|
securityGroup.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(80), 'Allow HTTP');
|
|
|
|
|
securityGroup.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(443), 'Allow HTTPS');
|
|
|
|
|
|
2026-08-06 05:36:03 +00:00
|
|
|
// WireGuard VPN
|
|
|
|
|
securityGroup.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.udp(51820), 'Allow WireGuard VPN');
|
2026-08-06 05:43:03 +00:00
|
|
|
securityGroup.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(51821), 'Allow WireGuard Web UI');
|
2026-08-06 05:36:03 +00:00
|
|
|
|
2026-08-06 06:06:39 +00:00
|
|
|
// Create IAM Role for EC2 Instance (to allow CloudWatch Agent to write logs & metrics)
|
|
|
|
|
const role = new iam.Role(this, 'MailServerRole', {
|
|
|
|
|
assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
|
|
|
|
|
managedPolicies: [
|
|
|
|
|
iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchAgentServerPolicy'),
|
|
|
|
|
],
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 3. Define the EC2 Instance (t3.micro for Free Tier compatibility)
|
2026-08-06 03:51:36 +00:00
|
|
|
const instance = new ec2.Instance(this, 'MailServerInstance', {
|
|
|
|
|
vpc,
|
|
|
|
|
vpcSubnets: { subnetType: ec2.SubnetType.PUBLIC },
|
2026-08-06 05:30:10 +00:00
|
|
|
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO),
|
2026-08-06 05:23:49 +00:00
|
|
|
machineImage: ec2.MachineImage.fromSsmParameter(
|
|
|
|
|
'/aws/service/canonical/ubuntu/server/24.04/stable/current/amd64/hvm/ebs-gp3/ami-id'
|
|
|
|
|
),
|
2026-08-06 03:51:36 +00:00
|
|
|
securityGroup,
|
2026-08-06 06:06:39 +00:00
|
|
|
role,
|
2026-08-06 05:45:09 +00:00
|
|
|
keyName: 'vignesh_tipro',
|
2026-08-06 06:13:00 +00:00
|
|
|
detailedMonitoring: true,
|
2026-08-06 03:51:36 +00:00
|
|
|
blockDevices: [
|
|
|
|
|
{
|
|
|
|
|
deviceName: '/dev/sda1',
|
|
|
|
|
volume: ec2.BlockDeviceVolume.ebs(60, { // 60GB Root Volume
|
|
|
|
|
volumeType: ec2.EbsDeviceVolumeType.GP3,
|
|
|
|
|
}),
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
});
|
|
|
|
|
|
2026-08-06 06:06:39 +00:00
|
|
|
// 4. Install Docker, Docker Compose, wg-easy, and CloudWatch Agent via User Data
|
2026-08-06 03:51:36 +00:00
|
|
|
instance.addUserData(
|
|
|
|
|
'apt-get update -y',
|
2026-08-06 06:06:39 +00:00
|
|
|
'apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release wget',
|
2026-08-06 03:51:36 +00:00
|
|
|
'mkdir -m 0755 -p /etc/apt/keyrings',
|
|
|
|
|
'curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg',
|
|
|
|
|
'echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null',
|
|
|
|
|
'apt-get update -y',
|
|
|
|
|
'apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin',
|
|
|
|
|
'systemctl enable docker',
|
2026-08-06 05:43:03 +00:00
|
|
|
'systemctl start docker',
|
2026-08-06 06:01:47 +00:00
|
|
|
// Setup wireguard directory
|
2026-08-06 05:43:03 +00:00
|
|
|
'mkdir -p /home/ubuntu/wireguard',
|
|
|
|
|
'cd /home/ubuntu/wireguard',
|
2026-08-06 06:01:47 +00:00
|
|
|
// Write the docker-compose.yml file with hardcoded Elastic IP
|
2026-08-06 05:43:03 +00:00
|
|
|
'cat <<EOF > docker-compose.yml',
|
|
|
|
|
'services:',
|
|
|
|
|
' wg-easy:',
|
|
|
|
|
' image: weejewel/wg-easy',
|
|
|
|
|
' container_name: wg-easy',
|
|
|
|
|
' environment:',
|
2026-08-06 06:03:23 +00:00
|
|
|
' - WG_HOST=13.205.93.190',
|
2026-08-06 05:43:03 +00:00
|
|
|
' - PASSWORD=admin123',
|
|
|
|
|
' volumes:',
|
|
|
|
|
' - ./config:/etc/wireguard',
|
|
|
|
|
' ports:',
|
|
|
|
|
' - "51820:51820/udp"',
|
|
|
|
|
' - "51821:51821/tcp"',
|
|
|
|
|
' cap_add:',
|
|
|
|
|
' - NET_ADMIN',
|
|
|
|
|
' - SYS_MODULE',
|
|
|
|
|
' sysctls:',
|
|
|
|
|
' - net.ipv4.ip_forward=1',
|
|
|
|
|
' - net.ipv4.conf.all.src_valid_mark=1',
|
|
|
|
|
' restart: unless-stopped',
|
|
|
|
|
'EOF',
|
|
|
|
|
// Start the container and adjust directory permissions
|
|
|
|
|
'docker compose up -d',
|
2026-08-06 06:06:39 +00:00
|
|
|
'chown -R ubuntu:ubuntu /home/ubuntu/wireguard',
|
|
|
|
|
// Install CloudWatch Agent
|
|
|
|
|
'wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/amd64/latest/amazon-cloudwatch-agent.deb',
|
|
|
|
|
'dpkg -i -E ./amazon-cloudwatch-agent.deb',
|
|
|
|
|
// Write CloudWatch Agent Configuration
|
|
|
|
|
'mkdir -p /opt/aws/amazon-cloudwatch-agent/etc',
|
|
|
|
|
'cat <<EOF > /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json',
|
|
|
|
|
'{',
|
|
|
|
|
' "agent": {',
|
|
|
|
|
' "metrics_collection_interval": 60,',
|
|
|
|
|
' "run_as_user": "root"',
|
|
|
|
|
' },',
|
|
|
|
|
' "metrics": {',
|
|
|
|
|
' "metrics_collected": {',
|
|
|
|
|
' "disk": {',
|
|
|
|
|
' "measurement": ["used_percent"],',
|
|
|
|
|
' "metrics_collection_interval": 60,',
|
|
|
|
|
' "resources": ["/"]',
|
|
|
|
|
' },',
|
|
|
|
|
' "mem": {',
|
|
|
|
|
' "measurement": ["mem_used_percent"],',
|
|
|
|
|
' "metrics_collection_interval": 60',
|
|
|
|
|
' }',
|
|
|
|
|
' }',
|
|
|
|
|
' },',
|
|
|
|
|
' "logs": {',
|
|
|
|
|
' "logs_collected": {',
|
|
|
|
|
' "files": {',
|
|
|
|
|
' "collect_list": [',
|
|
|
|
|
' {',
|
|
|
|
|
' "file_path": "/var/lib/docker/containers/*/*.log",',
|
|
|
|
|
' "log_group_name": "WireGuard-Logs",',
|
|
|
|
|
' "log_stream_name": "{instance_id}",',
|
|
|
|
|
' "retention_in_days": 7',
|
|
|
|
|
' }',
|
|
|
|
|
' ]',
|
|
|
|
|
' }',
|
|
|
|
|
' }',
|
|
|
|
|
' }',
|
|
|
|
|
'}',
|
|
|
|
|
'EOF',
|
|
|
|
|
// Start CloudWatch Agent service with configuration
|
|
|
|
|
'/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json'
|
2026-08-06 03:51:36 +00:00
|
|
|
);
|
|
|
|
|
|
2026-08-06 06:01:47 +00:00
|
|
|
// 5. Associate your pre-created Elastic IP using its Allocation ID
|
2026-08-06 03:51:36 +00:00
|
|
|
new ec2.CfnEIPAssociation(this, 'MailServerEIPAssociation', {
|
2026-08-06 06:08:04 +00:00
|
|
|
allocationId: 'eipalloc-06bea32c3a787c2b1',
|
2026-08-06 03:51:36 +00:00
|
|
|
instanceId: instance.instanceId,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Outputs
|
|
|
|
|
new cdk.CfnOutput(this, 'MailServerPublicIP', {
|
2026-08-06 06:03:23 +00:00
|
|
|
value: '13.205.93.190',
|
2026-08-06 03:51:36 +00:00
|
|
|
description: 'The Elastic IP address of your Mail Server',
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-06 06:01:47 +00:00
|
|
|
|
2026-08-06 06:03:23 +00:00
|
|
|
|
2026-08-06 06:06:39 +00:00
|
|
|
|