Pass multiple parameters to DBParameterGroup in YAML CloudFormation - yaml

I have the following cloudformation template. The goal is to only create a parameter group if the user wants to and then to populate the RDS parameters in the parameter group with the contents of the cloudformation template parameters.
Parameters:
UseCustomParameterGroup:
Description: Toggle to 'Yes' to create a new parameter group.
Type: String
AllowedValues: ['Yes', 'No']
Default: 'No'
CustomParameters:
Description: Add custom parameters to your custom parameter group. Creating a custom parameter group without parameters creates a mirror of the default group.
Type: String
Conditions:
UseCustomParameterGroup: !Equals [!Ref 'UseCustomParameterGroup', 'Yes']
Resources:
CustomParameterGroup:
Type: AWS::RDS::DBParameterGroup
Condition: 'UseCustomParameterGroup'
Properties:
Family: "postgres10"
Parameters: !Ref "CustomParameters"
If I call this template from another template as so, it will fail with the error Value of property Parameters must be an object
Parameters:
USECUSTOMPARAMETERGROUP: 'Yes'
CUSTOMPARAMETERS: '{
"shared_preload_libraries": "pg_stat_statements",
"pg_stat_statements.track": "all"
}'
Resources:
Postgres:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://..../rds-postgres-instance.yaml
TimeoutInMinutes: '60'
Parameters:
UseCustomParameterGroup: !Ref USECUSTOMPARAMETERGROUP
CustomParameters: !Ref CUSTOMPARAMETERS
The documentation for AWS::RDS::DBParameterGroup states the following for the Parameters parameter:
Type: A JSON object consisting of string key-value pairs, as shown in the following example
"Parameters" : { "Key1" : "Value1", "Key2" : "Value2", "Key3" : "Value3" }
I think this may be out of date for the YAML version of Cloudformation, but there is no documentation on how to pass this value multiple parameters.
I want the user to be able to define as few or many RDS parameters as they please without having to account for any of the thousands of possible parameters available to RDS.

Cloudformation doesn't allow you to convert string parameters to JSON objects (or YAML for that matter), your parameters are meant to be used as values for your definition keys.
Some other frameworks like serverless overcome this limitation by using a different template language that generates a Cloudformation compatible artifact after some processing, if this feature is critical to your process I advise you to migrate to one of those frameworks.

Related

How to show all the parameters names as comma separated string and assign to One Varaible in YAML Azure Pipelines

How to show all the parameter's names as comma-separated strings (concatenated) and assign them to One Variable in YAML Azure so that i can use this variable in several places
i tried using
parameters:
- name: Var1
displayName: Testing
type: string
- name: Var2
displayName: Coding
type: string
- name: Var3
displayName: Marketing
type: string
variables:
- name: allParametersString
${{each item in parameters}}:
value: $allParametersString + ','+ item.displayName
my desired output is upon using $allParametersString I should get
Testing,Coding,Marketing
but this is leaving an error mentioning 'value' is already defined so can anyone help me? regarding this, I am searching for a solution for 2 weeks :(
I found the way of using bash to assign values will work for this i did
variables:
- name: allParametersString
value: ' '
steps:
- ${{ each parameter in parameters }}:
# the below code will help us reassign the values to variables with bash so i am appending all parameters separated by comma
- bash: echo '##vso[task.setvariable variable=allParametersString]$(allParametersString)${{ parameter.Key }}, '
- script:
echo 'printing all parameters names separated by comma .->$(allParametersString)'
Please let me know if I can improve it more
this helps me understand that in order to reassign or assign twice or concatenate the string using YAML this is the one way of doing it
Your current thinking is not feasible.
There are several things that bind you.
1, The first is the processing logic of yml expression in DevOps.
See this official document:
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/runs?view=azure-devops#process-the-pipeline
From the first sentence given, we know your yml will be expanded like this:
parameters:
- name: Var1
displayName: Testing
type: string
default: value1
- name: Var2
displayName: Coding
type: string
default: value2
- name: Var3
displayName: Marketing
type: string
default: value3
variables:
- name: allParametersString
value: xxx
value: xxx
value: xxx
variable of yml concept doesn't allow the written method of the above. That's why you encountered error 'value' is already defined.
2, The second is the structure allowed by DevOps yml files.
Every section of yml definition has limited predefined key. This means that compile time cannot find other container to store the variable.
3, I am afraid the usage of yml expression does not support you to do so.
Refer to this:
Each Keyword This tell you the standard usage of 'each':
You can use the each keyword to loop through parameters with the
object type.
JOIN Expression
This is the way the DevOps yml pipeline provides compile-time flattening of data, but it doesn't work in your case.
And there's no such thing as an index or subscript to navigate to the last run.
4, By the way, the item object doesn't have such information 'displayName':
trigger:
- none
parameters:
- name: Var1
displayName: Testing
type: string
default: value1
- name: Var2
displayName: Coding
type: string
default: value2
- name: Var3
displayName: Marketing
type: string
default: value3
steps:
- ${{each item in parameters}}:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: |
# Write your PowerShell commands here.
Write-Host "${{ convertToJson(item) }}"
Result:
The DevOps yml pipeline has no built-in features to implement your needs. If you have to do this, a feasible method is to call the API to get the content of the yml file, then parse and get the parameter part (this is actually a self-designed parser), and then combine the acquired parameters into the variable in the script And pass logging command set variable(isoutput=true). In this way, other tasks can use this combined variable.
This can be done, but is overly complicated and you need to consider whether it is necessary to do such a thing.

Pywalify - evaluate nested maps

I'm using pykwalify to validate a schema.
Given this yaml:
variables:
dev:
options:
key: value
uat:
key: value
key2: value
prd:
key: value
key2: value
Under variables, any map should be allowed.
Under that second level (dev, uat, prd) - any key should be allowed, EXCEPT options. "options" should not be allowed here.
I've tried using a regex, but this is only evaluating the top level, and I'm not quite sure how evaluate the level nested under that "dev, uat, prd" level.
variables:
type: map
matching-rule: all
mapping:
regex;([^,]+):
type: any
regex;(^(?!.*options:).*$):
type: any
Another potential option would be if I have to explicitly list the values that are allowed, that would work too.
I see two issues in your snippet:
The regex to match anything but "options" is wrong.
The schema isn't properly structured for the nested mapping.
The following schema should provide what you need:
variables:
type: map
matching-rule: all
mapping:
regex;([^,]+):
type: map
mapping:
regex;(^(?!options$).*):
type: any

Chain functions in CloudFormation ImportValue, Join and Ref

I want to combine 3 functions in CloudFormation YAML but failing to do so.
I've got an exported parameter that I want to access foo-exportedParam
Then I want to import it, but taking into account that the prefix foo is dynamic and comes from a parameter in the template.
So I want something like
Name: Fn::ImportValue Fn::Join ['', [Fn::Ref prefix, "-exportedParam"]]
If I have the param prefix = foo, then this should translate into
Name: !ImportValue foo-exportedParam
Is this possible?
The documentation gave me a clue on the syntax. This works
Name:
Fn::ImportValue:
!Join ['', [!Ref prefix, "-exportedParam"]]
See nested simple sample: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html

Missed comma between flow collection entries when using Fn::GetAtt in YAML

I'm trying to add an event stream for DynamoDB in YAML, DynamoDB table is a variable that changes based on
the environment it gets deployed to, I'm using Fn::GetAtt to determine TABLE_NAME but it's giving me an exception.
Is the syntax right?
Is there a way to configure the stream in YAML other than Fn::GetAtt ?
Exception:
missed comma between flow collection entries in "erverless.yml" at line 60,
column28:Fn::GetAtt: [ ${self:custom.TABLE_NAME ...
Code:
custom:
TABLE_NAME : mix of account + env + name
events:
- stream:
type: dynamodb
arn:
Fn::GetAtt: [ ${self:custom.TABLE_NAME}, StreamArn ]
Inside YAML flow collections, strings with characters like {, }, [ etc. have to be quoted, because { starts a flow mapping and [ starts a flow sequence.
There is no space required for that.
So this is how it should look like:
arn:
Fn::GetAtt: [ '${self:custom.TABLE_NAME}', StreamArn ]
For information on pretty much all types of quoting in YAML you can have a look at https://www.yaml.info/learn/quote.html (disclaimer: I'm the author).

raml2html not generating arrays declarations properly

I am using the raml2html tool to generate html documentation for my ReST apis.
I have defined all my types in a raml file memberTypes.raml that I include in the main service.raml.
Following is a sample from the service.raml file.
#%RAML 1.0
title: update member object
uses:
memberTypes: /memberTypes.raml
types:
Member:
properties:
termsAndConditions:
type: memberTypes.TermsAndConditions[]
description: The terms and conditions that the member has accepted.
required: false
person:
type: memberTypes.Person
description: The personal details of the member.
required: true
And following is a sample for the 2 properties above in memberTypes.raml
Person:
properties:
personName:
type: NameType
description: The name of the member.
required: true
dateOfBirth:
type: DateOfBirth
required: true
TermsAndConditions:
properties:
version:
type: string
description: The version of the terms and conditions.
acceptedDate:
type: date-only
description: The date on which the corresponding terms and conditions were accepted. Format is YYYY-MM-DD, ISO-8601 Calendar date format.
Now, below is the what I get in the html
The array is shown as array of memberTypes.TermsAndConditions. The questions is how do i get rid of the memberTypes? i simply want the type to be array of TermsAndConditions.
How do I achieve this? is there a command line option to raml2html tool that will do the trick?
I don't think there is command line option to do that, since the template / theme of raml2html defines how things are shown in HTML. You can edit the default theme. If I recall correctly that is defined in item.nunjucks file.
The usual use case for that is "array of objects" or "array of strings" but there is also definitions how to show non standard type types.

Resources