Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
protocol = "HTTP";
targetProtocol = "HTTP";
useAppLoadBalancer = true;
break;
case "udp":
throw new RunError("UDP protocol unsupported for Services");
case "tcp":
protocol = "TCP";
targetProtocol = "TCP";
useAppLoadBalancer = false;
break;
default:
throw new RunError(`Unrecognized Service protocol: ${portMapping.protocol}`);
}
const loadBalancer = new aws.elasticloadbalancingv2.LoadBalancer(shortName, {
loadBalancerType: useAppLoadBalancer ? "application" : "network",
subnets: network.publicSubnetIds,
internal: internal,
// If this is an application LB, we need to associate it with the ECS cluster's security group, so
// that traffic on any ports can reach it. Otherwise, leave blank, and default to the VPC's group.
securityGroups: (useAppLoadBalancer && cluster.securityGroupId) ? [ cluster.securityGroupId ] : undefined,
tags: {
Name: longName,
},
}, {parent: parent});
// Create the target group for the new container/port pair.
const target = new aws.elasticloadbalancingv2.TargetGroup(shortName, {
port: portMapping.targetPort || portMapping.port,
protocol: targetProtocol,
vpcId: network.vpcId,
vpcId: defaultVpc.vpcId,
deregistrationDelay: 30, // seconds
healthCheck: {
interval: 10,
path: "/",
port: "traffic-port",
protocol: "HTTP",
matcher: "200-299",
timeout: 5,
healthyThreshold: 5,
unhealthyThreshold: 2,
},
});
let httpListener = new aws.elasticloadbalancingv2.ListenerRule("serviceHttpListener", {
listenerArn: loadBalancer.httpListener.arn,
priority: 100,
conditions: [{ field: "path-pattern", values: "/*" }],
actions: [{
type: "forward",
targetGroupArn: serverTargetGroup.arn,
}],
});
let wwwHttpsListenerRules = new aws.elasticloadbalancingv2.ListenerRule("wwwHTTPSRedirect", {
listenerArn: loadBalancer.httpsListener.arn,
priority: 100,
conditions: [{ field: "path-pattern", values: "/*" }],
actions: [{
type: "forward",
targetGroupArn: serverTargetGroup.arn,
}, {parent: parent});
// Create the target group for the new container/port pair.
const target = new aws.elasticloadbalancingv2.TargetGroup(shortName, {
port: portMapping.targetPort || portMapping.port,
protocol: targetProtocol,
vpcId: network.vpcId,
deregistrationDelay: 180, // 3 minutes
tags: {
Name: longName,
},
targetType: "ip",
}, { parent: parent });
// Listen on the requested port on the LB and forward to the target.
const listener = new aws.elasticloadbalancingv2.Listener(longName, {
loadBalancerArn: loadBalancer!.arn,
protocol: protocol,
certificateArn: useCertificateARN,
port: portMapping.port,
defaultActions: [{
type: "forward",
targetGroupArn: target.arn,
}],
// If SSL is used, we automatically insert the recommended ELB security policy from
// http://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html.
sslPolicy: useCertificateARN ? "ELBSecurityPolicy-2016-08" : undefined,
}, { parent: parent });
return {
loadBalancer: loadBalancer,
targetGroup: target,
this.cluster = cluster;
const parentOpts = { parent: this };
// Create the target group for the new container/port pair.
this.targetGroup = new aws.elasticloadbalancingv2.TargetGroup(shortName, {
port: args.loadBalancerPort.targetPort || args.loadBalancerPort.port,
protocol: targetProtocol,
vpcId: cluster.network.vpcId,
deregistrationDelay: 180, // 3 minutes
tags: { Name: longName },
targetType: "ip",
}, parentOpts);
// Listen on the requested port on the LB and forward to the target.
this.listener = new aws.elasticloadbalancingv2.Listener(longName, {
loadBalancerArn: this.arn,
protocol: listenerProtocol,
certificateArn: certificateArn,
port: args.loadBalancerPort.port,
defaultAction: {
type: "forward",
targetGroupArn: this.targetGroup.arn,
},
// If SSL is used, we automatically insert the recommended ELB security policy from
// http://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html.
sslPolicy: certificateArn ? "ELBSecurityPolicy-2016-08" : undefined,
}, parentOpts);
}
}
let serviceAccount = aws.elasticloadbalancing.getServiceAccount();
let policy = pulumi
.all([accessLogsBucket.id, serviceAccount, awsAccountId])
.apply(([accessLogsBucketId, serviceAccountResult, accountId]) => {
return accessLogsBucketPolicyString(accessLogsBucketId, serviceAccountResult.arn, logsPrefix, accountId);
});
let accessLogsBucketPolicy = new aws.s3.BucketPolicy(
"accessLogsBucketPolicy",
{
bucket: accessLogsBucket.id,
policy: policy,
});
export let alb = new aws.elasticloadbalancingv2.LoadBalancer(
"alb",
{
subnets: defaultVpc.subnetIds,
securityGroups: [ loadBalancerSecurityGroup.id ],
internal: false, // default false
idleTimeout: 120, // seconds
accessLogs: accessLogsBucket && {
enabled: true,
bucket: accessLogsBucket.id,
prefix: logsPrefix,
},
},
{
// We depend on the policy being created before we create the load balancer.
dependsOn: [ accessLogsBucketPolicy ],
},
constructor(name: string, listener: x.elasticloadbalancingv2.Listener,
args: ListenerRuleArgs, opts: pulumi.ComponentResourceOptions = {}) {
super("awsx:x:elasticloadbalancingv2", name, {}, { parent: listener, ...opts });
const parentOpts = { parent: this };
const actions = x.elasticloadbalancingv2.isListenerActions(args.actions)
? args.actions.actions()
: args.actions;
this.listenerRule = new aws.elasticloadbalancingv2.ListenerRule(name, {
...args,
actions,
listenerArn: listener.listener.arn,
}, parentOpts);
// If this is a rule hooking up this listener to a target group, then add our listener to
// the set of listeners the target group knows about. This is necessary so that anything
// that depends on the target group will end up depending on this rule getting created.
if (x.elasticloadbalancingv2.isListenerActions(args.actions)) {
args.actions.registerListener(listener);
}
this.registerOutputs();
}
}
loadBalancerType: useAppLoadBalancer ? "application" : "network",
subnets: cluster.network.publicSubnetIds,
internal: internal,
// If this is an application LB, we need to associate it with the ECS cluster's security
// group, so that traffic on any ports can reach it. Otherwise, leave blank, and
// default to the VPC's group.
securityGroups: useAppLoadBalancer ? [ cluster.instanceSecurityGroup.id ] : undefined,
tags: { Name: longName },
}, opts);
this.cluster = cluster;
const parentOpts = { parent: this };
// Create the target group for the new container/port pair.
this.targetGroup = new aws.elasticloadbalancingv2.TargetGroup(shortName, {
port: args.loadBalancerPort.targetPort || args.loadBalancerPort.port,
protocol: targetProtocol,
vpcId: cluster.network.vpcId,
deregistrationDelay: 180, // 3 minutes
tags: { Name: longName },
targetType: "ip",
}, parentOpts);
// Listen on the requested port on the LB and forward to the target.
this.listener = new aws.elasticloadbalancingv2.Listener(longName, {
loadBalancerArn: this.arn,
protocol: listenerProtocol,
certificateArn: certificateArn,
port: args.loadBalancerPort.port,
defaultAction: {
type: "forward",
},
);
const httpPort = 80;
const httpsPort = 443;
// The "empty target group" is the default target group used by our load balancer, and doesn't do
// anything other than act as a black hole for incomming traffic. We will create separate target
// groups for individual services based on routing rules.
let emptyHttpTargetGroup = new aws.elasticloadbalancingv2.TargetGroup("emptyTG", {
port: httpPort,
protocol: "HTTP",
vpcId: defaultVpc.vpcId,
});
export const httpListener = new aws.elasticloadbalancingv2.Listener("httpListener", {
loadBalancerArn: alb.arn,
port: httpPort,
protocol: "HTTP",
defaultActions: [{
targetGroupArn: emptyHttpTargetGroup.arn,
type: "forward",
}],
});
export const httpsListener = new aws.elasticloadbalancingv2.Listener("httpsListener", {
loadBalancerArn: alb.arn,
port: httpsPort,
protocol: "HTTPS",
certificateArn: config.httpsCertArn,
defaultActions: [{
targetGroupArn: emptyHttpTargetGroup.arn,
constructor(type: string, name: string,
defaultListenerAction: ListenerDefaultAction | undefined,
args: ListenerArgs, opts?: pulumi.ComponentResourceOptions) {
super(type, name, args, opts);
const parentOpts = { parent: this };
// If SSL is used, and no ssl policy was we automatically insert the recommended ELB
// security policy from:
// http://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html.
const defaultSslPolicy = pulumi.output(args.certificateArn)
.apply(a => a ? "ELBSecurityPolicy-2016-08" : undefined!);
this.listener = new aws.elasticloadbalancingv2.Listener(name, {
...args,
loadBalancerArn: args.loadBalancer.loadBalancer.arn,
sslPolicy: utils.ifUndefined(args.sslPolicy, defaultSslPolicy),
}, parentOpts);
const loadBalancer = args.loadBalancer.loadBalancer;
this.endpoint = this.listener.urn.apply(_ => pulumi.output({
hostname: loadBalancer.dnsName,
port: args.port,
}));
this.loadBalancer = args.loadBalancer;
this.defaultListenerAction = defaultListenerAction;
if (defaultListenerAction) {
// If our default rule hooked up this listener to a target group, then add our listener
if (bucketName !== undefined) {
if (lb.accessLogs === undefined || bucketName !== lb.accessLogs.bucket) {
reportViolation(`Load Balancer should have logging enabled with bucket '${bucketName}'.`);
}
}
};
return {
name: name,
description:
"All Application Load Balancers and the Classic Load Balancers should have " +
"logging enabled.",
enforcementLevel: "mandatory",
validateResource: [
validateTypedResource(aws.elasticloadbalancing.LoadBalancer, assertElbLogs),
validateTypedResource(aws.elasticloadbalancingv2.LoadBalancer, assertElbLogs),
],
};
}