in web-site/cdk/lib/database-stack.ts [12:90]
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Look up assets from other stacks.
const vpc = ec2.Vpc.fromLookup(this, 'vpc', {
vpcName: 'ecs-kerberos-stack/vpc'
});
// Set up an RDS SQL Server instance with Windows auth to the Active Directory.
// Create a SQL Server instance inside the VPC and joined to the existing directory.
const sqlServerInstance = new rds.DatabaseInstance(this, 'web-sql-rds', {
engine: rds.DatabaseInstanceEngine.sqlServerSe({ version: SqlServerEngineVersion.VER_15 }),
licenseModel: rds.LicenseModel.LICENSE_INCLUDED,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE3, ec2.InstanceSize.XLARGE),
vpc: vpc,
vpcPlacement: { subnetType: ec2.SubnetType.PRIVATE_WITH_NAT },
credentials: rds.Credentials.fromGeneratedSecret('web_dbo'),
autoMinorVersionUpgrade: true,
// You may wish to change these settings in a production environment.
deletionProtection: false,
removalPolicy: cdk.RemovalPolicy.DESTROY
});
// Set up credential rotation for the DB administrator user.
sqlServerInstance.addRotationSingleUser();
// Store the database credentials secret ARN in the Systems Manager Parameter Store, so it can be referenced by the Web application stack.
const sqlServerInstanceSecretArnParameter = new ssm.StringParameter(this, 'sql-server-credentials-secret-arn', {
allowedPattern: '.*',
description: 'ARN of the secret containing the database credentials',
parameterName: '/ecs-kerberos-sample/web-site/sql-server-credentials-secret-arn',
stringValue: sqlServerInstance.secret?.secretArn ?? '',
tier: ssm.ParameterTier.STANDARD
});
// Create an IAM Role with the `AmazonRDSDirectoryServiceAccess` policy. This is required to join the SQL Server to the domain.
const dbRole = new iam.Role(this, 'rds-role', {
assumedBy: new iam.ServicePrincipal('rds.amazonaws.com'),
managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AmazonRDSDirectoryServiceAccess')],
});
// Join the SQL server to the domain. This isn't available in CDK yet, so use the CloudFormation primitives.
// In order to join the server to the domain, we need to know the ID of the Active Directory.
// The root stack stored this value in the Systems Manager Parameter Store.
const activeDirectoryId = ssm.StringParameter.fromStringParameterAttributes(this, 'active-directory-id-parameter-value', {
parameterName: '/ecs-kerberos-sample/active-directory-id',
}).stringValue;
const cfnSqlServerInstance = sqlServerInstance.node.defaultChild as rds.CfnDBInstance;
cfnSqlServerInstance.domain = activeDirectoryId;
cfnSqlServerInstance.domainIamRoleName = dbRole.roleName;
// Store the security group IDs in the Systems Manager Parameter Store, so they can be referenced by the Web application stack.
const sqlServerInstanceSecurityGroupId = new ssm.StringParameter(this, 'sql-server-security-group-id', {
allowedPattern: '.*',
description: 'ID of the Security Group for the Web Site RDS instance',
parameterName: '/ecs-kerberos-sample/web-site/sql-server-security-group-id',
stringValue: sqlServerInstance.connections.securityGroups[0].securityGroupId,
tier: ssm.ParameterTier.STANDARD
});
// Allow the AD management instance to connect to the database, so the management instance can be used to set up the database access.
const activeDirectoryManagementServerSecurityGroupId = ssm.StringParameter.fromStringParameterAttributes(this, 'directory-management-server-security-group-id', {
parameterName: '/ecs-kerberos-sample/directory-management-server-security-group-id',
}).stringValue;
const activeDirectoryManagementServerSecurityGroup = ec2.SecurityGroup.fromSecurityGroupId(this, 'active-directory-management-server-security-group', activeDirectoryManagementServerSecurityGroupId);
sqlServerInstance.connections.allowDefaultPortFrom(activeDirectoryManagementServerSecurityGroup,
'Consider removing this rule after the database deployment is complete.');
// Output information about the database instance.
new cdk.CfnOutput(this, 'DBInstanceIdentifier', { value: sqlServerInstance.instanceIdentifier });
new cdk.CfnOutput(this, 'DBInstanceEndpointAddress', { value: sqlServerInstance.dbInstanceEndpointAddress });
new cdk.CfnOutput(this, 'DBInstanceCredentialsSecretARN', { value: sqlServerInstance.secret?.secretArn ?? '' });
}