How to Pass Multiple URLs to AllowOrigins in CloudFormation Template - amazon-web-services

I am using a CloudFormation template in YML format.
Depending on the environment, I need to be able to use different URLs for the Allowed Origins attribute of my CorsConfiguration. Ideally, I would like to use a Parameter defined like this:
AllowedOrigins:
Description: Allowed Origins
Type: String
AllowedPattern: '.+'
I have tried to pass in a delimited string (i.e. "http://localhost:4200,http://localhost:4201"), and split the values like this:
OnboardingHttpApi:
Type: AWS::Serverless::HttpApi
Properties:
CorsConfiguration:
AllowOrigins: !Split [ ",", !Ref AllowedOrigins ]
The response in CloudFormation is:
Warnings found during import: CORS Scheme is malformed, ignoring. (Service: AmazonApiGatewayV2; Status Code: 400; Error Code: BadRequestException; Request ID: 21072c02-70c3-473d-9629-784005226bd4; Proxy: null) (Service: null; Status Code: 404; Error Code: BadRequestException; Request ID: null; Proxy: null)

This is the answer I got from AWS Support:
The Split function is for splitting strings into a list, but it is not for referencing an attribute. It is designed to be used with the Select function or other functions. So it is not a stand-alone function to be used for referencing. For this, you can use the CommaDelimitedList parameter type. You can use the CommaDelimitedList parameter type to specify multiple string values in a single parameter. Once you pass the CommaDelimitedList parameter value, you can reference it later on your template. Here is a CloudFormation template that works:
AWSTemplateFormatVersion: 2010-09-09
Transform: 'AWS::Serverless-2016-10-31'
Parameters:
AllowedOriginsURLs:
Type: CommaDelimitedList
Default: 'https://example.com,https://example2.com'
Description: Please enter your URLs
Resources:
HttpApi:
Type: 'AWS::Serverless::HttpApi'
Properties:
StageName: my-stage-name
Tags:
Tag: MyTag
StageVariables:
StageVar: Value
CorsConfiguration:
AllowOrigins: !Ref AllowedOriginsURLs
AllowHeaders: [ x-apigateway-header ]
AllowMethods: [ GET ]
MaxAge: 600
AllowCredentials: true
The AllowedOriginsURLs parameter is of type CommaDelimitedList, with the default being 'http://localhost:4200,http://localhost:4201'. You can change this parameter on startup, then you can reference AllowedOriginsURLs on AllowOrigins.

Related

Template validation failed when using SAM syntax instead of CloudFormation syntax for step function

I have the following step function in my AWS SAM template, it was defined using the syntax in the documentation. I'm using intrinsic functions to get some pseudoparameters but something is going wrong with them.
SfdcOrderEventsStepFunction:
Type: AWS::Serverless::StateMachine
Properties:
DefinitionSubstitutions:
Region: !Ref "AWS::Region"
AccountId: !Ref "AWS::AccountId"
EventBusPublishTarget: "order-events"
DefinitionUri: sfn-definition.asl.yml
Events:
EventBridgeEvent:
Type: EventBridgeRule
Properties:
EventBusName: sfdc-events
Pattern:
# TODO: Update pattern when the salesforce service is ready
source:
- prefix: salesforce.com
detail-type:
- Order
detail:
Payload__c:
attributes:
type:
- order
InputPath: $.detail
Name: sfdc-order-events
Role: !Sub 'arn:aws:iam::${AWS::AccountId}:role/stepfunction_execution_role'
Tracing:
Enabled: true
when I try to deploy it shows me the following error:
Resource template validation failed for resource
SfdcOrderEventsStepFunction as the template has invalid properties.
Please refer to the resource documentation to fix the template.
Properties validation failed for resource SfdcOrderEventsStepFunction
with message:
#/De finitionSubstitutions/ AccountId: 2 subschemas matched instead of one
#/DefinitionSubstitutions/AccountId: expected type: Boolean, found: String
At the end it deploys without problems. The step function and all of its components run as expected and without errors, but I wanted to know if there if something I can do to fix the template.

Create JSON value in SSM Parameter Store in Cloudformation

I need to create SSM parameter store in Cloudformation to store JSON
Here is my Template
Resources:
WebServersSSM:
Type: AWS::SSM::Parameter
Properties:
AllowedPattern: String
DataType: text
Description: WebServers CloudWatch Agent Configuration
Name: WebServersSSM
Type: String
Tier: Standard
Value: |
{
... My JSON File
}
I am facing error
Parameter value, cannot be validated against allowedPattern: String (Service: AmazonSSM; Status Code: 400; Error Code: ParameterPatternMismatchException; Request ID: a7c2f063-9e63-4b4c-981b-c9ad05e56166; Proxy: null)
The AllowedPattern is a regular expression to validate the pattern and not the expected type. Remove it and it should work.

"Parameter values specified for a template which does not require them." when trying to deploy a conformance pack via AWS cloudformation

I am working on a proof of concept for deploying a conformance pack via AWS cloudformation and I am stumped by the error "Parameter values specified for a template which does not require them." The config rule I am using does require a parameter. Code is attached. I have also tested the template with cfn-lint and do not receive any feedback/errors.
My template is "simple" and below:
Parameters:
ElbPredefinedSecurityPolicySslCheckParamPredefinedPolicyName:
Default: ELBSecurityPolicy-2016-08
Type: String
Resources:
TestingConformancePack:
Type: AWS::Config::ConformancePack
Properties:
ConformancePackName: TestCP
ConformancePackInputParameters:
-
ParameterName: PredefinedPolicyName
ParameterValue: !Ref ElbPredefinedSecurityPolicySslCheckParamPredefinedPolicyName
TemplateBody: |
Resources:
ElbPredefinedSecurityPolicySslCheck:
Properties:
ConfigRuleName: elb-predefined-security-policy-ssl-check
InputParameters:
predefinedPolicyName:
Ref: ElbPredefinedSecurityPolicySslCheckParamPredefinedPolicyName
Scope:
ComplianceResourceTypes:
- AWS::ElasticLoadBalancing::LoadBalancer
Source:
Owner: AWS
SourceIdentifier: ELB_PREDEFINED_SECURITY_POLICY_SSL_CHECK
Type: AWS::Config::ConfigRule
The cause is that you are passing a parameter (the one specified in ConformancePackInputParameters) to a CloudFormation template (the one specified in TemplateBody) that does not contain a Parameters section and therefore expects no parameters. To solve this, you need to add a parameter to the inner CloudFormation template, which you can then refer to in predefinedPolicyName:
The following template works for me:
Parameters:
ElbPredefinedSecurityPolicySslCheckParamPredefinedPolicyName:
Default: ELBSecurityPolicy-2016-08
Type: String
Resources:
TestingConformancePack:
Type: AWS::Config::ConformancePack
Properties:
ConformancePackName: TestCP
ConformancePackInputParameters:
-
ParameterName: PredefinedPolicyName
ParameterValue: !Ref ElbPredefinedSecurityPolicySslCheckParamPredefinedPolicyName
TemplateBody: |
Parameters:
PredefinedPolicyName:
Type: String
Resources:
ElbPredefinedSecurityPolicySslCheck:
Properties:
ConfigRuleName: elb-predefined-security-policy-ssl-check
InputParameters:
predefinedPolicyName:
Ref: PredefinedPolicyName
Scope:
ComplianceResourceTypes:
- AWS::ElasticLoadBalancing::LoadBalancer
Source:
Owner: AWS
SourceIdentifier: ELB_PREDEFINED_SECURITY_POLICY_SSL_CHECK
Type: AWS::Config::ConfigRule
I was making a test case resource using cloudformation and stumbled upon this same error.
“Parameter values specified for a template which does not require them.”
Since it was a test case, I didn't use any parameters at all. The above answer was helpful for me to understand it has to do something with parameters. Even though you are not using any, there are some parameters passed while deploying the cfn.
By default, cloudformation also sends env as parameter which needs to come under parameters as such. (Below code snippet in JSON)
"Parameters": {
"env": {
"Type": "String"
}
},
Hope this was helpful.

How use Sub function wth GetAtt in serverless?

Consider the following code:
EventRule:
Type: AWS::Events::Rule
Properties:
Description: "ny trigger"
ScheduleExpression: "rate(1 minute)"
State: "DISABLED"
Targets:
-
Arn: !GetAtt MyFunctionLambdaFunction.Arn
Id: "someId"
Input:
Fn::Sub:
- '{"arn":"#{arn}"}'
- arn: !GetAtt MyStateMachine.Arn
This gives me en error:
Error: The CloudFormation template is invalid: Template error: One or more Fn::Sub
intrinsic functions don't specify expected arguments. Specify a string as first argument,
and an optional second argument to specify a mapping of values to replace in the string
You don't need GetAtt in Sub here. Sub can resolve things like MyStateMachine.Arn. So you can just do something like:
Input: !Sub
- |-
{ "arn": "${MyStateMachine.Arn}" }
In some cases you might still need to pass in parameters (for instance when you need to call functions like ImportValue). For instance, if your state machine is defined in a different stack and is exported via other-stack-MyStateMachine-Arn output, you can do the following:
Input: !Sub
- |-
{ "arn": "${MyStateMachineArn}" }
- MyStateMachineArn: !ImportValue
'Fn::Sub': 'other-stack-MyStateMachine-Arn'

CloudFormation nested stack parameter conversion from String/ComaDelimitedList to 'mappings Key-Value pairs'

I am passing a parameter from a cloudformation master stack to a nested stack for RequestParameters property of 'AWS::ApiGateway::Method' resource.
The supported CloudFormation Parameter types (DataType) are: String, Number, List, CommaDelimitedList and AWS-Specific Parameter Types as specified here:
Is it possible to set the parameter value as String ( or CommaDelimitedList ) and in the nested stack to convert it into mappings key-value pairs as RequestParameters property of 'AWS::ApiGateway::Method' resource requires it?
A mapping of key-value pairs would look like this:
Resources:
LambdaEndpointMethod:
Type: AWS::ApiGateway::Method
Properties:
RequestParameters:
method.request.querystring.param1 : true
method.request.querystring.param2 : true
method.request.querystring.param3 : true
I have already tried specifying the parameter type String and passing all key-value pairs as comma separated strings then using Fn::Split intrinsic function to split the string but cloudformation complains with an error Value of property RequestParameters must be an object.
this is my nested stack template:
Parameters:
RequestParametersString:
Description: List of request parameters
Type: String
Default: ''
...
Conditions:
EmptyRequestParametersString: !Equals [ !Ref RequestParametersString, '' ]
...
Resources:
LambdaEndpointMethod:
Type: AWS::ApiGateway::Method
Properties:
RequestParameters: !If [ EmptyRequestParametersString, 'AWS:NoValue', !Split [',', !Ref RequestParametersList] ]
and this is my master template:
MyNestedStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: ...
Parameters:
...
RequestParametersString: 'method.request.querystring.param1 : true, method.request.querystring.param2 : true, method.request.querystring.param3 : false'
Is there any way how to achieve this on cloudformation or could somebody provide a solution of how to pass a couple of key-value pairs from master to child stack as a parameter?