UNPKG

aws-spa

Version:

A no-brainer script to deploy a single page app on AWS

216 lines (167 loc) 6.47 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.updateRecord = exports.needsUpdateRecord = exports.findHostedZone = exports.createHostedZone = exports.createCertificateValidationDNSRecord = void 0; var _inquirer = _interopRequireDefault(require("inquirer")); var _awsHelper = require("./aws-helper"); var _awsServices = require("./aws-services"); var _logger = require("./logger"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const findHostedZone = async domainName => { _logger.logger.info(`[route53] 🔍 Looking for a hosted zone matching "${domainName}"...`); const hostedZones = await (0, _awsHelper.getAll)(async (nextMarker, page) => { _logger.logger.info(`[route53] 🔍 List hosted zones (page ${page})...`); const { HostedZones, NextMarker } = await _awsServices.route53.listHostedZones({ Marker: nextMarker }); if (!HostedZones) { _logger.logger.info(`[route53] 🧐 No hosted zones found`); return { items: [], nextMarker: undefined }; } return { items: HostedZones, nextMarker: NextMarker }; }); const matchingHostedZones = hostedZones.filter(hostedZone => domainName.endsWith(hostedZone.Name.replace(/\.$/g, ''))); if (matchingHostedZones.length === 1) { _logger.logger.info(`[route53] 👍 Found Hosted zone: "${matchingHostedZones[0].Name}"`); return matchingHostedZones[0]; } if (matchingHostedZones.length > 1) { _logger.logger.warn(`[route53] ⚠️ Found multiple hosted zones: ${matchingHostedZones.map(hostedZone => `"${hostedZone.Name}"`).join(', ')}. There first hosted zone will be used. If this is an issue, please open an issue on https://github.com/lalalilo/aws-spa/issues`); return matchingHostedZones[0]; } _logger.logger.info(`[route53] 🧐 No matching hosted zones found`); return null; }; exports.findHostedZone = findHostedZone; const createHostedZone = async domainName => { _logger.logger.info(`[route53] ✏️ Creating hosted zone "${domainName}"...`); const { HostedZone } = await _awsServices.route53.createHostedZone({ Name: domainName, CallerReference: `aws-spa-${Date.now()}` }); if (!HostedZone) { throw new Error(`[route53] ❌ Failed to create hosted zone "${domainName}"`); } return HostedZone; }; exports.createHostedZone = createHostedZone; const needsUpdateRecord = async (hostedZoneId, domainName, cloudfrontDomainName) => { if (!hostedZoneId) { _logger.logger.warn(`[route53] 🧐 hostedZoneId is undefined`); return false; } _logger.logger.info(`[route53] 🔍 Looking for a matching record...`); const { ResourceRecordSets } = await _awsServices.route53.listResourceRecordSets({ HostedZoneId: hostedZoneId, StartRecordName: domainName }); if (!ResourceRecordSets || ResourceRecordSets.length === 0) { _logger.logger.info(`[route53] 🔍 No matching record found.`); return true; } for (const record of ResourceRecordSets) { if (record.Name !== `${domainName}.`) { continue; } if (record.Type === 'CNAME' && record.ResourceRecords) { if (record.ResourceRecords[0].Value === `${cloudfrontDomainName}.`) { _logger.logger.info(`[route53] 👍 Found well configured CNAME matching record`); return false; } const { continueUpdate } = await _inquirer.default.prompt([{ type: 'confirm', name: 'continueUpdate', message: `[Route53] CNAME Record for "${domainName}" value is "${record.ResourceRecords[0].Value}". Would you like to update it to "${cloudfrontDomainName}."?`, default: false }]); if (continueUpdate) { return true; } else { _logger.logger.warn('⚠️ website might not be served correctly unless you allow route53 record update'); return false; } } if (record.Type === 'A' && record.AliasTarget) { if (record.AliasTarget.HostedZoneId === 'Z2FDTNDATAQYW2' && record.AliasTarget.DNSName === `${cloudfrontDomainName}.`) { _logger.logger.info(`[route53] 👍 Found well configured A matching record`); return false; } const { continueUpdate } = await _inquirer.default.prompt([{ type: 'confirm', name: 'continueUpdate', message: `[Route53] A Record for "${domainName}" value is "${record.AliasTarget.HostedZoneId}:${record.AliasTarget.DNSName}". Would you like to update it to "${record.AliasTarget.HostedZoneId}:${cloudfrontDomainName}."?`, default: false }]); if (continueUpdate) { return true; } else { _logger.logger.warn('⚠️ website might not be served correctly unless you allow route53 record update'); return false; } } } }; exports.needsUpdateRecord = needsUpdateRecord; const updateRecord = async (hostedZoneId, domainName, cloudfrontDomainName) => { if (!hostedZoneId) { throw new Error(`[route53] ❌ hostedZoneId is undefined`); } _logger.logger.info(`[route53] ✏️ Upserting A: "${domainName}." → ${cloudfrontDomainName}...`); await _awsServices.route53.changeResourceRecordSets({ HostedZoneId: hostedZoneId, ChangeBatch: { Changes: [{ Action: 'UPSERT', ResourceRecordSet: { Name: `${domainName}.`, AliasTarget: { HostedZoneId: 'Z2FDTNDATAQYW2', // https://docs.aws.amazon.com/general/latest/gr/rande.html#cf_region DNSName: `${cloudfrontDomainName}.`, EvaluateTargetHealth: false }, Type: 'A' } }] } }); }; exports.updateRecord = updateRecord; const createCertificateValidationDNSRecord = async (record, hostedZoneId) => { _logger.logger.info(`[Route53] Creating record ${record.Type}:${record.Name}=${record.Value} to validate SSL certificate`); await _awsServices.route53.changeResourceRecordSets({ HostedZoneId: hostedZoneId, ChangeBatch: { Changes: [{ Action: 'UPSERT', ResourceRecordSet: { Name: record.Name, Type: record.Type, ResourceRecords: [{ Value: record.Value }], TTL: 3600 } }] } }); }; exports.createCertificateValidationDNSRecord = createCertificateValidationDNSRecord;