async generateCloudFormationTemplate()

in source/services/tasks/tasks.ts [1020:1110]


    async generateCloudFormationTemplate(task: object): Promise<string | ErrorReturn> {
        let actionName = task['actionName'];

        try {
            // Gets CloudFormation template from S3
            LOGGER.info('Getting CloudFormation template from S3...');
            const getParams: AWS.S3.GetObjectAclRequest = {
                Bucket: this.cloudFormationBucket,
                Key: `${actionName}/cloudformation.template`
            };
            let data = await this.s3.getObject(getParams).promise();
            let yaml = data.Body.toString().replace('%%TASK_ID%%', task['taskId']);

            // Adds event related resources to the CloudFormation template
            if (task['triggerType'] === TriggerType.Event) {
                // Removes event pattern to prevent JSON parsing problem to make CloudWatch Events event rule
                let eventPattern = task['eventPattern'];
                delete task['eventPattern'];

                task['resources'] = '<resources>';
                let eventTemplate = fs.readFileSync('tasks/event-handler.template').toString()
                    .replace(/%%TASK_ID%%/g, task['taskId'])
                    .replace('%%TASK_DESCRIPTION%%', task['description'])
                    .replace('%%EVENT_PATTERN%%', eventPattern.replace(/\n/g, ''))
                    .replace('%%TASK%%', JSON.stringify(task)
                        .replace(/\\n/g, '')
                        .replace(/\\/g, '')
                        .replace(/"/g, '\\"'))
                    .replace(/%%MASTER_SNS_ARN%%/g, this.masterSnsArn)
                    .replace('%%MASTER_KMS_ARN%%', this.masterKmsArn)
                    .replace('%%MASTER_REGION%%', this.region);
                yaml = yaml.concat(eventTemplate);
                delete task['resources'];

                // Adds event pattern again to the task
                task['eventPattern'] = eventPattern;

                await this.editSnsPolicy(task['taskId'], task['accounts']);
                await this.editKmsPolicy(task['taskId'], task['accounts']);
            }

            LOGGER.info('Putting CloudFormation template from S3...');
            // Uploads the CloudFormation template to S3
            let putParams: AWS.S3.PutObjectRequest = {
                Bucket: this.cloudFormationBucket,
                Body: yaml,
                Key: `${actionName}/${task['taskId']}.template`,
                ContentType: 'binary/octet-stream'
            };
            await this.s3.putObject(putParams).promise();

            LOGGER.info('Modifying S3 bucket policy...');
            // Gets bucket policy
            let bucketPolicy = await this.s3.getBucketPolicy({ Bucket: this.cloudFormationBucket }).promise();
            let policy = JSON.parse(bucketPolicy.Policy);

            // Deletes bucket policy
            await this.s3.deleteBucketPolicy({ Bucket: this.cloudFormationBucket }).promise();

            // Puts new bucket policy
            let statement = (policy['Statement'] as object[]).filter((statement) => statement['Sid'] !== task['taskId']);
            statement.push({
                Sid: task['taskId'],
                Effect: 'Allow',
                Principal: {
                    AWS: [
                        ...
                        (task['accounts'] as string[]).map((account) => {
                            return `arn:aws:iam::${account}:root`
                        })
                    ]
                },
                Action: 's3:GetObject',
                Resource: `arn:aws:s3:::${this.cloudFormationBucket}/*`
            });
            policy['Statement'] = statement;
            await this.s3.putBucketPolicy({
                Bucket: this.cloudFormationBucket,
                Policy: JSON.stringify(policy)
            }).promise();

            return Promise.resolve(
                `https://${this.cloudFormationBucket}.s3.${this.region}.amazonaws.com/${actionName}/${task['taskId']}.template`
            );
        } catch (error) {
            LOGGER.error(`generateCloudFormationTemplate Error: ${JSON.stringify(error)}`);
            return Promise.reject(
                COMMON_UTIL.getErrorObject('GenerateCloudFormationTemplateFailure', 500, 'Error occurred while generating CloudFormation template.', error)
            );
        }
    }