Create JSON value in SSM Parameter Store in Cloudformation - amazon-web-services

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.

Related

aws_ssm_document unable to validate YAML automation file from S3

Getting a returned error when trying to create a AWS Systems Manager automation document via aws_ssm_document Terraform resource.
Error: creating SSM document: InvalidDocumentContent: YAML not well-formed. at Line: 1, Column: 1
Test for sanity to create the YAML automation document manually using the same document and also to import it inline (which is less than ideal due to the size)
Sample below of the Terraform resource and the YAML document.
resource "aws_ssm_document" "rhel_updates" {
name = "TEST-DW"
document_format = "YAML"
content = "YAML"
document_type = "Automation"
attachments_source {
key = "SourceUrl"
values = ["s3://rhel/templates/101/runbooks/test.yaml"]
name = "test.yaml"
}
}
schemaVersion: '0.3'
description: |-
cloud.support#test.co.uk
parameters:
S3ArtifactStore:
type: String
default: rhel01
description: S3 Artifact Store.
ApiInfrastructureStackName:
type: String
description: API InfrastructureStackName.
default: rhel-api
mainSteps:
- name: getApiInfrastructureStackOutputs
action: 'aws:executeAwsApi'
outputs:
- Selector: '$.Stacks[0].Outputs'
Name: Outputs
Type: MapList
inputs:
Service: cloudformation
Api: DescribeStacks
StackName: '{{ApiInfrastructureStackName}}'

How to input the dictionary structure in 'values' argument using the aws_ssm_parameter in cloudformation

I have one parameter in AWS System Manager, type of the value is string, but value has a dictionary structure:
Value:
{"key1": "value1","key2": "value2","key3": "value3"}
Now i'm trying to create this parameter using the cloudformation. But i received an error, when trying to write this in cloudformation:
AWSTemplateFormatVersion: "2010-09-09"
Description: Systems Manager Parameter Store Parameters
Resources:
Test-Channels:
Type: AWS::SSM::Parameter
DeletionPolicy: Delete
Properties:
Name: test-Channels
Description:Lambda required parameter key and values
Type: String
Value: "{ "key1": "value1","key2": "value2", "key3", "value3"}"
error from cloudformation:
Property validation failure: [Value of property {/Value} does not match type {String}]
could someone please advise what I did wrong or the proper way of assigning dictionary type of value to parameter name using cloudformation?
Thank a lot!
You can use single quotes:
AWSTemplateFormatVersion: "2010-09-09"
Description: Systems Manager Parameter Store Parameters
Resources:
TestChannels:
Type: AWS::SSM::Parameter
DeletionPolicy: Delete
Properties:
Name: test-Channels
Description: Lambda required parameter key and values
Type: String
Value: dddd
Value: '{ "key1": "value1","key2": "value2", "key3", "value3"}'

How to Pass Multiple URLs to AllowOrigins in CloudFormation Template

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.

AWS API Gateway and Lambda integration with resources on different Cloudformation stacks

I want to integrate a lambda function to an API gateway so that when I do a POST to the path defined on the API gateway the Lambda gets executed and returns a value.
Now, in my current project we currently have 2 Cloudformation templates:
- One that is generic and contains the definition of recourses common to all development environments
- And another non-generic one that deploys different resources depending on the environment passed as a paramater (dev, prod, etc).
In the non generic I have defined the lambda function, as well as the Deployment and Stage.
In the generic CF template I have defined the APIGateway as this:
Resources:
RecargakiApiGateway:
Type: AWS::ApiGateway::RestApi
Properties:
Body:
swagger: "2.0"
info:
version: "VersionTimestamp"
title: "Some API"
host: "some.host"
schemes:
- "https"
paths:
/payment:
post:
produces:
- "application/json"
responses:
"200":
description: "200 response"
schema:
$ref: "#/definitions/Empty"
x-amazon-apigateway-integration:
credentials:
Fn::ImportValue:
"lambda-credentials-outputvalue-in-another-generic-stack"
uri: !Sub
- "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda::${AWS::Region}:${AWS::AccountId}:function:${lambdaName}/invocations"
- lambdaName: "${stageVariables.lambda_name}"
responses:
default:
statusCode: "200"
passthroughBehavior: "when_no_match"
timeoutInMillis: 5000
httpMethod: "POST"
contentHandling: "CONVERT_TO_TEXT"
type: "aws_proxy"
definitions:
Empty:
type: "object"
title: "Empty Schema"
Description: "Desc"
Name: "Name"
EndpointConfiguration:
Types:
- REGIONAL
Now according to the docs on AWS proxy integration it is possible to construct the lambda uri like this:
arn:aws:apigateway:<region>:lambda:path/2015-03-31/functions/arn:aws:lambda::<account_id>:function:${stageVariables.<function_variable_name>}/invocations
I tried to construct the uri according to that format but I get this error:
Unable to put integration on 'POST' for resource at path '/payment': Invalid function ARN or invalid uri (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException
In all the examples I've seen, people assume the Lambda function to be integrated is located in the same CF template/stack as the API Gateway resource, but I have no idea how to reference the function's ARN and/or name in the Swagger definition of the API Gateway when the function is actually located in a different CF stack.
I've also tried referencing a stage variable that would contain the full URI like:
uri: "${stageVariables.functionURI}" # the URI would be constructed in the non generic stack in the format stated by the docs
But it fails with:
Unable to put integration on 'POST' for resource at path '/payment': Invalid ARN specified in the request (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException
Any help is greatly appreciated.

Cloudformation Cloudwatch InputTemplate Formatting

I'm attempting to use a cloudformation template to create a cloudwatch event rule that matches a glue event and targets an SNS topic to send a message to, I can create it in the cloudwatch console, but not via a cloud watch template. Here is my event rule:
NotifyEventRule:
Type: AWS::Events::Rule
Properties:
Name: JobNotifyEvent
Description: Notification event on job status change.
EventPattern:
source:
- aws.glue
account:
- !Ref AWS::AccountId
detail-type:
- Glue Job State Change
detail:
jobName:
- !Ref GlueJobName
Targets:
-
Arn:
Ref: "JobNotificationTopic"
Id:
Ref: "JobNotificationTopicName"
InputTransformer:
InputTemplate: "Job finished in the following state: <state>."
InputPathsMap:
state: "$.detail.state"
The problem is with InputTemplate. The error I get is:
Invalid InputTemplate for target JobNotificationTopic : [Source:
(String)"Job finished in the following state: null."; line: 1, column:
10]. (Service: AmazonCloudWatchEvents; Status Code: 400; Error Code:
ValidationException; Request ID: 12345678...)
It seems like <state> may be the problem.
The syntax for InputTemplate is for some reason quite strict in CloudFormation. It is of type string but it does not accept any form of valid YAML string.
In your case, you should use YAML Literal Block Scalar, |, before the input string.
InputTransformer:
InputPathsMap:
state: "$.detail.state"
InputTemplate: |
"Job finished in the following state: <state>."
If the input string is multiline, each line has to be enclosed in double quotes.
InputTransformer:
InputPathsMap:
state: $.detail.state
name: $.detail.name
InputTemplate: |
"Job <name> has just been run."
"Job finished in the following state: <state>."
Just to note that your string uses plain flow scalars, which is picky about the : character. Colon cannot appear before a space or newline. See Yaml multiline for further details. However, as I pointed out most of these YAML multiline rules does not apply to InputTemplate.
This is not an issue with YAML format as you get the same error using JSON.
The InputTemplate must be a string inside AWS:
InputTemplate=
"\"The Pipeline <pipeline> Started\""
This AWS Developer Forum topic gave me the answer: https://forums.aws.amazon.com/thread.jspa?messageID=798687
I believe the issue is that the InputTemplate is not a valid JSON. See: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-events-rule-inputtransformer.html#cfn-events-rule-inputtransformer-inputtemplate
The InputTemplate must be valid JSON.