See the code below:
Mappings:
RegionMap:
us-east-1:
bucketname: s3bucketname-us-east-1
us-east-2:
bucketname: s3bucketname-us-east-2
us-west-1:
bucketname: s3bucketname-us-west-1
us-west-2:
bucketname: s3bucketname-us-west-2
ap-south-1:
bucketname: s3bucketname-ap-south-1
ap-northeast-2:
bucketname: s3bucketname-ap-northeast-2
ap-southeast-1:
bucketname: s3bucketname-ap-southeast-1
ap-southeast-2:
bucketname: s3bucketname-ap-southeast-2
ap-northeast-1:
bucketname: s3bucketname-ap-northeast-1
ca-central-1:
bucketname: s3bucketname-ca-central-1
eu-central-1:
bucketname: s3bucketname-eu-central-1
eu-west-1:
bucketname: s3bucketname-eu-west-1
eu-west-2:
bucketname: s3bucketname-eu-west-2
eu-west-3:
bucketname: s3bucketname-eu-west-3
eu-north-1:
bucketname: s3bucketname-eu-north-1
sa-east-1:
bucketname: s3bucketname-east-1
af-south-1:
bucketname: s3bucketname-south-1
ap-east-1:
bucketname: s3bucketname-east-1
ap-northeast-3:
bucketname: s3bucketname-ap-northeast-3
eu-south-1:
bucketname: s3bucketname-eu-south-1
me-south-1:
bucketname: s3bucketname-me-south-1
Resources:
StateS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub "cfntf-${AWS::Region}-${AWS::AccountId}"
There is more to this code however I've only included the relevant snippets for the question.
To summarize - why include mappings for bucketname when the bucketname is set directly, using region and account ID in the 'Resources' section?
There is use of the Fn::FindInMap
function which is used here as part of the ExecutorLambdaFunction
:
ExecutorLambdaFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: myfunction
Handler: index.handler
Role: !GetAtt ExecutorLambdaServiceRole.Arn
Environment:
Variables:
BUCKET: !Ref StateS3Bucket
Code:
S3Bucket: !If
- S3Defined
- !Ref S3Bucket
- Fn::FindInMap:
- RegionMap
- !Ref AWS::Region
- bucketname
S3Key: !If
- S3Defined
- !Ref S3Key
- /app.zip
Runtime: python3.8
CodePudding user response:
StateS3Bucket
is being built from the region and account ID but that has nothing to do with the Mappings
section.
The mappings, in this case, are being used to provide the correct region-specific S3 bucket name for where the packaged source code for ExecutorLambdaFunction
exists - that is why Fn::FindInMap
is being used in the Lambda declaration.
Sometimes you may want to have dynamic values based on specific keys - the CloudFormation Mappings
section is the perfect solution to this problem.
Your packaged Lambda (the source code) is pointing to an S3 location in this case & as S3 buckets are region-specific, you need a way of getting the correct bucket name for the region that the stack is being deployed in.
The code for the ExecutorLambdaFunction
must be loaded from the S3 bucket in the relevant region otherwise it won't work.
For example, trying to load the Lambda source code from a bucket in us-east-1
won't work when your Lambda is deployed in eu-west-2
(note: it will work if it is deployed in us-east-2
as while that is in another availability zone, it is still within the same region).
Even if you only intend to have your stack in one region only, it won't harm you to have a Mappings
section as it will future proof your CloudFormation template.
If you don't have any region-specific infrastructure (quite rare but e.g. only creating IAM roles which are global & are set at an account-level), then you can not include one.
You'll spend much more time trying to add one in later than if you just spent an extra 3 minutes defining & using Mappings
as you write your template - you'll thank yourself if you later decide to deploy your stack in another region.