UNPKG

@pulumi/awsx

Version:

[![Actions Status](https://github.com/pulumi/pulumi-awsx/workflows/master/badge.svg)](https://github.com/pulumi/pulumi-awsx/actions) [![Slack](http://www.pulumi.com/images/docs/badges/slack.svg)](https://slack.pulumi.com) [![NPM version](https://badge.fur

281 lines • 12.4 kB
"use strict"; // Copyright 2016-2018, Pulumi Corporation. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.ApplicationListener = exports.ApplicationTargetGroup = exports.ApplicationLoadBalancer = void 0; const pulumi = __importStar(require("@pulumi/pulumi")); const ec2 = __importStar(require("../ec2")); const listener_1 = require("./listener"); const loadBalancer_1 = require("./loadBalancer"); const targetGroup_1 = require("./targetGroup"); const utils = __importStar(require("../utils")); /** * A application load balancer serves as the single point of contact for clients. The load balancer * distributes incoming application traffic across multiple targets, such as EC2 instances, in * multiple Availability Zones. This increases the availability of your application. You add one or * more listeners to your load balancer. * * See https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html for * more details. */ class ApplicationLoadBalancer extends loadBalancer_1.LoadBalancer { listeners; targetGroups; constructor(name, args = {}, opts = {}) { const argsCopy = { vpc: args.vpc || ec2.Vpc.getDefault(opts), ...args, loadBalancerType: "application", }; if (!argsCopy.securityGroups) { argsCopy.securityGroups = [new ec2.SecurityGroup(name, { description: `Default security group for ALB: ${name}`, vpc: argsCopy.vpc, }, opts)]; } super("aws:lb:ApplicationLoadBalancer", name, argsCopy, pulumi.mergeOptions(opts, { aliases: [{ type: "awsx:x:elasticloadbalancingv2:ApplicationLoadBalancer" }] })); this.listeners = []; this.targetGroups = []; this.registerOutputs(); } /** * Creates a new listener for this [ApplicationLoadBalancer] see ApplicationListener for more * details. */ createListener(name, args, opts = {}) { return new ApplicationListener(name, { loadBalancer: this, ...args, }, { parent: this, ...opts }); } /** * Creates a target group for this [ApplicationLoadBalancer] see ApplicationTargetGroup for more * details. */ createTargetGroup(name, args, opts = {}) { return new ApplicationTargetGroup(name, { loadBalancer: this, ...args, }, { parent: this, ...opts }); } } exports.ApplicationLoadBalancer = ApplicationLoadBalancer; /** * Each target group routes requests to one or more registered targets, such as EC2 instances, using * the protocol and port number that you specify. You can register a target with multiple target * groups. You can configure health checks on a per target group basis. Health checks are performed * on all targets registered to a target group that is specified in a listener rule for your load * balancer. */ class ApplicationTargetGroup extends targetGroup_1.TargetGroup { loadBalancer; listeners; /** @internal */ // tslint:disable-next-line:variable-name __isApplicationTargetGroup; constructor(name, args = {}, opts = {}) { const loadBalancer = args.loadBalancer || new ApplicationLoadBalancer(name, { vpc: args.vpc, name: args.name, }, opts); const { port, protocol } = args.targetGroup ? { port: undefined, protocol: undefined } : computePortInfo(args.port, args.protocol); opts = pulumi.mergeOptions(opts, { aliases: [{ type: "awsx:x:elasticloadbalancingv2:ApplicationTargetGroup" }] }); super("awsx:lb:ApplicationTargetGroup", name, loadBalancer, { ...args, vpc: loadBalancer.vpc, port, protocol, }, opts); this.__isApplicationTargetGroup = true; this.listeners = []; this.loadBalancer = loadBalancer; loadBalancer.targetGroups.push(this); this.registerOutputs(); } createListener(name, args, opts = {}) { // We didn't use to parent the listener to the target group. Now we do. Create an alias // from the old parent to the current one if this moves over. return new ApplicationListener(name, { defaultAction: this, loadBalancer: this.loadBalancer, ...args, }, { parent: this, ...pulumi.mergeOptions(opts, { aliases: [{ parent: opts.parent }] }), }); } static isInstance(obj) { return utils.isInstance(obj, "__isApplicationTargetGroup"); } } exports.ApplicationTargetGroup = ApplicationTargetGroup; function computePortInfo(port, protocol) { if (port === undefined && protocol === undefined) { throw new Error("At least one of [port] or [protocol] must be provided."); } const computedPort = pulumi.all([port, protocol]).apply(([port, protocol]) => { if (port !== undefined) { return port; } switch (protocol) { case "HTTP": return 80; case "HTTPS": return 443; default: throw new Error(`Could not automatically determine port for protocol ${JSON.stringify(protocol)}. Please provide an explicit port.`); } }); protocol = pulumi.all([port, protocol]).apply(([port, protocol]) => { if (protocol !== undefined) { return protocol; } switch (port) { case 80: case 8000: case 8008: case 8080: return "HTTP"; case 443: case 8443: return "HTTPS"; default: throw new Error(`Could not automatically determine protocol for port ${JSON.stringify(port)}. Please specify either "HTTP" or "HTTPS"`); } }); return { port: computedPort, protocol }; } class ApplicationListener extends listener_1.Listener { loadBalancer; // tslint:disable-next-line:variable-name __isApplicationListenerInstance; constructor(name, args, opts = {}) { const argCount = (args.defaultAction ? 1 : 0) + (args.defaultActions ? 1 : 0) + (args.targetGroup ? 1 : 0); if (argCount >= 2) { throw new Error("Only provide one of [defaultAction], [defaultActions] or [targetGroup]."); } const loadBalancer = pulumi.Resource.isInstance(args.loadBalancer) ? args.loadBalancer : new ApplicationLoadBalancer(name, { ...args.loadBalancer, vpc: args.vpc, name: args.name, }, opts); const { port, protocol } = computePortInfo(args.port || args.listener?.port, args.protocol || args.listener?.protocol); const { defaultActions, defaultListener } = getDefaultActions(name, loadBalancer, args, port, protocol, opts); // Pass along the target as the defaultTarget for this listener. This allows this listener // to defer to it for ContainerPortMappings information. this allows this listener to be // passed in as the portMappings information needed for a Service. opts = pulumi.mergeOptions(opts, { aliases: [{ type: "awsx:x:elasticloadbalancingv2:ApplicationListener" }] }); super("awsx:lb:ApplicationListener", name, defaultListener, { ...args, defaultActions, loadBalancer, port, protocol, }, opts); this.__isApplicationListenerInstance = true; this.loadBalancer = loadBalancer; loadBalancer.listeners.push(this); // As per https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-update-security-groups.html // // Whenever you add a listener to your load balancer or update the health check port for a // target group used by the load balancer to route requests, you must verify that the // security groups associated with the load balancer allow traffic on the new port in both // directions. if (!args.listener && args.external !== false) { const args = { location: new ec2.AnyIPv4Location(), ports: new ec2.TcpPorts(port), description: pulumi.interpolate `Externally available at port ${port}`, }; for (let i = 0, n = this.loadBalancer.securityGroups.length; i < n; i++) { const securityGroup = this.loadBalancer.securityGroups[i]; securityGroup.createIngressRule(`${name}-external-${i}-ingress`, args, { parent: this }); securityGroup.createEgressRule(`${name}-external-${i}-egress`, args, { parent: this }); } } this.registerOutputs(); } /** @internal */ static isApplicationListenerInstance(obj) { return obj && !!obj.__isApplicationListenerInstance; } } exports.ApplicationListener = ApplicationListener; function getDefaultActions(name, loadBalancer, args, port, protocol, opts) { if (args.defaultActions) { return { defaultActions: args.defaultActions, defaultListener: undefined }; } if (args.defaultAction) { return (0, listener_1.isListenerDefaultAction)(args.defaultAction) ? { defaultActions: [args.defaultAction.listenerDefaultAction()], defaultListener: args.defaultAction } : { defaultActions: [args.defaultAction], defaultListener: undefined }; } // User didn't provide default actions for this listener. Create a reasonable target group for // us and use that as our default action. const targetGroup = createTargetGroup(); return { defaultActions: [targetGroup.listenerDefaultAction()], defaultListener: targetGroup }; function createTargetGroup() { // Use the target group if provided by the client. Otherwise, create a reasonable default // one for our LB that will connect to this listener's port using our app protocol. if (pulumi.Resource.isInstance(args.targetGroup)) { return args.targetGroup; } else if (args.targetGroup) { return new ApplicationTargetGroup(name, { ...args.targetGroup, loadBalancer, }, opts); } else { return new ApplicationTargetGroup(name, { port, protocol, loadBalancer, name: args.name, }, opts); } } } //# sourceMappingURL=application.js.map