From c71288a20074dc01e8ad77a001bbfb1d58c2bb56 Mon Sep 17 00:00:00 2001 From: fahd Date: Wed, 12 Aug 2026 14:00:01 +0300 Subject: [PATCH] FEAT: Provisioned Postgres Managed Service --- infrastructure/go.mod | 1 + infrastructure/go.sum | 3 ++ infrastructure/main.go | 90 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+) diff --git a/infrastructure/go.mod b/infrastructure/go.mod index 9aa5935..570005a 100644 --- a/infrastructure/go.mod +++ b/infrastructure/go.mod @@ -71,6 +71,7 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/pkg/term v1.1.0 // indirect github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231 // indirect + github.com/pulumi/pulumi-random/sdk/v4 v4.21.1 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 // indirect diff --git a/infrastructure/go.sum b/infrastructure/go.sum index 2208ae4..3b13c14 100644 --- a/infrastructure/go.sum +++ b/infrastructure/go.sum @@ -172,6 +172,8 @@ github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231 h1:vkHw5I/plNdTr435 github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231/go.mod h1:murToZ2N9hNJzewjHBgfFdXhZKjY3z5cYC1VXk+lbFE= github.com/pulumi/pulumi-aws/sdk/v7 v7.40.0 h1:hCWhnZ4qaXECoxFrUGmDh1S4U6aCMuPghllRvZc+VqY= github.com/pulumi/pulumi-aws/sdk/v7 v7.40.0/go.mod h1:jv6dSPiG6CDnje0YLo7MdzkvR91kWCJjXcnETXwJdrw= +github.com/pulumi/pulumi-random/sdk/v4 v4.21.1 h1:pqvBaBMwFPP3DV8BYh/f45V4A62kFqJRQv171pfgObk= +github.com/pulumi/pulumi-random/sdk/v4 v4.21.1/go.mod h1:4Q2jFqgCimgOQxvWntZSnV6u8+JhCkPHewloJQfLoeQ= github.com/pulumi/pulumi/sdk/v3 v3.256.0 h1:OrkIu7Iw3HUcMtoEy2uzpD21C32B5EYBLBgBoh/uQPM= github.com/pulumi/pulumi/sdk/v3 v3.256.0/go.mod h1:pyX/FL1Ta3mn4UPfYh2LKG+q/90i2+Jnl0OX4cS+b9U= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= @@ -190,6 +192,7 @@ github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= diff --git a/infrastructure/main.go b/infrastructure/main.go index 101b954..6c69251 100644 --- a/infrastructure/main.go +++ b/infrastructure/main.go @@ -4,8 +4,11 @@ import ( "encoding/json" "github.com/pulumi/pulumi-aws/sdk/v7/go/aws/cloudfront" + "github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ec2" "github.com/pulumi/pulumi-aws/sdk/v7/go/aws/mediaconvert" + "github.com/pulumi/pulumi-aws/sdk/v7/go/aws/rds" "github.com/pulumi/pulumi-aws/sdk/v7/go/aws/s3" + "github.com/pulumi/pulumi-random/sdk/v4/go/random" "github.com/pulumi/pulumi/sdk/v3/go/pulumi" ) @@ -120,9 +123,96 @@ func main() { return err } + // Small, single-AZ Postgres instance for the assignment: default VPC, + // no public access, no Multi-AZ, no backups, destroyable without a snapshot. + vpc, err := ec2.LookupVpc(ctx, &ec2.LookupVpcArgs{Default: pulumi.BoolRef(true)}) + if err != nil { + return err + } + + subnets, err := ec2.GetSubnets(ctx, &ec2.GetSubnetsArgs{ + Filters: []ec2.GetSubnetsFilter{ + {Name: "vpc-id", Values: []string{vpc.Id}}, + }, + }) + if err != nil { + return err + } + + dbSubnetGroup, err := rds.NewSubnetGroup(ctx, "postgres-subnet-group", &rds.SubnetGroupArgs{ + SubnetIds: pulumi.ToStringArray(subnets.Ids), + }) + if err != nil { + return err + } + + dbSecurityGroup, err := ec2.NewSecurityGroup(ctx, "postgres-sg", &ec2.SecurityGroupArgs{ + Description: pulumi.String("Allow Postgres access from within the VPC only"), + VpcId: pulumi.String(vpc.Id), + Ingress: ec2.SecurityGroupIngressArray{ + &ec2.SecurityGroupIngressArgs{ + Protocol: pulumi.String("tcp"), + FromPort: pulumi.Int(5432), + ToPort: pulumi.Int(5432), + CidrBlocks: pulumi.ToStringArray([]string{vpc.CidrBlock}), + }, + }, + Egress: ec2.SecurityGroupEgressArray{ + &ec2.SecurityGroupEgressArgs{ + Protocol: pulumi.String("-1"), + FromPort: pulumi.Int(0), + ToPort: pulumi.Int(0), + CidrBlocks: pulumi.ToStringArray([]string{"0.0.0.0/0"}), + }, + }, + }) + if err != nil { + return err + } + + // Generated once and kept in the stack state, so it stays stable across deploys + // unless explicitly replaced. RDS master passwords can't contain '/', '@', '"', or spaces. + dbPassword, err := random.NewRandomPassword(ctx, "postgres-db-password", &random.RandomPasswordArgs{ + Length: pulumi.Int(24), + Special: pulumi.Bool(true), + OverrideSpecial: pulumi.String("!#$%&*()-_=+[]{}<>:?"), + MinUpper: pulumi.Int(1), + MinLower: pulumi.Int(1), + MinNumeric: pulumi.Int(1), + MinSpecial: pulumi.Int(1), + }) + if err != nil { + return err + } + + db, err := rds.NewInstance(ctx, "postgres-db", &rds.InstanceArgs{ + Engine: pulumi.String("postgres"), + EngineVersion: pulumi.String("16"), + InstanceClass: pulumi.String("db.t3.micro"), + AllocatedStorage: pulumi.Int(20), + StorageType: pulumi.String("gp3"), + StorageEncrypted: pulumi.Bool(true), + DbName: pulumi.String("appdb"), + Username: pulumi.String("postgres"), + Password: dbPassword.Result, + DbSubnetGroupName: dbSubnetGroup.Name, + VpcSecurityGroupIds: pulumi.StringArray{dbSecurityGroup.ID()}, + PubliclyAccessible: pulumi.Bool(false), + MultiAz: pulumi.Bool(false), + BackupRetentionPeriod: pulumi.Int(0), + DeletionProtection: pulumi.Bool(false), + SkipFinalSnapshot: pulumi.Bool(true), + ApplyImmediately: pulumi.Bool(true), + }) + if err != nil { + return err + } + // Export the name of the bucket ctx.Export("bucketName", bucket.ID()) ctx.Export("cdnDomainName", distribution.DomainName) + ctx.Export("dbEndpoint", db.Endpoint) + ctx.Export("dbPassword", dbPassword.Result) return nil }) }