Skip to content

Commit

Permalink
feat(secrets-manager): move secret to Rds database construct
Browse files Browse the repository at this point in the history
  • Loading branch information
briancaffey committed Jun 13, 2021
1 parent e4a4141 commit 9344b3e
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 86 deletions.
21 changes: 19 additions & 2 deletions src/common/database/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,33 @@ import * as cdk from '@aws-cdk/core';

export interface RdsPostgresInstanceProps {
readonly vpc: ec2.IVpc;
readonly secret: secretsmanager.ISecret;
readonly dbSecretName: string;
}

export class RdsPostgresInstance extends cdk.Construct {

public rdsPostgresInstance: rds.IDatabaseInstance;
public rdsSecurityGroup: ec2.ISecurityGroup;
public secret: secretsmanager.ISecret;
public dbSecretName: string;

constructor(scope: cdk.Construct, id: string, props: RdsPostgresInstanceProps) {
super(scope, id);

/**
* Secret used for RDS postgres password
*/
this.secret = new secretsmanager.Secret(scope, 'dbSecret', {
secretName: props.dbSecretName,
description: 'secret for rds',
generateSecretString: {
secretStringTemplate: JSON.stringify({ username: 'postgres' }),
generateStringKey: 'password',
excludePunctuation: true,
includeSpace: false,
},
});

const rdsSecurityGroup = new ec2.SecurityGroup(scope, 'RdsSecurityGroup', {
vpc: props.vpc,
securityGroupName: 'RdsSecurityGroup',
Expand All @@ -34,8 +50,9 @@ export class RdsPostgresInstance extends cdk.Construct {
vpcPlacement: { subnetType: ec2.SubnetType.ISOLATED },
port: 5432,
securityGroups: [rdsSecurityGroup],
credentials: rds.Credentials.fromSecret(props.secret),
credentials: rds.Credentials.fromSecret(this.secret),
});
this.rdsPostgresInstance = rdsPostgresInstance;
this.dbSecretName = props.dbSecretName;
}
}
14 changes: 2 additions & 12 deletions src/django-ecs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import * as ecs from '@aws-cdk/aws-ecs';
import * as patterns from '@aws-cdk/aws-ecs-patterns';
import * as logs from '@aws-cdk/aws-logs';
import * as s3 from '@aws-cdk/aws-s3';
import * as secretsmanager from '@aws-cdk/aws-secretsmanager';
import * as cdk from '@aws-cdk/core';
import { RdsPostgresInstance } from './common/database';
import { ElastiCacheCluster } from './common/elasticache';
Expand Down Expand Up @@ -64,7 +63,6 @@ export class DjangoEcs extends cdk.Construct {
public vpc: ec2.IVpc;
public cluster: ecs.Cluster;
public image: ecs.ContainerImage;
private secret: secretsmanager.ISecret;

constructor(scope: cdk.Construct, id: string, props: DjangoEcsProps) {
super(scope, id);
Expand Down Expand Up @@ -104,14 +102,6 @@ export class DjangoEcs extends cdk.Construct {
memoryMiB: '512',
});

/**
* Secret used for RDS postgres password
*/
this.secret = new secretsmanager.Secret(scope, 'dbSecret', {
secretName: 'dbSecret',
description: 'secret for rds',
});

/**
* Container image used in web API, celery worker and management task containers
*/
Expand All @@ -122,7 +112,7 @@ export class DjangoEcs extends cdk.Construct {
*/
const database = new RdsPostgresInstance(scope, 'RdsPostgresInstance', {
vpc: this.vpc,
secret: this.secret,
dbSecretName: 'dbSecret',
});


Expand All @@ -146,7 +136,7 @@ export class DjangoEcs extends cdk.Construct {
const environment: { [key: string]: string } = {
AWS_STORAGE_BUCKET_NAME: staticFilesBucket.bucketName,
POSTGRES_SERVICE_HOST: database.rdsPostgresInstance.dbInstanceEndpointAddress,
POSTGRES_PASSWORD: this.secret.secretValue.toString(),
DB_SECRET_NAME: database.dbSecretName,
DEBUG: '0',
DJANGO_SETTINGS_MODULE: 'backend.settings.production',
REDIS_SERVICE_HOST: elastiCacheRedis.elastiCacheCluster.attrRedisEndpointAddress,
Expand Down
82 changes: 11 additions & 71 deletions src/django-eks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ import * as ec2 from '@aws-cdk/aws-ec2';
import * as ecrAssets from '@aws-cdk/aws-ecr-assets';
import * as eks from '@aws-cdk/aws-eks';
// import * as logs from '@aws-cdk/aws-logs';
import * as elbv2 from '@aws-cdk/aws-elasticloadbalancingv2';
import * as iam from '@aws-cdk/aws-iam';
import * as s3 from '@aws-cdk/aws-s3';
import * as secretsmanager from '@aws-cdk/aws-secretsmanager';
import * as cdk from '@aws-cdk/core';
import { RdsPostgresInstance } from './common/database';
import { ApplicationVpc } from './common/vpc';
Expand Down Expand Up @@ -67,8 +65,6 @@ export class DjangoEks extends cdk.Construct {
public staticFileBucket: s3.Bucket;
public vpc: ec2.IVpc;
public cluster: eks.Cluster;
private secret: secretsmanager.ISecret;


constructor(scope: cdk.Construct, id: string, props: DjangoEksProps) {
super(scope, id);
Expand Down Expand Up @@ -122,21 +118,6 @@ export class DjangoEks extends cdk.Construct {
},
});

const DB_SECRET_NAME = 'dbSecret';
/**
* Secret used for RDS postgres password
*/
this.secret = new secretsmanager.Secret(scope, 'dbSecret', {
secretName: DB_SECRET_NAME,
description: 'secret for rds',
generateSecretString: {
secretStringTemplate: JSON.stringify({ username: 'postgres' }),
generateStringKey: 'password',
excludePunctuation: true,
includeSpace: false,
},
});

/**
* Creates an IAM role with a trust relationship that is scoped to the cluster's OIDC provider
* https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-technical-overview.html
Expand All @@ -147,27 +128,27 @@ export class DjangoEks extends cdk.Construct {
const irsa = new Irsa(scope, 'Irsa', {
cluster: this.cluster,
});
irsa.node.addDependency(appNamespace);

/**
* Make sure that the namespace has been deployed
*/
irsa.node.addDependency(appNamespace);

/**
* Give the IRSA podRole read access to the bucket and read/write access to the S3 bucket
*/
this.secret.grantRead(irsa.podRole);
this.staticFileBucket.grantReadWrite(irsa.podRole);
irsa.chart.node.addDependency(appNamespace);

/**
* RDS instance
*/
const database = new RdsPostgresInstance(scope, 'RdsPostgresInstance', {
const database = new RdsPostgresInstance(scope, 'RdsPostgresInstance', {
vpc: this.vpc,
secret: this.secret,
// TODO: base dbSecret on environment name
dbSecretName: 'dbSecret',
});

/**
* Give the IRSA podRole read access to the bucket and read/write access to the S3 bucket
*/
database.secret.grantRead(irsa.podRole);
this.staticFileBucket.grantReadWrite(irsa.podRole);

/**
* Security Group for worker nodes
*/
Expand Down Expand Up @@ -215,7 +196,7 @@ export class DjangoEks extends cdk.Construct {
{
// this is used in the application to fetch the secret value
name: 'DB_SECRET_NAME',
value: DB_SECRET_NAME,
value: database.dbSecretName,

},
{
Expand Down Expand Up @@ -271,46 +252,5 @@ export class DjangoEks extends cdk.Construct {
ingress.node.addDependency(awslbc);
ingress.node.addDependency(webResources);

/**
* Get the ALB address using KubernetesObjectValue as a String
*
* This currently is not working, use .fromLookup instead (see below)
*/
// https://github.com/aws/aws-cdk/issues/14933
// const albAddress = new eks.KubernetesObjectValue(scope, 'AlbAddress', {
// cluster: this.cluster,
// objectType: 'ingress',
// objectNamespace: 'app',
// objectName: 'app-ingress',
// jsonPath: '.items[0].status.loadBalancer.ingress[0].hostname',
// });

/**
* Route53 A Record pointing to ALB that is created by AWS Application Load Balancer Controller
*
*/


/**
* Get the ALB created by the AWS Load Balancer Controller using by Tag
*/
const alb = elbv2.ApplicationLoadBalancer.fromLookup(this, 'appAlb', {
loadBalancerTags: {
Environment: 'test',
},
});

/**
* This might not be necessary, but the ingress needs to be created before looking up the ALB
* that it creates
*/
alb.node.addDependency(ingress);


/**
* Output the Load Balancer URL as a CfnOutput
*/
new cdk.CfnOutput(this, 'apiUrl', { value: alb.loadBalancerDnsName });

}
}
3 changes: 2 additions & 1 deletion src/eks/irsa/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface IrsaProps {
export class Irsa extends cdk.Construct {

public podRole: iam.Role;
public chart: eks.HelmChart;

constructor(scope: cdk.Construct, id: string, props: IrsaProps) {
super(scope, id);
Expand Down Expand Up @@ -58,7 +59,7 @@ export class Irsa extends cdk.Construct {
/**
* Apply the service account manfiest that will be used by pods running the application
*/
props.cluster.addManifest('pod-service-account', podServiceAccount);
this.chart = props.cluster.addManifest('pod-service-account', podServiceAccount);

}
}

0 comments on commit 9344b3e

Please sign in to comment.