@pulumi/awsx
Version:
[](https://github.com/pulumi/pulumi-awsx/actions) [](https://slack.pulumi.com) [;
// 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