UNPKG

9.12 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const ResourceConstants_1 = require("./ResourceConstants");
4const dataSource_1 = require("cloudform-types/types/appSync/dataSource");
5const iam_1 = require("cloudform-types/types/iam");
6const cloudform_1 = require("cloudform");
7const RelationalDBResolverGenerator_1 = require("./RelationalDBResolverGenerator");
8/**
9 * This is the Class responsible for generating and managing the CloudForm template
10 * provided a TemplateContext object, which is generated by the RelationalDBSchemaTransformer.
11 *
12 * It will generate the basic CloudForm template needed for getting the AppSync API and
13 * RDS DataSource provisioned. It also allows for adding the CRUDL+Q Resolvers upon need.
14 */
15class RelationalDBTemplateGenerator {
16 constructor(context) {
17 this.context = context;
18 }
19 /**
20 * Creates and returns the basic Cloudform template needed for setting
21 * up an AppSync API pointing at the RDS DataSource.
22 *
23 * @returns the created CloudFormation template.
24 */
25 createTemplate(context) {
26 const template = {
27 AWSTemplateFormatVersion: "2010-09-09",
28 Parameters: this.makeParameters(this.context.databaseName),
29 Resources: {
30 [ResourceConstants_1.ResourceConstants.RESOURCES.RelationalDatabaseDataSource]: this.makeRelationalDataSource(context),
31 [ResourceConstants_1.ResourceConstants.RESOURCES.RelationalDatabaseAccessRole]: this.makeIAMDataSourceRole()
32 }
33 };
34 return template;
35 }
36 /**
37 * Provided a Cloudform Template, this method adds Resolver Resources to the
38 * Template.
39 *
40 * @param template - the Cloudform template
41 * @returns the given template, updated with new resolvers.
42 */
43 addRelationalResolvers(template, resolverFilePath) {
44 let resolverGenerator = new RelationalDBResolverGenerator_1.default(this.context);
45 template.Resources = Object.assign({}, template.Resources, resolverGenerator.createRelationalResolvers(resolverFilePath));
46 return template;
47 }
48 /**
49 * Provided a Cloudform Template, this method returns the cfn json template as a string
50 *
51 * @param template - the Cloudform template
52 * @returns the json, string form of the template given.
53 */
54 printCloudformationTemplate(template) {
55 return cloudform_1.default(template);
56 }
57 /*
58 * Private Helper Methods for Generating the Necessary CFN Specs for the CFN Template
59 */
60 /**
61 * Creates any Parmaters needed for the CFN Template
62 *
63 * @param databaseName - the name of the database being parsed.
64 * @returns the parameters for the template.
65 */
66 makeParameters(databaseName) {
67 return {
68 [ResourceConstants_1.ResourceConstants.PARAMETERS.AppSyncApiName]: new cloudform_1.StringParameter({
69 Description: `The name of the AppSync API generated from database ${databaseName}`,
70 Default: `AppSyncSimpleTransform`
71 }),
72 [ResourceConstants_1.ResourceConstants.PARAMETERS.Env]: new cloudform_1.StringParameter({
73 Description: 'The environment name. e.g. Dev, Test, or Production',
74 Default: 'NONE'
75 }),
76 [ResourceConstants_1.ResourceConstants.PARAMETERS.S3DeploymentBucket]: new cloudform_1.StringParameter({
77 Description: 'The S3 bucket containing all deployment assets for the project.'
78 }),
79 [ResourceConstants_1.ResourceConstants.PARAMETERS.S3DeploymentRootKey]: new cloudform_1.StringParameter({
80 Description: 'An S3 key relative to the S3DeploymentBucket that points to the root of the deployment directory.'
81 }),
82 [ResourceConstants_1.ResourceConstants.PARAMETERS.AppSyncApiId]: new cloudform_1.StringParameter({
83 Description: 'The id of the AppSync API associated with this project.'
84 }),
85 [ResourceConstants_1.ResourceConstants.PARAMETERS.rdsRegion]: new cloudform_1.StringParameter({
86 Description: 'The region that the RDS Cluster is located in.'
87 }),
88 [ResourceConstants_1.ResourceConstants.PARAMETERS.rdsClusterIdentifier]: new cloudform_1.StringParameter({
89 Description: 'The ARN identifier denoting the RDS cluster.'
90 }),
91 [ResourceConstants_1.ResourceConstants.PARAMETERS.rdsSecretStoreArn]: new cloudform_1.StringParameter({
92 Description: 'The ARN for the Secret containing the access for the RDS cluster.'
93 }),
94 [ResourceConstants_1.ResourceConstants.PARAMETERS.rdsDatabaseName]: new cloudform_1.StringParameter({
95 Description: 'The name of the database within the RDS cluster to use.'
96 })
97 };
98 }
99 /*
100 * Resources
101 */
102 /**
103 * Creates the IAM Role CFN Spec to allow AppSync to interact with the RDS cluster
104 *
105 * @returns the IAM role CloudFormation resource.
106 */
107 makeIAMDataSourceRole() {
108 return new iam_1.default.Role({
109 RoleName: cloudform_1.Fn.Join('-', [
110 'role',
111 cloudform_1.Fn.Ref(ResourceConstants_1.ResourceConstants.PARAMETERS.AppSyncApiId),
112 cloudform_1.Fn.Ref(ResourceConstants_1.ResourceConstants.PARAMETERS.Env)
113 ]),
114 AssumeRolePolicyDocument: {
115 Version: '2012-10-17',
116 Statement: [
117 {
118 Effect: 'Allow',
119 Principal: {
120 Service: 'appsync.amazonaws.com'
121 },
122 Action: 'sts:AssumeRole'
123 }
124 ]
125 },
126 Policies: [
127 new iam_1.default.Role.Policy({
128 PolicyName: 'RelationalDatabaseAccessPolicy',
129 PolicyDocument: {
130 Version: '2012-10-17',
131 Statement: [
132 {
133 Effect: 'Allow',
134 Action: [
135 'rds-data:ExecuteSql',
136 'rds-data:ExecuteStatement',
137 'rds-data:DeleteItems',
138 'rds-data:GetItems',
139 'rds-data:InsertItems',
140 'rds-data:UpdateItems'
141 ],
142 Resource: [
143 cloudform_1.Fn.Ref(ResourceConstants_1.ResourceConstants.PARAMETERS.rdsClusterIdentifier)
144 ]
145 },
146 {
147 Effect: 'Allow',
148 Action: [
149 'secretsmanager:GetSecretValue'
150 ],
151 Resource: [
152 cloudform_1.Fn.Ref(ResourceConstants_1.ResourceConstants.PARAMETERS.rdsSecretStoreArn)
153 ]
154 }
155 ]
156 }
157 })
158 ]
159 });
160 }
161 /**
162 * Creates the AppSync DataSource CFN Spec pointing at the provided RDS Cluster
163 *
164 * @param cliContext - the Amplify context, used to load environment variables.
165 * @returns the data source CloudFormation resource.
166 */
167 makeRelationalDataSource(cliContext) {
168 return new dataSource_1.default({
169 Type: 'RELATIONAL_DATABASE',
170 Name: `${this.context.databaseName}_rds_DataSource`,
171 Description: `RDS Data Source Provisioned for ${this.context.databaseName}`,
172 ApiId: cloudform_1.Fn.Ref(ResourceConstants_1.ResourceConstants.PARAMETERS.AppSyncApiId),
173 ServiceRoleArn: cloudform_1.Fn.GetAtt(ResourceConstants_1.ResourceConstants.RESOURCES.RelationalDatabaseAccessRole, 'Arn'),
174 RelationalDatabaseConfig: {
175 RelationalDatabaseSourceType: 'RDS_HTTP_ENDPOINT',
176 RdsHttpEndpointConfig: {
177 AwsRegion: cloudform_1.Fn.Ref(ResourceConstants_1.ResourceConstants.PARAMETERS.rdsRegion),
178 DbClusterIdentifier: cloudform_1.Fn.Ref(ResourceConstants_1.ResourceConstants.PARAMETERS.rdsClusterIdentifier),
179 DatabaseName: cloudform_1.Fn.Ref(ResourceConstants_1.ResourceConstants.PARAMETERS.rdsDatabaseName),
180 Schema: this.context.databaseSchema,
181 AwsSecretStoreArn: cloudform_1.Fn.Ref(ResourceConstants_1.ResourceConstants.PARAMETERS.rdsSecretStoreArn)
182 }
183 }
184 }).dependsOn([ResourceConstants_1.ResourceConstants.RESOURCES.RelationalDatabaseAccessRole]);
185 }
186}
187exports.default = RelationalDBTemplateGenerator;
188//# sourceMappingURL=RelationalDBTemplateGenerator.js.map
\No newline at end of file