I've got a problem with AWS Cloudformation.
Here is part of the my template
"CreationPolicy": {
"ResourceSignal": {
"Fn::If": [
"UseCreationPolicy",
{
"Count": 1,
"Timeout": "PT150M"
},
{
"Ref": "AWS::NoValue"
}
]
}
},
There is no errors while validating locally with aws cloudformation validate-template --template-body file:////...
But in Cloudformation I have a Validation Error while creating Stack :
Template error: Fn::If requires a list argument with three elements
Did someone has something like that?
Regarding that I have found only one question (unanswered) on AWS Forum: https://forums.aws.amazon.com/thread.jspa?threadID=202297
The problem I guess is with AWS:NoValue which is returned for ResourceSignal. What I think you should try is returning AWS:NoValue for CreationPolicy instead of ResourceSignal so that when the condition UseCreationPolicy is false then the whole CreationPolicy should be waived off.
I am currently doing the exact same thing as the original poster. ( I know it is old ), but the accepted answer is no longer relevant and I want to clarify this for anyone trying to find the answer (like me). To do this in 2023 you can do like this:
ReservedConcurrentExecutions:
!If
- IsProdEnv
- !Sub '${VeryHighLambdaConcurrency}'
- !Sub '${HighLambdaConcurrency}'
Related
I'm using the below simple template and trying to list the region in parameter section using Pseudo parameter AWS::Region, however getting the below error while trying to update the stack :
Failed to retrieve external values
Image posted here [1]: https://i.stack.imgur.com/kUcoo.png
Nothing reporting on cloudtrail :
"responseElements": {
"parameters": [
{
"parameterType": "List<AWS::Region>",
"noEcho": false,
"parameterKey": "S3"
}
Below are my template details :
Parameters:
Region:
Type: List<AWS::Region>
Default: us-east-1
Resources:
###
Can someone give an advice. Thanks in advance.
Its not possible. You have to use CommaDelimitedList.
I would love to be able to update an existing lambda function via AWS CDK. I need to update the environment variable configuration. From what I can see this is not possible, is there something workable to make this happen?
I am using code like this to import the lambda:
const importedLambdaFromArn = lambda.Function.fromFunctionAttributes(
this,
'external-lambda-from-arn',
{
functionArn: 'my-arn',
role: importedRole,
}
);
For now, I have to manually alter a cloudformation template. Updating directly in cdk would be much nicer.
Yes, it is possible, although you should read #Allan_Chua's answer before actually doing it. Lambda's UpdateFunctionConfiguration API can modify a deployed function's environment variables. The CDK's AwsCustomResource construct lets us call that API during stack deployment.*
Let's say you want to set TABLE_NAME on a previously deployed lambda to the value of a DynamoDB table's name:
// MyStack.ts
const existingFunc = lambda.Function.fromFunctionArn(this, 'ImportedFunction', arn);
const table = new dynamo.Table(this, 'DemoTable', {
partitionKey: { name: 'id', type: dynamo.AttributeType.STRING },
});
new cr.AwsCustomResource(this, 'UpdateEnvVar', {
onCreate: {
service: 'Lambda',
action: 'updateFunctionConfiguration',
parameters: {
FunctionName: existingFunc.functionArn,
Environment: {
Variables: {
TABLE_NAME: table.tableName,
},
},
},
physicalResourceId: cr.PhysicalResourceId.of('DemoTable'),
},
policy: cr.AwsCustomResourcePolicy.fromSdkCalls({
resources: [existingFunc.functionArn],
}),
});
Under the hood, the custom resource creates a lambda that makes the UpdateFunctionConfiguration call using the JS SDK when the stack is created. There are also onUpdate and onDelete cases to handle.
* Again, whether this is a good idea or not depends on the use case. You could always call UpdateFunctionConfiguration without the CDK.
The main purpose of CDK is to enable AWS customers to have the capability to automatically provision resources. If we're attempting to update settings of pre-existing resources that were managed by other CloudFormation stacks, it is better to update the variable on its parent CloudFormation template instead of CDK. This provides the following advantages on your side:
There's a single source of truth of what the variable should look like
There's no tug o war between the CDK and CloudFormation template whenever an update is being pushed from these sources.
Otherwise, since this is a compute layer, just get rid of the lambda function from CloudFormation and start full CDK usage altogether bro!
Hope this advise helps
If you are using AWS Amplify, the accepted answer will not work and instead you can do this by exporting a CloudFormation Output from your custom resource stack and then referencing that output using an input parameter in the other stack.
With CDK
new CfnOutput(this, 'MyOutput', { value: 'MyValue' });
With CloudFormation Template
"Outputs": {
"MyOutput": {
"Value": "MyValue"
}
}
Add an input parameter to the cloudformation-template.json of the resource you want to reference your output value in:
"Parameters": {
"myInput": {
"Type": "String",
"Description": "A custom input"
},
}
Create a parameters.json file that passes the output to the input parameter:
{
"myInput": {
"Fn::GetAtt": ["customResource", "Outputs.MyOutput"]
}
}
Finally, reference that input in your stack:
"Resources": {
"LambdaFunction": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Environment": {
"Variables": {
"myEnvVar": {
"Ref": "myInput"
},
}
},
}
}
}
I have been using nested stacks in CloudFormation for several months and they are very useful. So I thought I should spend sometime to make each nested stack reusable to other teams in the org.
I saw the use case of AWS::Include in several places like here and here and it makes good sense to me.
One approach I have in mind is one snippet for each resource, like an AWS::EC2::Subnet or AWS::EC2::InternetGateway which can be included zero or more times into a vpc.json template, which itself can be used as a nested stack in a larger application.
The snippet does not take any parameters, but can reference a parameter that exists in the parent template.
At first glance this doesn't seem enough to me. Consider this example:
"PublicSubnet": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"VpcId": {"Ref": "VPC"},
"AvailabilityZone": {
"Fn::Select" : [ "0", { "Fn::GetAZs" : {"Ref": "AWS::Region"} }]
},
"CidrBlock": {
"Fn::FindInMap": ["AZSubnetMap", {
"Fn::Select" : [ "0", { "Fn::GetAZs" : {"Ref": "AWS::Region"} }]},
"PublicSubnet"]},
"MapPublicIpOnLaunch": "true",
"Tags": [..]
}
}
How can I avoid hard coding that "0" for the AZ in a Subnet snippet for example?
Unfortunately, AWS doesn't provide a way to dynamically update the template as per the requirement.
I have solved a similar problem using Mustache Templates using Java Library Handle Bars. Using this library you can generate template on the fly based on the requirements.
Hope this helps.
You will have to use two AWS::Include files located in:
s3://yourname/PublicSubnetA.yaml
s3://yourname/PublicSubnetB.yaml
And call them from your MAIN Template:
Fn::Transform:
Name: AWS::Include
Parameters:
Location : "s3://yourname/PublicSubnetA.yaml"
Fn::Transform:
Name: AWS::Include
Parameters:
Location : "s3://yourname/PublicSubnetB.yaml"
I 'am trying to find way to send additional parameters or override parameter to AWS::include, as you see it has
Parameters:
Location:
Why ti's not understanding more parameters and not just Location, I would be glad to have something like this:
Fn::Transform:
Name: AWS::Include
Parameters:
MySubnetIndex: 0
Location : "s3://yourname/PublicSubnetB.yaml"
I tried this way to send additional parameters:
Fn::Transform:
Name: AWS::Include
Parameters:
Location : "s3://my.test/create-ec2.yaml"
EC2Size :
Type: String
Default: "t2.micro"
And got interesting error:
The value of parameter EC2Size under transform Include must resolve to a string, number, boolean or a list of any of these
Looks like it understand what this is additional parameters, probably it need to be configured little bit different. I was not able to find way to fix this error yet.
Trying to create a cloud formation template to configure WAF with geo location condition. Couldnt find the right template yet. Any pointers would be appreciated.
http://docs.aws.amazon.com/waf/latest/developerguide/web-acl-geo-conditions.html
Unfortunately, the actual answer (as of this writing, July 2018) is that you cannot create geo match sets directly in CloudFormation. You can create them via the CLI or SDK, then reference them in the DataId field of a WAFRule's Predicates property.
Creating a GeoMatchSet with one constraint via CLI:
aws waf-regional get-change-token
aws waf-regional create-geo-match-set --name my-geo-set --change-token <token>
aws waf-regional get-change-token
aws waf-regional update-geo-match-set --change-token <new_token> --geo-match-set-id <id> --updates '[ { "Action": "INSERT", "GeoMatchConstraint": { "Type": "Country", "Value": "US" } } ]'
Now reference that GeoMatchSet id in the CloudFormation:
"WebAclGeoRule": {
"Type": "AWS::WAFRegional::Rule",
"Properties": {
...
"Predicates": [
{
"DataId": "00000000-1111-2222-3333-123412341234" // id from create-geo-match-set
"Negated": false,
"Type": "GeoMatch"
}
]
}
}
There is no documentation for it, but it is possible to create the Geo Match in serverless/cloudformation.
Used the following in serverless:
Resources:
Geos:
Type: "AWS::WAFRegional::GeoMatchSet"
Properties:
Name: geo
GeoMatchConstraints:
- Type: "Country"
Value: "IE"
Which translated to the following in cloudformation:
"Geos": {
"Type": "AWS::WAFRegional::GeoMatchSet",
"Properties": {
"Name": "geo",
"GeoMatchConstraints": [
{
"Type": "Country",
"Value": "IE"
}
]
}
}
That can then be referenced when creating a rule:
(serverless) :
Resources:
MyRule:
Type: "AWS::WAFRegional::Rule"
Properties:
Name: waf
Predicates:
- DataId:
Ref: "Geos"
Negated: false
Type: "GeoMatch"
(cloudformation) :
"MyRule": {
"Type": "AWS::WAFRegional::Rule",
"Properties": {
"Name": "waf",
"Predicates": [
{
"DataId": {
"Ref": "Geos"
},
"Negated": false,
"Type": "GeoMatch"
}
]
}
}
I'm afraid that your question is too vague to solicit a helpful response. The CloudFormation User Guide (pdf) defines many different WAF / CloudFront / R53 resources that will perform various forms of geo match / geo blocking capabilities. The link you provide seems a subset of Web Access Control Lists (Web ACL) - see AWS::WAF::WebACL on page 2540.
I suggest you have a look and if you are still stuck, actually describe what it is you are trying to achieve.
Note that the term you used: "geo location condition" doesn't directly relate to an AWS capability that I'm aware of.
Finally, if you are referring to https://aws.amazon.com/about-aws/whats-new/2017/10/aws-waf-now-supports-geographic-match/, then the latest Cloudformation User Guide doesn't seem to have been updated yet to reflect this.
I am trying to set up my S3 to notify my SQS Queue for a "PUT" Object Creation Event.
I am able to achieve this using CLI by:
aws --profile QA s3api put-bucket-notification --bucket <BUCKET_NAME> --notification-configuration '{ "QueueConfiguration": { "Id": "<EVENT ID>", "Event": "s3:ObjectCreated:Put", "Queue": "<QUEUE ARN>" } }'
Also able to do the same using Java:
NotificationConfiguration notificationConfiguration = new QueueConfiguration(queueArn, EnumSet.of(S3Event.ObjectCreatedByPut));
BucketNotificationConfiguration bucketNotificationConfiguration = new BucketNotificationConfiguration("DropShipInboundQueueDelivery", notificationConfiguration);
client.setBucketNotificationConfiguration(bucketName, bucketNotificationConfiguration)
However when I tried to something similar using CloudFormation template, I cannot find any way to trigger a notification to SQS. The only option I see that works and is documented is to trigger notification to SNS.
I have referred the Cloud Formation Documentation:
I looked at the AWS::S3::Bucket docs to look at the outer syntax. I saw NotificationConfiguration which I need to set
However the Notification Configuration can only contain a list of TopicConfigurations with was the old constructor in JDK before QueueConfiguration was supported
I tried doing something like this:
"NotificationConfiguration" :{
"QueueConfiguration": {
"Id": "DropshipInboundEventNotification",
"Event": "s3:ObjectCreated:Put",
"Queue": "arn:aws:sqs:*:*:Dropship-Inbound-qa"
}
},
But this as expected threw an error: "Encountered unsupported property QueueConfiguration" from amazon.
Looked at this API documentation
I would like to know if someone has been able to do this using CloudFormation Templates as thats how I am maintaining all the other AWS resources and do not want to do anything special for this particular feature.
Any help is appreciated.
There is no need "Id" in Cloudformation Template ( You can check from QueueConfiguration Doc ) and your second mistake, that is not "QueueConfiguration", it's "QueueConfigurations". Because of that you get an error that says "Encountered unsupported property QueueConfiguration"
It must be something like that.
"S3Bucket":{
"Type" : "AWS::S3::Bucket",
"Properties" : {
"AccessControl" : String,
"BucketName" : String,
"CorsConfiguration" : CORS Configuration,
"LifecycleConfiguration" : Lifecycle Configuration,
"LoggingConfiguration" : Logging Configuration,
"NotificationConfiguration" :
{ "QueueConfigurations" : [ {
"Event" : "s3:ObjectCreated:Put",
"Queue" : "arn:YOURQUEUEARN"
} ] },
"Tags" : [ Resource Tag, ... ],
"VersioningConfiguration" : Versioning Configuration,
"WebsiteConfiguration" : Website Configuration Type
}
}
While you are reading cloudformation template documents, you must be careful about "Required:" sections. If it is not required, you don't need to fill it, just remove that line from your template if you don't use it( Like S3 Tags ).
Other Docs about it:
S3BucketDocs
NotificationConfigurationDocs