package com.unicorn; import software.amazon.awscdk.Duration; import software.amazon.awscdk.Stack; import software.amazon.awscdk.StackProps; import software.amazon.awscdk.services.ec2.ISecurityGroup; import software.amazon.awscdk.services.ec2.IVpc; import software.amazon.awscdk.services.ec2.InstanceClass; import software.amazon.awscdk.services.ec2.InstanceSize; import software.amazon.awscdk.services.ec2.InstanceType; import software.amazon.awscdk.services.ec2.Peer; import software.amazon.awscdk.services.ec2.Port; import software.amazon.awscdk.services.ec2.SecurityGroup; import software.amazon.awscdk.services.ec2.SecurityGroupProps; import software.amazon.awscdk.services.ec2.SubnetSelection; import software.amazon.awscdk.services.ec2.SubnetType; import software.amazon.awscdk.services.ec2.Vpc; import software.amazon.awscdk.services.rds.Credentials; import software.amazon.awscdk.services.rds.DatabaseInstance; import software.amazon.awscdk.services.rds.DatabaseInstanceEngine; import software.amazon.awscdk.services.rds.DatabaseSecret; import software.amazon.awscdk.services.rds.PostgresEngineVersion; import software.amazon.awscdk.services.rds.PostgresInstanceEngineProps; import software.constructs.Construct; import java.util.List; public class InfrastructureStack extends Stack { private final DatabaseSecret databaseSecret; private final DatabaseInstance database; private final IVpc vpc; private final ISecurityGroup applicationSecurityGroup; public InfrastructureStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); vpc = createUnicornVpc(); databaseSecret = createDatabaseSecret(); database = createRDSPostgresInstance(vpc, databaseSecret); applicationSecurityGroup = new SecurityGroup(this, "ApplicationSecurityGroup", SecurityGroupProps .builder() .securityGroupName("applicationSG") .vpc(vpc) .allowAllOutbound(true) .build()); new DatabaseSetupConstruct(this, "UnicornDatabaseConstruct"); } private SecurityGroup createDatabaseSecurityGroup(IVpc vpc) { var databaseSecurityGroup = SecurityGroup.Builder.create(this, "DatabaseSG") .securityGroupName("DatabaseSG") .allowAllOutbound(false) .vpc(vpc) .build(); databaseSecurityGroup.addIngressRule( Peer.ipv4("10.0.0.0/16"), Port.tcp(5432), "Allow Database Traffic from local network"); return databaseSecurityGroup; } private DatabaseInstance createRDSPostgresInstance(IVpc vpc, DatabaseSecret databaseSecret) { var databaseSecurityGroup = createDatabaseSecurityGroup(vpc); var engine = DatabaseInstanceEngine.postgres(PostgresInstanceEngineProps.builder().version(PostgresEngineVersion.VER_13_4).build()); return DatabaseInstance.Builder.create(this, "UnicornInstance") .engine(engine) .vpc(vpc) .allowMajorVersionUpgrade(true) .backupRetention(Duration.days(0)) .databaseName("unicorns") .instanceIdentifier("UnicornInstance") .instanceType(InstanceType.of(InstanceClass.BURSTABLE3, InstanceSize.MEDIUM)) .vpcSubnets(SubnetSelection.builder() .subnetType(SubnetType.PRIVATE_WITH_EGRESS) .build()) .securityGroups(List.of(databaseSecurityGroup)) .credentials(Credentials.fromSecret(databaseSecret)) .build(); } private DatabaseSecret createDatabaseSecret() { return DatabaseSecret.Builder.create(this, "postgres") .secretName("unicornstore-db-secret") .username("postgres") .build(); } private IVpc createUnicornVpc() { return Vpc.Builder.create(this, "UnicornVpc") .vpcName("UnicornVPC") .build(); } public IVpc getVpc() { return vpc; } public ISecurityGroup getApplicationSecurityGroup() { return applicationSecurityGroup; } public String getDatabaseSecretString() { return databaseSecret.secretValueFromJson("password").toString(); } public String getDatabaseJDBCConnectionString() { return "jdbc:postgresql://" + database.getDbInstanceEndpointAddress() + ":5432/unicorns"; } }