async createVpnConnection()

in functions/source/faz-handler/lib/aws/index.js [1333:1530]


    async createVpnConnection(parameters) {
        let params, tgwAttachment, vpnConnection, vpnCreationTime, data;
        try {
            logger.info('calling createVpnConnection');
            params = {
                CustomerGatewayId: parameters.customerGatewayId,
                Type: parameters.type,
                Options: {
                    StaticRoutesOnly: false
                }
            };
            if (parameters.transitGatewayId) {
                params.TransitGatewayId = parameters.transitGatewayId;
            }
            data = await ec2.createVpnConnection(params).promise();
            if (data && data.VpnConnection) {
                vpnConnection = data.VpnConnection;
                // tag the vpnconnection
                params = {
                    Resources: [vpnConnection.VpnConnectionId],
                    Tags: [
                        {
                            Key: 'FortiGateAutoscaleTgwVpnAttachment',
                            Value: RESOURCE_TAG_PREFIX
                        },
                        {
                            Key: 'Name',
                            Value:
                                `${RESOURCE_TAG_PREFIX}-fortigate-autoscale-` +
                                `vpn-${parameters.publicIp}`
                        },
                        {
                            Key: 'ResourceGroup',
                            Value: RESOURCE_TAG_PREFIX
                        }
                    ]
                };
                logger.info('creating tags on the vpnconnection. tags: ', JSON.stringify(params));
                await ec2.createTags(params).promise();
                // if this vpn is created for a transit gateway, tag the tgw attachment
                // describe the tgw attachment
                // NOTE: it might not be accessible immediately after the vpn connection is created
                // wait for it

                if (parameters.transitGatewayId) {
                    let vpnConnectionId = vpnConnection.VpnConnectionId;
                    logger.info(
                        'describing transit gateway attachment' +
                            `(vpn connection: ${vpnConnectionId}).`
                    );
                    params = {
                        Filters: [
                            {
                                Name: 'resource-id',
                                Values: [vpnConnectionId]
                            },
                            {
                                Name: 'transit-gateway-id',
                                Values: [parameters.transitGatewayId]
                            }
                        ]
                    };
                    let promiseEmitter = () => {
                        return ec2
                            .describeTransitGatewayAttachments(params)
                            .promise()
                            .catch(error => {
                                logger.warn(
                                    'error in describeTransitGatewayAttachments ' +
                                        `>${JSON.stringify(
                                            error instanceof Error
                                                ? {
                                                      message: error.message,
                                                      stack: error.stack
                                                  }
                                                : error
                                        )}`
                                );
                            });
                    };
                    let validator = result => {
                        logger.debug(`TransitGatewayAttachments: ${JSON.stringify(result)}`);
                        if (
                            result &&
                            result.TransitGatewayAttachments &&
                            result.TransitGatewayAttachments.length > 0
                        ) {
                            // NOTE: by the time April 26, 2019. the AWS JavascriptSDK
                            // ec2.describeTransitGatewayAttachments cannot properly filter resource
                            // by resource-id. instead, it always return all resources so we must
                            // do the filtering in the function here.
                            // eslint-disable-next-line max-len
                            // ref link: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/EC2.html#describeTransitGatewayAttachments-property
                            let attachmentFound = null;
                            attachmentFound = result.TransitGatewayAttachments.find(attachment => {
                                return (
                                    attachment.ResourceId === vpnConnectionId &&
                                    attachment.TransitGatewayId === parameters.transitGatewayId
                                );
                            });
                            logger.debug(
                                `attachmentFound: ${JSON.stringify(attachmentFound)}, ` +
                                    `state: ${attachmentFound && attachmentFound.State}`
                            );
                            return attachmentFound;
                        }
                        return false;
                    };

                    try {
                        vpnCreationTime = Date.now();
                        data = await AutoScaleCore.Functions.waitFor(
                            promiseEmitter,
                            validator,
                            5000,
                            10
                        );
                        logger.info(
                            'transit gateway attachment created. time used: ' +
                                `${(Date.now() - vpnCreationTime) / 1000} seconds.`
                        );
                    } catch (error) {
                        data = null;
                        logger.error(
                            JSON.stringify(
                                error instanceof Error
                                    ? {
                                          message: error.message,
                                          stack: error.stack
                                      }
                                    : error
                            )
                        );
                        logger.error(
                            'failed to wait for the transit gateway attachment for vpn' +
                                `connetion (id: ${vpnConnectionId}) to become accessible.`
                        );
                    }
                    logger.info('transit gateway attachment info: ', JSON.stringify(data));
                    if (data) {
                        // NOTE: by the time April 26, 2019. the AWS JavascriptSDK
                        // ec2.describeTransitGatewayAttachments cannot properly filter resource
                        // by resource-id. instead, it always return all resources so we must
                        // do the filtering in the function here.
                        // eslint-disable-next-line max-len
                        // ref link: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/EC2.html#describeTransitGatewayAttachments-property
                        tgwAttachment = data.TransitGatewayAttachments.find(attachment => {
                            return (
                                attachment.ResourceId === vpnConnectionId &&
                                attachment.TransitGatewayId === parameters.transitGatewayId
                            );
                        });
                        if (tgwAttachment) {
                            params = {
                                Resources: [tgwAttachment.TransitGatewayAttachmentId],
                                Tags: [
                                    {
                                        Key: 'FortiGateAutoscaleTgwVpnAttachment',
                                        Value: RESOURCE_TAG_PREFIX
                                    },
                                    {
                                        Key: 'Name',
                                        Value:
                                            `${RESOURCE_TAG_PREFIX}-fortigate-autoscale-` +
                                            `tgw-attachment-vpn-${parameters.publicIp}`
                                    },
                                    {
                                        Key: 'ResourceGroup',
                                        Value: RESOURCE_TAG_PREFIX
                                    }
                                ]
                            };
                            logger.info(
                                'creating tags on attachment. tags: ',
                                JSON.stringify(params)
                            );
                            await ec2.createTags(params).promise();
                        }
                    }
                }
            }
            logger.info('called createVpnConnection');
            return {
                attachmentId: tgwAttachment && tgwAttachment.TransitGatewayAttachmentId,
                vpnConnection: vpnConnection
            };
        } catch (error) {
            logger.warn(
                `called createVpnConnection. failed.(error: ${JSON.stringify(
                    error instanceof Error ? { message: error.message, stack: error.stack } : error
                )})`
            );
            return {
                attachmentId: tgwAttachment && tgwAttachment.TransitGatewayAttachmentId,
                vpnConnection: vpnConnection
            };
        }
    }