dem*_*ron 4 amazon-web-services aws-cloudformation elastic-load-balancer
我有一个CloudFormation模板,其中包含应用程序负载平衡器ListenerRule。ListenerRule的必需属性之一是其优先级(介于1到50000之间的数字)。每个ListenerRule的优先级必须唯一。
我需要多次部署相同的模板。每次我启动模板时,ListenerRule的优先级都应更改。
目前,我已经将Priority转换为启动堆栈时可以设置的参数,并且可以正常工作。有没有一种方法可以将ListenerRule的优先级自动设置为下一个可用优先级?
不,目前不可能仅使用AWS::ElasticLoadBalancingV2::ListenerRule
资源自动分配它。但是,可以使用自定义资源来实现。
首先,让我们创建实际的自定义资源Lambda代码。
allocate_alb_rule_priority.py:
import json
import os
import random
import uuid
import boto3
from botocore.vendored import requests
SUCCESS = "SUCCESS"
FAILED = "FAILED"
# Member must have value less than or equal to 50000
ALB_RULE_PRIORITY_RANGE = 1, 50000
def lambda_handler(event, context):
try:
_lambda_handler(event, context)
except Exception as e:
# Must raise, otherwise the Lambda will be marked as successful, and the exception
# will not be logged to CloudWatch logs.
# Always send a response otherwise custom resource creation/update/deletion will be stuck
send(
event,
context,
response_status=FAILED if event['RequestType'] != 'Delete' else SUCCESS,
# Do not fail on delete to avoid rollback failure
response_data=None,
physical_resource_id=uuid.uuid4(),
reason=e,
)
raise
def _lambda_handler(event, context):
print("Received event: " + json.dumps(event, indent=2))
physical_resource_id = event.get('PhysicalResourceId', str(uuid.uuid4()))
response_data = {}
if event['RequestType'] == 'Create':
elbv2_client = boto3.client('elbv2')
result = elbv2_client.describe_rules(ListenerArn=os.environ['ListenerArn'])
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
}
send(event, context, SUCCESS, response_data, physical_resource_id)
def send(event, context, response_status, response_data, physical_resource_id, reason=None):
response_url = event['ResponseURL']
response_body = {
'Status': response_status,
'Reason': str(reason) if reason else 'See the details in CloudWatch Log Stream: ' + context.log_stream_name,
'PhysicalResourceId': physical_resource_id,
'StackId': event['StackId'],
'RequestId': event['RequestId'],
'LogicalResourceId': event['LogicalResourceId'],
'Data': response_data,
}
json_response_body = json.dumps(response_body)
headers = {
'content-type': '',
'content-length': str(len(json_response_body))
}
try:
requests.put(
response_url,
data=json_response_body,
headers=headers
)
except Exception as e:
print("send(..) failed executing requests.put(..): " + str(e))
Run Code Online (Sandbox Code Playgroud)
根据您的问题,您需要使用同一模板创建多个堆栈。因此,我建议将自定义资源放置在仅部署一次的模板中。然后让其他模板导入其ServiceToken
。
allocate_alb_rule_priority_custom_resouce.yml
:
Resources:
AllocateAlbRulePriorityCustomResourceLambdaRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: ''
Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
Path: /
Policies:
- PolicyName: DescribeRulesPolicy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- elasticloadbalancing:DescribeRules
Resource: "*"
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
AllocateAlbRulePriorityCustomResourceLambdaFunction:
Type: AWS::Lambda::Function
Properties:
Handler: allocate_alb_rule_priority.lambda_handler
Role: !GetAtt AllocateAlbRulePriorityCustomResourceLambdaRole.Arn
Code: allocate_alb_rule_priority.py
Runtime: python3.6
Timeout: '30'
Environment:
Variables:
ListenerArn: !Ref LoadBalancerListener
Outputs:
AllocateAlbRulePriorityCustomResourceLambdaArn:
Value: !GetAtt AllocateAlbRulePriorityCustomResourceLambdaFunction.Arn
Export:
Name: AllocateAlbRulePriorityCustomResourceLambdaArn
Run Code Online (Sandbox Code Playgroud)
您会注意到,我们正在将ListenerArn传递给Lambda函数。这是因为我们要避免新分配中优先级编号冲突。
最后,我们现在可以在模板中使用我们的新自定义资源,该资源将被多次部署。
template_meant_to_be_deployed_multiple_times.yml
:
AllocateAlbRulePriorityCustomResource:
Type: Custom::AllocateAlbRulePriority
Condition: AutoAllocateAlbPriority
Properties:
ServiceToken:
Fn::ImportValue: AllocateAlbRulePriorityCustomResourceLambdaArn
ListenerRule:
Type: AWS::ElasticLoadBalancingV2::ListenerRule
Properties:
Priority: !GetAtt AllocateAlbRulePriorityCustomResource.Priority
[...]
Run Code Online (Sandbox Code Playgroud)
这些是片段,尽管它们是从工作代码中摘录的,但它们可能无法按原样工作。我希望它能使您大致了解如何实现它。让我知道您是否需要更多帮助。
归档时间: |
|
查看次数: |
2260 次 |
最近记录: |