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.
Related
I'm using the OpenSearch 1.2 version deployed on AWS.
I was following this AWS tutorial but with my own sensor data. I've created the following IoT Core Rule OpenSearch Action:
OpenSearchTopicRule:
Type: AWS::IoT::TopicRule
Properties:
TopicRulePayload:
Actions:
- OpenSearch:
Endpoint: !Join ['', ['https://', !GetAtt OpenSearchServiceDomain.DomainEndpoint]]
Id: '${newuuid()}'
Index: sensors
RoleArn: !GetAtt IoTOSActionRole.Arn
Type: sensor_data
Sql: SELECT *, timestamp() as ts FROM 'Greenhouse/+/Sensor/Status'
The IoTOSActionRole has propper es:ESHttpPut permission. But when I try to create an index with following command send from Postman that would match the Type: sensor_data attribute:
curl --location --request PUT 'https://search-iot***-avt***i.eu-west-1.es.amazonaws.com/sensors' \
--header 'Content-Type: application/json' \
--data-raw '{
"mappings": {
"sensor_data": {
"properties": {
"ts": { "type": "long",
"copy_to": "datetime"},
"datetime": {"type": "date",
"store": true},
"deviceID": {"type": "text",
"store": true},
"humidity": {"type": "integer",
"store": true},
"temperature": {"type": "integer",
"store": true},
"lux": {"type": "integer",
"store": true},
"soil": {"type": "integer",
"store": true}
}}}'
I receive an error:
{
"error": {
"root_cause": [
{
"type": "mapper_parsing_exception",
"reason": "Root mapping definition has unsupported parameters: [sensor_data : {properties={datetime={store=true, type=date}, temperature={store=true, type=integer}, humidity={store=true, type=integer}, soil={store=true, type=integer}, deviceID={store=true, type=text}, lux={store=true, type=integer}, ts={copy_to=datetime, type=long}}}]"
}
],
"type": "mapper_parsing_exception",
"reason": "Failed to parse mapping [_doc]: Root mapping definition has unsupported parameters: [...]",
"caused_by": {
"type": "mapper_parsing_exception",
"reason": "Root mapping definition has unsupported parameters: [...}]"
}
},
"status": 400
}
I've tried removing the 'type' "sensor_data" attribute as mentioned here (but that's ElasticSearch solution) and that allowed me to create an index with that mapping,
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "sensors"
}
and then index pattern in OpenSearch Dashboard, but what happens then is that the IoT Core Rule even though it gets triggered does not result in any data ingestion to the OpenSearch domain. So I guess IoT Core Action tries to send that data with type sensor_databut there's no corresponding type in OS. Additionally, when I open the Discovery tab in OS dashboard I get this notice:
"undefined" is not a configured index pattern ID
Showing the default index pattern: "sensors*" (d97775d0-***a2fd725)
Sample data:
{
"deviceID": "Tomatoes",
"Greenhouse": 1,
"date": "05-05",
"time": "09:35:39",
"timestamp": 1651743339,
"humidity": 60,
"temperature": 33.3,
"lux": 9133.333,
"soil": 78
}
What PUT call I have to make to create a sensor_data type mapping in OS that would match the type specified in IoT Core OpenSearch Action Rule?
UPDATE
I've tried the same API call with Elasticsearch_7.10 and received the same mapper_parsing_exception response. I've tried removing the "store": true attribute. The only call accepted is the one omitting the sensor_data type attribute to the .../sensors/_mappings API.
I'm trying to use an existing role (present in the AWS account) in a cloudformation template to setup a lambda function, i plan to be use this across multiple AWS accounts.
In the CF template, I'm using Parameters to set the name of the Role and then using Ref in the Role property for the Lambda function. This is what my template looks like,
"Parameters" : {
"ExistingRoleName" : {
"Type" : "String",
"Default" : "MyCustomRole"
}
"Resources" : {
"CustomLambdaFunction" : {
"Type" : "AWS::Lambda::Function",
"Properties" : {
"MemorySize" : "128",
"Role" : { "Ref" : "ExistingRoleName" },
}
},
...
However, the CF template fails with the following error :
Properties validation failed for resource CustomLambdaFunction with message: #/Role: failed validation constraint for keyword [pattern]
Is this because Lambda resource in Cloudformation needs the role arn instead of RoleName as i seen in this docaws-resource-lambda-function
Based on which i updated the CF like so,
"Resources" : {
"CustomLambdaFunction" : {
"Type" : "AWS::Lambda::Function",
"Properties" : {
"MemorySize" : "128",
"Role" : "arn:aws:iam::AccountID:role/MyCustomRole",
}
},
However, i still see the same error.
Properties validation failed for resource CustomLambdaFunction with message: #/Role: failed validation constraint for keyword [pattern]
I was wondering if i'm missing something here ?
The Ref of an IAM Role “returns the resource name”, not its ARN. But you can use GetAtt on the Arn attribute of the role instead.
In JSON:
{"Fn::GetAtt": ["MyRole", "Arn"]}
In YAML:
!GetAtt MyRole.Arn
Format to reference the iam role arn
"Role" : { "Fn::Sub" : "arn:aws:iam::${AWS::AccountId}:role/MyCustomRole" }
In yaml if you are pointing to an already existing role the syntax is:
function:
...
role: !Sub arn:aws:iam::${AWS::AccountId}:role/MyRoleName
Somehow I have forgotten the !Sub in the beginning
This is what worked for me,
"Role": { "Fn::Join" : [ "", [ "arn:aws:iam::", { "Ref" : "AWS::AccountId" }, ":role/MyCustomRole" ] ] }
I was getting the same problem with below syntax -
"Resources" : {
"CustomLambdaFunction" : {
"Type" : "AWS::Lambda::Function",
"Properties" : {
"Role" : "arn:aws:iam::<account-id>:role/MyCustomRole",
}
},
I solved it like this -
The issue was that when inserting my AWS account ID in place of "account-id", I was keeping it in the same format as is given on the AWS console i.e. xxxx-xxxx-xxxx. However, the "account-id" space expects "\d{12}" format, i.e. 12 digits only. Removing the '-' in between digits solved the problem for me.
I'm validating a CloudFormation template that was generated via a Troposphere script. The resource in question which seems to be causing the error is a Metric Transformation which is defined as follows in the Troposphere script:
t.add_resource(logs.MetricTransformation(
"planReconciliationFiduciaryStepMetricTransformation",
MetricNamespace=Ref("metricNamespace"),
MetricName=Join("", [Ref("springProfile"), "-", "plan-reconciliation-step-known-to-fiduciary"]),
MetricValue="1"
))
The parameters it depends on are defined beforehand in the script as follows:
t.add_parameter(Parameter(
"metricNamespace",
Type="String",
Default="BATCH-ERRORS",
Description="Metric namespace for CloudWatch filters"
))
t.add_parameter(Parameter(
"springProfile",
Type="String",
Default=" ",
Description="SPRING PROFILE"
))
The exact command that I'm running is
aws cloudformation validate-template --template-body
file://hor-ubshobackgroundtaskdefinition.template --profile saml
with the resulting output
An error occurred (ValidationError) when calling the ValidateTemplate operation:
Invalid template resource property 'MetricName'
My properties for the MetricTransformation appear to be well-defined from the AWS documentation. For visibility, this is also what the metric transformation resource in the template that's being validated looks like too:
"planReconciliationFiduciaryStepMetricTransformation": {
"MetricName": {
"Fn::Join": [
"",
[
{
"Ref": "springProfile"
},
"-",
"plan-reconciliation-step-known-to-fiduciary"
]
]
},
"MetricNamespace": {
"Ref": "metricNamespace"
},
"MetricValue": "1"
}
Any ideas?
UPDATE:
As requested, adding the metric filter resource:
"PlanReconciliationFiduciaryStepMetricFilter": {
"Properties": {
"FilterPattern": "INFO generatePlanReconciliationStepKnownToFiduciary",
"LogGroupName": {
"Ref": "logGroupName"
},
"MetricTransformations": [
{
"Ref": "planReconciliationFiduciaryStepMetricTransformation"
}
]
},
"Type": "AWS::Logs::MetricFilter"
}
As it turns out, the MetricTransformation resource needs to be initialized within the MetricFilter itself in order to produce the correct CloudFormation template from the Troposphere script. If you declare the MetricTransformation as a separate resource and try to reference it within the the MetricFilter resource, the ensuing template will be incorrectly formatted.
The correct format in the Troposphere script will look like the following:
t.add_resource(logs.MetricFilter(
"PlanReconciliationFiduciaryStepMetricFilter",
FilterPattern="INFO generatePlanReconciliationStepKnownToFiduciary",
LogGroupName=Ref("logGroupName"),
MetricTransformations=[logs.MetricTransformation(
"planReconciliationFiduciaryStepMetricTransformation",
MetricNamespace=Ref("metricNamespace"),
MetricName=Join("", [Ref("springProfile"), "-", "plan-reconciliation-fiduciary-step"]),
MetricValue="1")]
))
I'm attempting to to have an API Gateway act as a proxy to DynamoDB and I'm currently testing with a simple POST call to append the $context.requestId and $context.requestTime to my table. I am getting the following error message:
{
"__type": "com.amazon.coral.validate#ValidationException",
"message": "One or more parameter values were invalid: An AttributeValue may not contain an empty string"
}
and what is sent is:
Mon Apr 15 19:10:24 UTC 2019 : Endpoint request body after transformations: {
"TableName": "BurgerOrders",
"Item": {
"OrderId": {
"S": "1f54a90b-5fb2-11e9-8b31-c9003bb71ec2"
},
"RequestTime": {
"S": ""
}
}
}
The mapping template within Integration Request that I have is:
{
"TableName": "BurgerOrders",
"Item": {
"OrderId": {
"S": "$context.requestId"
},
"RequestTime": {
"S": "$context.requestTime"
},
}
}
I've tried to change $context.requestTime to $context.requestTimeEpoch and I get the same error.
I know this was posted a while back, but according to an AWS dev:
"At this time, [$context.requestTime] is only available when the API has been deployed and API call was invoked to deployed stage."
Source: https://forums.aws.amazon.com/thread.jspa?messageID=697652
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.