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
Related
Say I have a reusable component:
parameters:
ResourceName:
in: path
name: name
description: The name of the Resource (See tag for resource)
schema:
type: string
required: true
I have a use for this component across several endpoints, and the identifier that I see for these endpoints is the tag. Can I insert the tag name in the description as its inserted?
An example implementation in an operation
tags:
- SampleResourceName
parameters:
- $ref: '#/components/parameters/ResourceName'
How can I insert SampleResourceName in the description of the parameter, IE:
parameters:
ResourceName:
in: path
name: name
description: The name of the {tag}
schema:
type: string
required: true
OpenAPI and YAML do not support variable placeholders.
But you can write a script that would parse your OpenAPI file and process it the way you need. Check out Use placeholders in YAML which contains links to YAML extension libraries that can help you with this.
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?
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'
I don't know if there's a way to use previously defined variables in variable definition. Basically I want to do something like this:
variables:
- name: basePath
value: \\somepath
- name: servicePath
value: $(basePath)\servicePath
- name: backupPath
value: $(basePath)\backups
The later variables don't recognize basePath. Is there a different syntax I can use?
We do something similar, here's what we have in our yaml:
- name: cdn-base
value: 'https://cdn-name.azureedge.net'
- name: 'CDN_URL'
value: '$(cdn-base)/$(site-name)-$(environment)/'
- name: NODE_MODULES_CACHE_FOLDER
value: $(System.DefaultWorkingDirectory)/node_modules
Might just need to wrap your strings in quotes. Also check your agent type because it might be you using windows path separator on a linux agent.
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: