1 回答
- 最新
- 投票最多
- 评论最多
1
You can use a Lambda-backed custom resource. During the Stack creation, the Lambda goes to the Parameter Store, gets a list of strings, parses it and returns back to the CloudFormation
Parameters:
ParameterPath:
Type: String
Default: /core/bmas-ip-address
Description: Parameter path containing comma-separated list of IP addresses
Resources:
CustomResolverRuleUpdaterFunction:
Type: AWS::Lambda::Function
Properties:
Code:
ZipFile: |
import json
import logging
import signal
import urllib3
import boto3
LOGGER = logging.getLogger()
LOGGER.setLevel(logging.INFO)
def handler(event, context):
try:
LOGGER.info('REQUEST RECEIVED:\n %s', event)
LOGGER.info('REQUEST RECEIVED:\n %s', context)
if event['RequestType'] == 'Create':
LOGGER.info('CREATE!')
ssm_parameter_path = event['ResourceProperties']['ParameterPath']
ssm_client = boto3.client('ssm')
response = ssm_client.get_parameter(Name=ssm_parameter_path, WithDecryption=True)
ip_list = response['Parameter']['Value'].split(',')
response_data = {
'TargetIps': [{'Ip': ip, 'Port': "53"} for ip in ip_list]
}
send_response(event, context, "SUCCESS", response_data)
elif event['RequestType'] == 'Update':
LOGGER.info('UPDATE!')
send_response(event, context, "SUCCESS",
{"Message": "Resource update successful!"})
elif event['RequestType'] == 'Delete':
LOGGER.info('DELETE!')
send_response(event, context, "SUCCESS",
{"Message": "Resource deletion successful!"})
else:
LOGGER.info('FAILED!')
send_response(event, context, "FAILED",
{"Message": "Unexpected event received from CloudFormation"})
except Exception as e:
LOGGER.info('FAILED!')
send_response(event, context, "FAILED", {"Message": "Exception during processing: {}".format(str(e))})
def send_response(event, context, response_status, response_data):
'''Send a resource manipulation status response to CloudFormation'''
response_body = json.dumps({
"Status": response_status,
"Reason": "See the details in CloudWatch Log Stream: " + context.log_stream_name,
"PhysicalResourceId": context.log_stream_name,
"StackId": event['StackId'],
"RequestId": event['RequestId'],
"LogicalResourceId": event['LogicalResourceId'],
"Data": response_data
})
LOGGER.info('ResponseURL: %s', event['ResponseURL'])
LOGGER.info('ResponseBody: %s', response_body)
http = urllib3.PoolManager()
response = http.request('PUT', event['ResponseURL'], body=response_body, headers={'Content-Type': ''})
LOGGER.info("Status code: %s", response.status)
LOGGER.info("Status message: %s", response.reason)
def timeout_handler(_signal, _frame):
'''Handle SIGALRM'''
raise Exception('Time exceeded')
signal.signal(signal.SIGALRM, timeout_handler)
Handler: index.handler
Role: !GetAtt CustomResolverRuleUpdaterRole.Arn
Runtime: python3.8
CustomResolverRuleUpdaterRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: CustomResolverRuleTargetIpPolicy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- ssm:GetParameter
Resource: "*"
- PolicyName: WriteLogs
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:*
Resource: arn:aws:logs:*:*:*
CustomResolverRuleUpdater:
Type: Custom::ResolverRuleUpdater
Properties:
ServiceToken: !GetAtt CustomResolverRuleUpdaterFunction.Arn
ParameterPath: !Ref ParameterPath
MyResolverRule:
Type: AWS::Route53Resolver::ResolverRule
Properties:
DomainName: demo1.com
RuleType: FORWARD
ResolverEndpointId: rslvr-out-ce*****4ca
TargetIps: !GetAtt CustomResolverRuleUpdater.TargetIps
Outputs:
ResolverRuleId:
Value: !GetAtt MyResolverRule.ResolverRuleId
相关内容
- AWS 官方已更新 1 年前