How to integrate CloudFront distribution to AWS WAF by using CloudFormation? - amazon-web-services

I am trying to add CloudFront distribution to AWS WAF by using CloudFormation and have tried this,
"Type": "AWS::WAFRegional::WebACLAssociation",
"Properties": {
"ResourceArn": "arn:aws:cloudfront::AccountID:distribution/CloudFrontID",
"WebACLId": {
"Ref": "WebACLName"
}
But I ended up with this error:
The referenced item does not exist. (Service: AWSWAFRegional; Status Code: 400; Error Code: WAFNonexistentItemException; Request ID: 149453cd-1606-11e8-86b2-a3efdb49d9d1)

AWS::WAFRegional::* is actually for association with Application Load Balancers. You'll want to use the AWS::WAF::* types (without the "Regional").
Then for the association you have to do it from the CloudFront distribution itself. Like so:
"myDistribution": {
"Type": "AWS::CloudFront::Distribution",
"Properties": {
"DistributionConfig": {
"WebACLId": { "Ref" : "MyWebACL" },
That part is explained in the CloudFormation documentation.

Related

Failed to create API Gateway

I'm trying to create this API Gateway (gist) with Authorizer, and ANY method.
I run into this error:
The following resource(s) failed to create: [BaseLambdaExecutionPolicy, ApiGatewayDeployment]
I've checked the parameters passed into this template from my other stacks and they're correct. I've checked this template and it's valid.
My template is modified from this template with "Runtime": "nodejs8.10".
This is the same stack (gist) which is created successfully using swagger 2. I just want to replace swagger 2 with AWS::ApiGateway::Method.
Update 6 Jun 2019:
I tried to create the whole nested stack using the working version of the API Gateway stack, then create another API Gateway with the template that doesn't work with the parameters I get from the nested stack, then I have this:
The REST API doesn't contain any methods (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException; Request ID: ID)
But I did specify the method in my template following AWS docs:
"GatewayMethod": {
"Type" : "AWS::ApiGateway::Method",
"DependsOn": ["LambdaRole", "ApiGateway"],
"Properties" : {
"ApiKeyRequired" : false,
"AuthorizationType" : "Cognito",
"HttpMethod" : "ANY",
"Integration" : {
"IntegrationHttpMethod" : "ANY",
"Type" : "AWS",
"Uri" : {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaFunction.Arn}/invocations"
}
},
"MethodResponses" : [{
"ResponseModels": {
"application/json": "Empty"
},
"StatusCode": 200
}],
"RequestModels" : {"application/json": "Empty"},
"ResourceId" : {
"Fn::GetAtt": ["ApiGateway", "RootResourceId"]
},
"RestApiId" : {
"Ref": "ApiGateway"
}
}
},
Thanks to #John's suggestion. I've tried to create the nested stack with the version that worked and pass in the parameters for the version that doesn't work.
The reason for that error is:
CloudFormation might try to create Deployment before it creates Method
from balaji's answer here.
So this is what I did:
"methodANY": {
"Type": "AWS::ApiGateway::Method",
"Properties": {
"AuthorizationType": "COGNITO_USER_POOLS",
...},
"ApiGatewayDeployment": {
"Type": "AWS::ApiGateway::Deployment",
"DependsOn": "methodANY",
...
I also found this article on cloudonaut.io by Michael Wittig helpful.

aws cloudformation WAF geo location condition

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.

Invalid domain name identifier specified

When trying to create an AWS::ApiGateway::BasePathMapping through CloudFormation, I am given the following error:
Invalid domain name identifier specified
Below is the portion(s) of my CloudFormation template that should create the AWS::ApiGateway::BasePathMapping:
{
"Parameters": {
"ApiDomainName": {
"Description": "The domain name for the API",
"Type": "String"
}
},
"Resources": {
"ApiBasePathMapping": {
"Type": "AWS::ApiGateway::BasePathMapping",
"Properties": {
"DomainName": {
"Ref": "ApiDomainName"
},
"RestApiId": {
"Ref": "RepositoryApi"
},
"Stage": {
"Ref": "ApiProductionStage"
}
},
"DependsOn": [
"ApiProductionStage"
]
}
}
}
The documentation makes no mention that it needs to be anything special for the DomainName, but the documentation for this resource seems to be lacking some information (It doesn't list outputs for example even though there is a Distribution Domain Name created as an example).
The remainder of the stack works as expected. I am trying to add this resource in as a Change Set. I do own the domain I am trying to use, and I have created a certificate in ACM for this domain.
Quoting from AWS forums:
You can only create or modify base path mappings after the domain name
has been added to API Gateway. This "Invalid domain name identifier
specified" error message is returned when the domain name given in the
base path mapping is not found, indicating that it has not been added
yet.
Also, as of March 2017, the only way to add domain name to the API Gateway via CloudFormation is via custom resources that CloudFormation offers.
Ref: https://forums.aws.amazon.com/message.jspa?messageID=769627
It is now possible to just do that. You just have to explicit state on your CFN template that there is a dependency (DependsOn):
...
ApiDevMapping:
Type: 'AWS::ApiGateway::BasePathMapping'
Properties:
BasePath: v1.0
Stage: dev
DomainName: my-api.example.com
RestApiId: !Ref MobileApiDev
DependsOn:
- MobileApiDevDomain
...

Publish S3 Bucket Notification to SQS

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

create event subscriptions in RDS with CloudFormation

Does CloudFormation support or have the ability to create DB event subscriptions(RDS)?
I failed to find any reference in AWS document...
Thanks
The latest version of CloudFormation, at the time of this writing, actually supports performing this by creating a "AWS::RDS::EventSubscription" resource in your stack.
"myEventSubscription": {
"Type": "AWS::RDS::EventSubscription",
"Properties": {
"EventCategories": ["configuration change", "failure", "deletion"],
"SnsTopicArn": "arn:aws:sns:us-west-2:123456789012:example-topic",
"SourceIds": ["db-instance-1", { "Ref" : "myDBInstance" }],
"SourceType":"db-instance",
"Enabled" : false
}
}