Created
November 14, 2020 21:30
-
-
Save AlJohri/fa18bf58b338888934a140c8b6214fdd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Source: https://stackoverflow.com/questions/50003378/automatically-set-listenerrule-priority-in-cloudformation-template | |
import random | |
import uuid | |
import traceback | |
import boto3 | |
# Member must have value less than or equal to 50000 | |
ALB_RULE_PRIORITY_RANGE = 1, 50000 | |
def handler(event, context): | |
physical_resource_id = event.get("PhysicalResourceId", str(uuid.uuid4())) | |
response_data = {} | |
listener_arn = event["ResourceProperties"]["ListenerArn"] | |
if event["RequestType"] == "Create": | |
elbv2_client = boto3.client("elbv2") | |
result = elbv2_client.describe_rules(ListenerArn=listener_arn) | |
in_use = list( | |
filter(lambda s: s.isdecimal(), [r["Priority"] for r in result["Rules"]]) | |
) | |
priority = None | |
while not priority or priority in in_use: | |
priority = str(random.randint(*ALB_RULE_PRIORITY_RANGE)) | |
response_data = {"Priority": priority} | |
return {"PhysicalResourceId": physical_resource_id, "Data": response_data} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const loadBalancerName = `${titleCase(stage)}PublicLoadBalancer` | |
const loadBalancer = elbv2.ApplicationLoadBalancer.fromLookup( | |
this, | |
`LoadBalancer`, | |
{ | |
loadBalancerTags: { Name: loadBalancerName }, | |
} | |
) | |
const listener = elbv2.ApplicationListener.fromLookup(this, `Listener`, { | |
loadBalancerTags: { Name: loadBalancerName }, | |
listenerProtocol: elbv2.ApplicationProtocol.HTTPS, | |
}) | |
const hostedZone = route53.HostedZone.fromLookup(this, `HostedZone`, { | |
domainName: "blahblahblah.io", | |
}) | |
let subdomain = `${client}-snowplow-collector` | |
if (stage === STAGE.DEVELOPMENT) subdomain = `${stage}-${subdomain}` | |
const recordName = `${subdomain}.blahblahblah.io` | |
new route53.ARecord(this, `AliasRecord`, { | |
zone: hostedZone, | |
recordName, | |
target: route53.RecordTarget.fromAlias( | |
new alias.LoadBalancerTarget(loadBalancer) | |
), | |
}) | |
const targetGroup = new elbv2.ApplicationTargetGroup(scope, `TargetGroup`, { | |
port: 80, | |
healthCheck: { | |
port: "traffic-port", | |
path: "/health", | |
}, | |
targets: [service], | |
vpc: vpc, | |
}) | |
const nextListenerRulePriorityLambda = new CustomResource( | |
this, | |
"nextListenerRulePriority", | |
{ | |
resourceType: "Custom::AllocateAlbRulePriority", | |
serviceToken: Fn.importValue("AllocateAlbRulePriority-serviceToken"), | |
properties: { | |
ListenerArn: listener.listenerArn, | |
}, | |
} | |
) | |
const nextListenerRulePriority = nextListenerRulePriorityLambda.getAttString( | |
"Priority" | |
) | |
const listenerRule = new elbv2.ApplicationListenerRule( | |
this, | |
"ListenerRule", | |
{ | |
action: elbv2.ListenerAction.forward([targetGroup]), | |
conditions: [elbv2.ListenerCondition.hostHeaders([recordName])], | |
listener, | |
priority: 9999, | |
} | |
) | |
// Source: https://github.com/aws/aws-cdk/issues/9296#issuecomment-723294027 | |
const albRuleEscapeHatch = listenerRule.node | |
.defaultChild as elbv2.CfnListenerRule | |
albRuleEscapeHatch.priority = Token.asNumber(nextListenerRulePriority) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as cdk from "@aws-cdk/core" | |
import * as logs from "@aws-cdk/aws-logs" | |
import * as path from "path" | |
import * as iam from "@aws-cdk/aws-iam" | |
import * as lambda from "@aws-cdk/aws-lambda" | |
import * as cr from "@aws-cdk/custom-resources" | |
import { CfnOutput } from "@aws-cdk/core" | |
/** | |
* Central lambdas used throughout the team. | |
*/ | |
export default function createLambdas(scope: cdk.Stack) { | |
const fn = new lambda.Function(scope, "AllocateAlbRulePriority", { | |
runtime: lambda.Runtime.PYTHON_3_6, | |
handler: "allocate_alb_rule_priority.handler", | |
timeout: cdk.Duration.seconds(30), | |
code: lambda.Code.fromAsset( | |
path.join(__dirname, "..", "..", "lambdas", "allocate-alb-rule-priority") | |
), | |
initialPolicy: [ | |
new iam.PolicyStatement({ | |
sid: "DescribeRulesPolicy", | |
actions: ["elasticloadbalancing:DescribeRules"], | |
resources: ["*"], | |
}), | |
], | |
}) | |
const provider = new cr.Provider(scope, "AllocateAlbRulePriorityProvider", { | |
onEventHandler: fn, | |
logRetention: logs.RetentionDays.ONE_DAY, | |
}) | |
new cdk.CfnOutput(scope, "AllocateAlbRulePriorityServiceToken", { | |
value: provider.serviceToken, | |
exportName: "AllocateAlbRulePriority-serviceToken", | |
}) | |
} |
glad I could help @Lasim!
Could you please share some instructions on how exactly to use this code ? Thanks.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You saved me hours of my life.
Thank you!