Last active
September 12, 2019 14:41
-
-
Save tomislacker/a5e623e854108938edcdda4c29c4a13a to your computer and use it in GitHub Desktop.
CloudFormation - Search & Replace Custom Resource
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
--- | |
AWSTemplateFormatVersion: 2010-09-09 | |
Description: Testing something | |
Resources: | |
R1: | |
Type: Custom::StringReplacement | |
Properties: | |
ServiceToken: !ImportValue cfn-helpers:Replace | |
Find: '-test' | |
Replace: '-prod' | |
Subject: example-stack-name-test | |
R2: | |
Type: Custom::StringReplacement | |
Properties: | |
ServiceToken: !ImportValue cfn-helpers:Replace | |
Find: '-[^-]+$' | |
Limit: 1 | |
Regex: True | |
Replace: '-prod' | |
Subject: example-stack-name-test | |
Outputs: | |
R1: | |
# Results in 'example-stack-name-prod' | |
Value: !GetAtt R1.Result | |
R2: | |
# Results in 'example-stack-name-prod' | |
Value: !GetAtt R2.Result | |
# vim: ft=yaml.cloudformation sw=2 ts=2 |
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
--- | |
AWSTemplateFormatVersion: 2010-09-09 | |
Description: | | |
Provides a Lambda-backed Custom Resource for doing string replacement. | |
Resource Parameters: | |
Find (required, string): String or regular expression to find | |
Insensitive (optional, boolean): Switch to indicate case sensitivity. | |
Defaults to False & requires Regex=True | |
Limit (optional, integer): Maximum number of matches to replace | |
Regex (optional, boolean): If the `Find` parameter is a regular | |
expression. Defaults to False | |
Replace (required, string): Replacement string | |
Subject (required, string): String to do replacement in | |
Return Parameters: | |
Result (string): Result of the string replacement | |
Resources: | |
ReplaceFunctionLogGroup: | |
Type: AWS::Logs::LogGroup | |
Properties: | |
LogGroupName: !Sub /aws/lambda/${ReplaceFunction} | |
RetentionInDays: 1 | |
ReplaceFunctionRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Version: 2012-10-17 | |
Statement: | |
- Effect: Allow | |
Principal: {Service: lambda.amazonaws.com} | |
Action: sts:AssumeRole | |
Path: /cfn-custom-resources/ | |
Policies: | |
- PolicyName: logs | |
PolicyDocument: | |
Statement: | |
- Effect: Allow | |
Action: | |
- logs:CreateLogStream | |
- logs:PutLogEvents | |
Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:*" | |
ReplaceFunction: | |
Type: AWS::Lambda::Function | |
Properties: | |
Description: Executes string replacement | |
Handler: index.lambda_handler | |
MemorySize: 128 | |
Role: !GetAtt ReplaceFunctionRole.Arn | |
Runtime: python3.6 | |
Timeout: 5 | |
Code: | |
ZipFile: | | |
import cfnresponse | |
def lambda_handler(event, context): | |
# Define the signal & data that will be returned | |
return_status = cfnresponse.FAILED | |
return_data = {} | |
try: | |
# Fetch the invocation settings | |
props = event['ResourceProperties'] | |
find = props['Find'] | |
insensitive = props.get('Insensitive', '').lower() == 'true' | |
limit = int(props.get('Limit', 0)) | |
regex = props.get('Regex', '').lower() == 'true' | |
replace = props['Replace'] | |
subject = props['Subject'] | |
# Sanity check | |
if insensitive and not regex: | |
raise NotImplementedError( | |
'Cannot do case-insensitive replacement without' | |
'setting Regex=True') | |
if regex: | |
# Regular expression replacement | |
import re | |
kwargs = {} | |
if limit: | |
kwargs.update({'count': limit}) | |
if insensitive: | |
kwargs.update({'flags': re.I}) | |
result = re.sub(find, replace, subject, **kwargs) | |
else: | |
# Simple string replacement | |
result = subject.replace(find, replace) | |
# Setup return data & signal | |
return_data.update({ | |
'Result': result, | |
}) | |
return_status = cfnresponse.SUCCESS | |
except Exception as e: | |
# Some error | |
import traceback | |
traceback.print_exc() | |
return_data.update({ | |
'Exception': str(e), | |
}) | |
# Send the CFN response | |
cfnresponse.send( | |
event, | |
context, | |
return_status, | |
return_data) | |
Outputs: | |
ReplaceFunctionArn: | |
Description: ARN of the replacement Lambda function | |
Value: !GetAtt ReplaceFunction.Arn | |
Export: | |
Name: cfn-helpers:Replace | |
# vim: ft=yaml.cloudformation sw=2 ts=2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment