CloudFormation Transform Section stops Rule Assertions from executing - aws-cloudformation

I have the following (contrived) CloudFormation Template, without a Transform Section, which executes the Validation Assertion Rules properly (will show AssertDescription if BlueGreen and Lambda Param values are Equal, and won't let me click "Next" off the first page in the CF Console):
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
BlueGreen:
Type: String
Default: Yes
AllowedValues:
- Yes
- No
Lambda:
Type: String
Default: No
AllowedValues:
- Yes
- No
Rules:
ValidateBlueGreenOrLambda:
Assertions:
- AssertDescription: "Select BlueGreen or Lambda"
Assert: !Not [!Equals [!Ref BlueGreen, !Ref Lambda]]
Resources:
MyBucket:
Type: AWS::S3::Bucket
However, if I add a Transform Section to the Template, the Rules are not Asserted, and I can continue on in the Console to build the Stack:
AWSTemplateFormatVersion: "2010-09-09"
Transform: "AWS::CodeDeployBlueGreen"
... Rest of Template from above here
Does anyone know why adding a Transform Section would stop the Rule Assertions from executing?

Related

Azure DevOps - AWS CloudFormation and parameters

I have a simple CloudFomration template to create a VPC:
vpc.yaml
---
Parameters:
CidrBlock:
Type: String
Description: The primary IPv4 CIDR block for the VPC
Resources:
VPC:
Type: "AWS::EC2::VPC"
Properties:
CidrBlock: !Ref "CidrBlock"
Tags:
- Key: "Name"
Value: "This is the main VPC"
In my Azure Devops pipleline I want to use AWS Stack create to create a VPC by using this CloudFormation template.
Azure-pipeline.yaml
---
jobs:
- job: Job1
steps:
- task: CloudFormationCreateOrUpdateStack#1
inputs:
awsCredentials: 'My-cred'
regionName: 'ap-southeast-2'
stackName: 'Stack1'
templateSource: 'file'
templateFile: 'vpc.yaml'
templateParametersSource: inline
templateParameters: |
- ParameterKey: CidrBlock
ParameterValue: '10.10.10.0/24'
Obviousely, it'll work fine when I manually provide the value for the CidrBlock parameter when calling vpc.yaml template (like above ^). But what I want to do is using another file to store the parameters and values and pass that when running the vpc template.
In other words, I have a params.yaml file in which I stored the required parameters to run vpc.yaml. How can I use that when running the vpc.yaml template as the parameter files?
params.yaml
---
parameters:
- name: CidrBlock
value: '10.10.10.0/24'
Like how I refer to the template file in azure-pipeline file above, is there a similar way with which I can refer to the params file instead of using templateParametersSource: inline ?
It looks like there is an issue with YAML parameters file with aws-cli:
https://github.com/aws/aws-cli/issues/2275
You can use JSON file:
[
{
"CidrBlock": "10.10.10.0/24",
}
]
Sounds like unlike Azure Bicep or ARM where you can use keys of your own when creating the params files, AWS expect a specific structure where you must always use ParameterKey and ParameterValue as the key.
Here is how the params file should look like in my case:
---
- ParameterKey: CidrBlock
ParameterValue: '10.10.10.0/24'

Rundeck passing key-data value as command line argument

How I can pass the log filter key-value data into one of the reference job as an argument.
I was able to use the options available on the job as an argument to pass on the child reference job use,
But when I passed my log filter key-value data variable as ${data.my_log_filer_var} from the parent job argument, it does not evaluate in the child job but other argument passing is working for like for other option variables, I passed as: ${option.my_another_var}
Please let me know if there is any other way to pass the ${data.my_log_filer_var} to my child job.
Following this, I made a little example. Basically, you need an option on the child's job to "receive" the argument from the parent's job. This example is a couple of job definitions that you can import to your instance.
Child job (contains an option, this option is called from parent job passing the data variable):
- defaultTab: nodes
description: ''
executionEnabled: true
id: 0aeaa0f4-d090-4083-b0a5-2878c5f558d1
loglevel: INFO
name: ChildJob
nodeFilterEditable: false
options:
- name: opt1
plugins:
ExecutionLifecycle: null
scheduleEnabled: true
sequence:
commands:
- exec: 'echo "the argument is: ${option.opt1}"'
keepgoing: false
strategy: node-first
uuid: 0aeaa0f4-d090-4083-b0a5-2878c5f558d1
And the Parent job (creates a data value and passes it to a child using arguments -opt1 ${data.mydata})
- defaultTab: nodes
description: ''
executionEnabled: true
id: 5c3d4248-9761-45d4-b164-6e38d5146007
loglevel: INFO
name: ParentJob
nodeFilterEditable: false
plugins:
ExecutionLifecycle: null
scheduleEnabled: true
sequence:
commands:
- exec: env
plugins:
LogFilter:
- config:
invalidKeyPattern: \s|\$|\{|\}|\\
logData: 'true'
regex: ^(USER)\s*=\s*(.+)$
type: key-value-data
- exec: 'echo "the data value is ${data.USER}, sending to child job using arguments
on job reference step..."'
- jobref:
args: -opt1 ${data.USER}
group: ''
name: ChildJob
nodeStep: 'true'
uuid: 0aeaa0f4-d090-4083-b0a5-2878c5f558d1
keepgoing: false
strategy: node-first
uuid: 5c3d4248-9761-45d4-b164-6e38d5146007
The global variable step can capture data variable captured by key-value data log filter.
For example, if you capture the key-value data to export group, you can create a global variable {export.keyname*}, which can be used on other steps or in notifications. Note that if you only want the value from a single node, you should use {export.keyname#nodename} instead.
Rundeck Docs

YAML set a value on a parameter with a variable

is it possible to set a value on a parameter or to define the default value with the valiable.
e.g.
parameters:
- name: paraA
type: boolean
default: true
value: $(variableA)
#variableA is set in a yaml build in azure devops and for some build it should false and not true
parameters:
- name: paraA
type: boolean
default: ${{ if eq(variable.variableA, false) }}
As I know it's not supported scenario. Variables like variableA are expanded at runtime while parameters like paraA are expanded at template parsing time.
When processing one pipeline, it first expands templates and evaluate template expressions before expanding the runtime variables. The document has stated this:

Azure Yaml Pipelines - Dynamic object parameter to template

I would like to trigger a job template with an object as parameter.
Unfortunately, even based on the examples I couldn't find a way to do that.
I would appreciate if someone could guide me how to achieve this.
What I want to achieve, is to replace the ["DEPLOY", "CONFIG"] part with a dynamic variable:
- template: job-template.yaml
parameters:
jobs: ["DEPLOY", "CONFIG"]
This is not possible. YAML is very limited here and you may read more about this here
Yaml variables have always been string: string mappings.
So for instance you can define paramaters as complex type
Template file
parameters:
- name: 'instances'
type: object
default: {}
- name: 'server'
type: string
default: ''
steps:
- ${{ each instance in parameters.instances }}:
- script: echo ${{ parameters.server }}:${{ instance }}
Main file
steps:
- template: template.yaml
parameters:
instances:
- test1
- test2
server: someServer
But you are not able to do it dynamically/programmatically as every output you will create will end up as simple string.
What you can do is to pass as string and then using powershell split that string. But it all depends what you want to run further because you won't be able to simply iterate over yaml structure in that way. All what you can do is to run in in powershell loop and do something, but it can be not enough for you.
It's possible with some logic. see below
- template: job-template.yaml
parameters:
param: ["DEPLOY", "CONFIG"]
and in job-template.yaml file you can define. So every job name will be different
parameters:
param: []
jobs:
- ${{each jobName in parameters.param}}:
- job: ${{jobName}}
steps:
- task: Downl......

How to add 'Always Required' Values to a CommaDelimitedList

I'm attempting to create an IAM Policy for limiting access to selected S3 Buckets. There are some default S3 Bucket ARNs, that must always be present, the template operator is allowed to add a list of additional Bucket ARNs to grant access to, through a Parameter.
In my template the BucketARNs Parameter, allows the operator to specify a list of ARN that is not limited in length.
BucketARNs:
Type: CommaDelimitedList
Description: 'Add the ARN of S3 Buckets that the Get* and List*
access to. When specifying a Bucket 2 values should be supplied one for the
bucket and for objects within that bucket, for example: arn:aws:s3:::MyContentBucket,arn:aws:s3:::MyContentBucket/* .
This defaults to all buckets.'
Default: arn:aws:s3:::*, arn:aws:s3:::*/*
The policy document that uses this Parameter looks like
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- s3:Get*
- s3:List*
Resource:
!Ref BucketARNs
I want to do is ensure that, for example
arn:aws:s3:::MyMustHaveBucket,
arn:aws:s3:::MyMustHaveBucket/*
ARNs are always present in the list of BucketARNs. The Default in the Parameter can be removed by the operator - Is the only solution to add them as Default values and add information in the Parameter Description warning users not to remove the required ARNs? Which like it could be easily broken.
Does anyone know a way of ensuring I always have these available? considering the list of BucketARNs specified via the Parameter is variable?
Ideally, I'd like a list concatenation function
Two options:
You can use AllowedPattern on a String Parameter along with a Default value to ensure that the provided default is always included in the supplied parameter, then use Fn::Split to resolve the parameter into an array when used in your template:
Parameters:
BucketARNs:
Type: String
Default: arn:aws:s3:::*, arn:aws:s3:::*/*
AllowedPattern: arn:aws:s3:::\*, arn:aws:s3:::\*\/\*.*
Resources:
Dummy:
Type: AWS::CloudFormation::WaitConditionHandle
Outputs:
Result:
Value: !Join [',', !Split [',', !Ref BucketARNs]]
You can use Fn::Split along with Fn::Sub and Fn::Join to append your fixed values to a user-supplied Parameter:
Parameters:
BucketARNs:
Type: CommaDelimitedList
Resources:
Dummy:
Type: AWS::CloudFormation::WaitConditionHandle
Outputs:
Result:
Value: !Join [',', !Split [',', !Sub [
"arn:aws:s3:::*,arn:aws:s3:::*/*,${Buckets}",
{Buckets: !Join [',', !Ref BucketARNs]}
]]]
The final !Join in the above examples are only to output the Array in the Stack Output, they're not needed when using the parameters in an actual property input to your template.
Use FN::join to concatenate the constants with the parameters