Not able to map VPC_LINK with Method Integration on Api Gateway using cloud formation - aws-api-gateway

I am using Cloudformation to configure API Gateway Method to use VPC Link.
Its not working.
Sample code is as below:
ProxyResourceANY:
Type: AWS::ApiGateway::Method
Properties:
RestApiId: !Ref RestApi
ResourceId: !Ref RestApiResource
HttpMethod: ANY
AuthorizationType: NONE
Integration:
Type: HTTP_PROXY
IntegrationHttpMethod: ANY
#ConnectionType: VPC_LINK
#ConnectionId: !Ref VpcLink
Uri: !Sub http://${LoadBalancerUrl}:8098
CloudFormation error:
Encountered unsupported property ConnectionId

You can't use !Ref there but you have 2 solution for this :
Simply use !Sub instead of !Ref like this :
#ConnectionId: !Sub ${VpcLink}
Or more complex you can use stage variable :
Use a stage variable "${stageVariables.variable}" in your method instead of the reference to your VpcLink
ProxyResourceANY:
Type: AWS::ApiGateway::Method
Properties:
RestApiId: !Ref RestApi
ResourceId: !Ref RestApiResource
HttpMethod: ANY
AuthorizationType: NONE
Integration:
Type: HTTP_PROXY
IntegrationHttpMethod: ANY
ConnectionType: VPC_LINK
ConnectionId: '${stageVariables.vpcLink}'
Uri: !Sub http://${LoadBalancerUrl}:8098
And then set your stage variable referencing your VpcLink when you create your stage :
Stage:
Type: AWS::ApiGateway::Stage
Properties:
StageName: 'Stage'
Variables:
VpcLink: !Ref VpcLink

Related

AWS SAM AWS::ApiGatewayV2::Stage AccessLogSetting Property validation failure

Unfortunately I cannot get AWS WebSocket logging to work. Property validation failure: [Encountered unsupported properties in {/}: [AccessLogSetting]]. Any help highly appreciated.
Stage:
Type: AWS::ApiGatewayV2::Stage
Properties:
StageName: Prod
Description: Prod Stage
DeploymentId: !Ref Deployment
ApiId: !Ref TriviaWebSocket
AccessLogSetting:
DestinationArn: !GetAtt GwLogGroup.Arn
Format: '{"requestTime":"$context.requestTime","requestId":"$context.requestId"}'
GwLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: /aws/apigateway/gw-ws-loggroup
RetentionInDays: 7

Export and ImportValue in another stack under sub

I am trying to get a value from one stack to another using the below syntax.
stack one-
Outputs:
CompRestAPI:
Description: Rest Api Id
Value: !Ref CompRestAPI
Export:
Name: 'CompRestAPI'
Stack two -
CompRestApiWaf:
Type: AWS::WAFv2::WebACLAssociation
DependsOn: CompApiGatewayStage
Properties:
RestApiId: !ImportValue 'CompRestAPI'
ResourceArn: !Sub 'arn:aws:apigateway:${REGION}:/${RestApiId}/${STAGENAME}-apistage'
WebACLArn: !Ref WafId
I am able to get the values for other resources using 1st syntax, but I am not able to get the value for RestApiId under !Sub
RestApiId: !ImportValue 'CompRestAPI'
ResourceArn: !Sub 'arn:aws:apigateway:${REGION}:/${RestApiId}/apistage'
So is there any way to use !ImportValue under !Sub condition?
I tried it using below code, validation is pass but still showing me an error
Error reason: The ARN isn't valid. A valid ARN begins with arn: and includes other information separated by colons or slashes., field: RESOURCE_ARN, parameter:
CompRestApiWaf:
Type: AWS::WAFv2::WebACLAssociation
DependsOn: CompApiGatewayStage
Properties:
ResourceArn: !Sub 'arn:aws:apigateway:${REGION}:/{!ImportValue CompRestAPI}/stages/apistage'
WebACLArn: !Ref WafId
I am done with it using Fn::join:
SourceArn:
Fn::Join:
- ""
- - 'arn:aws:execute-api:'
- !Ref AWS::Region
- ':'
- !Ref AWS::AccountId
- ':'
- !Ref ApiGatewayRestApiResource
- '/*'
this should work
ResourceArn: !Sub
- 'arn:aws:apigateway:${REGION}:/${CompRestAPI}/stages/apistage'
- CompRestAPI: !ImportValue CompRestAPI
you can expand the second parameter to have multiple keys for multiple imports like so
SecretString: !Sub
- 'postgres://${username}:${password}#${dbhost}:${dbport}/${dbname}'
- username: !Ref 'DBUser'
password: !Ref 'DBPassword'
dbhost: !Ref DbMasterDnsEntry
dbport: !GetAtt AuroraPgCluster.Endpoint.Port
dbname: !Ref 'DBName'

Getting Fn::GetAtt error in the AWS SAM template

I have declared the SNS topic and Subscription like below in my AWS Serverless Application Model template :-
MyTopic:
Type: AWS::SNS::Topic
Properties:
DisplayName: !Sub 'test-${Environment}-${AWS::AccountId}-${AWS::Region}'
Tags:
- Key: Environment
Value: !FindInMap [Environment, FullForm, !Ref Environment]
TopicName: !Sub 'test-${Environment}-${AWS::AccountId}-${AWS::Region}'
MySubscription:
Type: AWS::SNS::Subscription
Properties:
Endpoint: !Ref SubscriptionEndPoint
Protocol: !Ref SubscriptionProtocol
Region: !Ref 'AWS::Region'
TopicArn: !Ref MyTopic
And then using the SNS Topic ARN in my Lambda function's environment as following in the same template file :-
MyLambda:
Type: AWS::Serverless::Function
Properties:
Environment:
Variables:
RUNTIME_SNS_TOPIC_ARN: !GetAtt MyTopic.Arn
Outputs (in SAM template):-
MyTopic:
Description: SNS Topic for the Ingest to send notification to
Export:
Name: !Sub
- ${ExportPrefix_}:${AWS::Region}:MyTopic
- ExportPrefix_: !If
- HasExportPrefix
- !Join ['-', [!Ref ExportPrefix, !Ref Environment]]
- !Join ['-', [!Select [0, !Split ["-", !Ref "AWS::StackName"]], !Ref Environment]]
Value: !Sub "${MyTopic.Arn}:${MyTopic.Version.Version}"
MySubscription:
Description: Subscription to get messages from a topic
Export:
Name: !Sub
- ${ExportPrefix_}:${AWS::Region}:MySubscription
- ExportPrefix_: !If
- HasExportPrefix
- !Join ['-', [!Ref ExportPrefix, !Ref Environment]]
- !Join ['-', [!Select [0, !Split ["-", !Ref "AWS::StackName"]], !Ref Environment]]
Value: !Sub "${MySubscription.Arn}:${MySubscription.Version.Version}"
However, I'm getting following error :-
13:30:30 Error: Failed to create changeset for the stack: my-stack, ex: Waiter ChangeSetCreateComplete failed: Waiter encountered a terminal failure state Status: FAILED. Reason: Template error: resource MyTopic does not support attribute type Arn in Fn::GetAtt
An AWS::SNS:Topic returns the ARN when you use Ref
Check out the Docs on the return values.
Try with
MyLambda:
Type: AWS::Serverless::Function
Properties:
Environment:
Variables:
RUNTIME_SNS_TOPIC_ARN: !Ref MyTopic # Using !Ref
Recommend trying the CloudFormation Linter in VSCode to see some of these errors inline while authoring templates:
[cfn-lint] E1010: Invalid GetAtt MyTopic.Arn for resource MyLambda
[cfn-lint] E1019: Parameter MyTopic.Arn for Fn::Sub not found at Outputs/MyTopic/Value/Fn::Sub
[cfn-lint] E1019: Parameter MyTopic.Version.Version for Fn::Sub not found at Outputs/MyTopic/Value/Fn::Sub
[cfn-lint] E1019: Parameter MySubscription.Arn for Fn::Sub not found at Outputs/MySubscription/Value/Fn::Sub
[cfn-lint] E1019: Parameter MySubscription.Version.Version for Fn::Sub not found at Outputs/MySubscription/Value/Fn::Sub
It'll also point out that Value needs to be indented less in the Outputs
AWS::SNS::Topic return values
AWS::SNS::Subscription

Cloudformation - Type: "AWS::ApiGateway::Method" returns {"message": "Internal server error"}

I get {"message": "Internal server error"} return from AWS API gateway when I write a Cloudformation template. Everything works well if I configure them on AWS console.
curl https://abcdefgh.execute-api.ap-southeast-1.amazonaws.com/demo/getitems
{"message": "Internal server error"}
I check all parts in the CF template and I think the problem is in "AWS::ApiGateway::Method". All configuration/parameters are the same between CF template and AWS console ( I checked them on console). When I delete the method created by CF, re-create and re-deploy it manually, it works.
I believe that "AWS::Lambda::Permission" works because I see it in Resource-based policy.
Does anyone have a solution to this problem? Thank you in advance.
The CF template:
apigwGETMethod:
DependsOn:
- apiResourceGET
- lambdaFunction3
Type: "AWS::ApiGateway::Method"
Properties:
AuthorizationType: "NONE"
HttpMethod: "GET"
ResourceId: !Ref apiResourceGET
RestApiId: !Ref apiGateway
Integration:
IntegrationHttpMethod: "GET"
Type: "AWS"
Credentials: !GetAtt ServerlessIAMRole.Arn
Uri: !Sub
- "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${lambdaArn}/invocations"
- lambdaArn: !GetAtt lambdaFunction3.Arn
IntegrationResponses:
- ResponseTemplates:
"application/json": ""
StatusCode: 200
MethodResponses:
- ResponseModels:
"application/json": "Empty"
StatusCode: 200
apiGatewayDeployment:
Type: "AWS::ApiGateway::Deployment"
DependsOn:
- apiGatewayGETMethod
Properties:
RestApiId: !Ref apiGateway
StageName: !Ref apiGatewayStageName
lambdaFunction3:
DependsOn:
- ServerlessIAMRole
Type: "AWS::Serverless::Function"
Properties:
FunctionName: !Ref lambdaFunction3Name
Handler: lambda_function3.lambda_handler
Description: "get all items from DynamoDB table"
Runtime: python3.6
CodeUri: .
Role: !GetAtt ServerlessIAMRole.Arn
lambda3ApiGatewayInvoke:
DependsOn:
- lambdaFunction3
- apiGatewayGETMethod
Type: "AWS::Lambda::Permission"
Properties:
Action: "lambda:InvokeFunction"
FunctionName: !GetAtt lambdaFunction3.Arn
Principal: "apigateway.amazonaws.com"
SourceArn: !Sub "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${apiGateway}/*"

Nested Fn::ImportValue in Fn::Sub not working for SAM template

Description:
I am trying to define Serverless API resource. But having trouble in defining location of swagger specification file using function ImportValue.
Steps to reproduce the issue:
I am not able to define AWS::Serverless::Api resource having nested function ImportValue in Location. I have tried following three ways, none of them work.
Note: Stack parameters are defined properly and export value from other stack exists. Not showing them here for brevity reason.
ApiGatewayApi:
Type: AWS::Serverless::Api
Properties:
Name: !Sub ${AWS::StackName}-API
StageName: !Ref ApiGatewayStageName
DefinitionBody:
'Fn::Transform':
Name: 'AWS::Include'
Parameters:
Location:
Fn::Sub:
- s3://${BucketName}/${SwaggerSpecificationS3Key}
- BucketName:
Fn::ImportValue:
!Sub "${EnvironmentName}-dist-bucket-${AWS::Region}"
ApiGatewayApi:
Type: AWS::Serverless::Api
Properties:
Name: !Sub ${AWS::StackName}-API
StageName: !Ref ApiGatewayStageName
DefinitionBody:
'Fn::Transform':
Name: 'AWS::Include'
Parameters:
Location:
Fn::Sub:
- s3://${BucketName}/${SwaggerSpecificationS3Key}
- BucketName:
!ImportValue 'dev-dist-bucket-us-east-1'
ApiGatewayApi:
Type: AWS::Serverless::Api
Properties:
Name: !Sub ${AWS::StackName}-API
StageName: !Ref ApiGatewayStageName
DefinitionBody:
'Fn::Transform':
Name: 'AWS::Include'
Parameters:
Location:
Fn::Sub:
- s3://${BucketName}/${SwaggerSpecificationS3Key}
- BucketName:
Fn::ImportValue: 'dev-dist-bucket-us-east-1'
Cloudformation shows following error.
FAILED - The value of parameter Location under transform Include must
resolve to a string, number, boolean or a list of any of these.
However, if I do not use ImportValue it works with a nested Fn::Sub
ApiGatewayApi:
Type: AWS::Serverless::Api
Properties:
Name: !Sub ${AWS::StackName}-API
StageName: !Ref ApiGatewayStageName
DefinitionBody:
'Fn::Transform':
Name: 'AWS::Include'
Parameters:
Location:
Fn::Sub:
- s3://${BucketName}/${SwaggerSpecificationS3Key}
- BucketName:
Fn::Sub: dist-bucket-${EnvironmentName}-${AWS::Region}
Is it because of Fn::Transform or AWS::Include?