Related
here is the template below. I am getting an Incorrect policy, unable to write to bucket. Please help
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Template for a startup company looking to move their services to the cloud",
"Resources": {
"ResumeConfigRecorder": {
"Type": "AWS::Config::ConfigurationRecorder",
"Properties": {
"Name": "ResumeConfigRecorder",
"RecordingGroup": {
"AllSupported": true
},
"RoleARN": "arn:aws:iam::451750859333:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig"
}
},
"ResumeConfigDeliveryChannel": {
"Type": "AWS::Config::DeliveryChannel",
"Properties": {
"ConfigSnapshotDeliveryProperties": {
"DeliveryFrequency": "Three_Hours"
},
"Name": "ResumeConfigDeliveryChannel",
"S3BucketName": "config-resumematch",
"S3KmsKeyArn": {
"Fn::GetAtt": [
"ConfigKey",
"Arn"
]
}
}
},
"ConfigBucket": {
"Type": "AWS::S3::Bucket",
"Properties": {
"AccessControl": "Private",
"BucketName": "config-resumematch",
"BucketEncryption": {
"ServerSideEncryptionConfiguration": [
{
"BucketKeyEnabled": true,
"ServerSideEncryptionByDefault": {
"KMSMasterKeyID": {
"Ref": "ConfigKey"
},
"SSEAlgorithm": "aws:kms"
}
}
]
},
"Tags": [
{
"Key": "Name",
"Value": "ConfigBucket"
}
]
}
},
"ConfigBucketPolicy": {
"Type": "AWS::S3::BucketPolicy",
"Properties": {
"Bucket": {
"Ref": "ConfigBucket"
},
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AWSConfigBucketPermissionsCheck",
"Effect": "Allow",
"Principal": {
"Service": "config.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::config-resumematch",
"Condition": {
"StringEquals": {
"AWS:SourceAccount": "451750859333"
}
}
},
{
"Sid": "AWSConfigBucketExistenceCheck",
"Effect": "Allow",
"Principal": {
"Service": "config.amazonaws.com"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::config-resumematch",
"Condition": {
"StringEquals": {
"AWS:SourceAccount": "451750859333"
}
}
},
{
"Sid": "AWSConfigBucketDelivery",
"Effect": "Allow",
"Principal": {
"Service": "config.amazonaws.com"
},
"Action": [
"s3:PutObject*"
],
"Resource": "arn:aws:s3:::config-resumematch/AWSLogs/451750859333/Config/",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control",
"AWS:SourceAccount": "451750859333"
}
}
}
]
}
}
},
"ConfigKey": {
"Type": "AWS::KMS::Key",
"Properties": {
"Description": "Key to encrypt config records in S3",
"Enabled": true,
"KeyPolicy": {
"Version": "2012-10-17",
"Id": "config-key-1",
"Statement": [
{
"Sid": "Enable IAM Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::451750859333:root"
},
"Action": "kms:",
"Resource": ""
},
{
"Sid": "Allow administration of the key",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::451750859333:user/ecargle"
},
"Action": [
"kms:Put",
"kms:Create*",
"kms:Describe*",
"kms:Enable*",
"kms:List*",
"kms:Get*",
"kms:Delete*"
],
"Resource": ""
},
{
"Sid": "Allow config to use KMS key",
"Effect": "Allow",
"Principal": {
"Service": "config.amazonaws.com"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt*"
],
"Resource": "*"
}
]
},
"KeySpec": "SYMMETRIC_DEFAULT",
"KeyUsage": "ENCRYPT_DECRYPT",
"Tags": [
{
"Key": "Name",
"Value": "ConfigKey"
}
]
}
},
"ConfigKeyAlias": {
"Type": "AWS::KMS::Alias",
"Properties": {
"AliasName": "alias/configKey",
"TargetKeyId": {
"Ref": "ConfigKey"
}
}
},
"ResumeConfigRuleEC2": {
"DependsOn" : "ResumeConfigRecorder",
"Type": "AWS::Config::ConfigRule",
"Properties": {
"ConfigRuleName": "ResumeMatchConfigRuleEC2",
"Description": "rule to monitor the configuration of AWS resources",
"Scope": {
"ComplianceResourceTypes": [
"AWS::EC2::Volume"
]
},
"Source": {
"Owner": "AWS",
"SourceIdentifier": "EC2_EBS_ENCRYPTION_BY_DEFAULT"
}
}
},
"ResumeConfigRuleS3": {
"DependsOn" : "ResumeConfigRecorder",
"Type": "AWS::Config::ConfigRule",
"Properties": {
"ConfigRuleName": "ResumeMatchConfigRuleS3",
"Description": "rule to monitor the configuration of AWS resources",
"Scope": {
"ComplianceResourceTypes": [
"AWS::S3::Bucket"
]
},
"Source": {
"Owner": "AWS",
"SourceIdentifier": "ELB_LOGGING_ENABLED"
}
}
},
"ResumeConfigRuleELB": {
"DependsOn" : "ResumeConfigRecorder",
"Type": "AWS::Config::ConfigRule",
"Properties": {
"ConfigRuleName": "ResumeMatchConfigRuleELB",
"Description": "rule to monitor the configuration of AWS resources",
"Scope": {
"ComplianceResourceTypes": [
"AWS::ElasticLoadBalancingV2::LoadBalancer"
]
},
"Source": {
"Owner": "AWS",
"SourceIdentifier": "ELB_LOGGING_ENABLED"
}
}
}
}
}
Tried to deploy the above template and got the Incorrect policy unable to write to bucket error
I am trying to create a SAM template (serverless.template) in visual studio to publish my API Gateway. I have a couple of errors being produced within the template validation (in Visual Studio) that I'm unable to resolve. When published, the stack deploys, but there is no usage plan(s) or api key(s) created (or rather, they are created but not viewable in the console, they come up as 'invalid reference' if you try to view them via Cloudformation > Resources, and they don't show up at all in the API Gateway console).
The errors are:
ServerlessRestApiDeployment26aad1646f is an unknown reference
"ServerlessRestApiProdStage": {
"Type": "AWS::ApiGateway::Stage",
"Properties": {
"DeploymentId": {
"Ref": "ServerlessRestApiDeployment26aad1646f"
},
"RestApiId": {
"Ref": "ServerlessRestApi"
},
"StageName": "Prod"
}
},
And
ServerlessRestApiProdStage is an invalid type for this reference
"APIGatewayHeartInHandKey": {
"Type": "AWS::ApiGateway::ApiKey",
"DependsOn": [
"ServerlessRestApi",
"ServerlessRestApiProdStage"
],
"Properties": {
"Name": "HeartInHandApiKey",
"Description": "Api Key for Heart In Hand",
"Enabled": true,
"GenerateDistinctId": true,
"StageKeys": [
{
"RestApiId": {
"Ref": "ServerlessRestApi"
},
"StageName": {
"Ref": "ServerlessRestApiProdStage"
}
}
]
}
},
The full SAM template shown below.
{
"AWSTemplateFormatVersion": "2010-09-09",
"Transform": "AWS::Serverless-2016-10-31",
"Description": "API Gateway to access InSite data-store",
"Resources": {
"Get": {
"Type": "AWS::Serverless::Function",
"Properties": {
"VpcConfig": {
"SecurityGroupIds": [
"sg-111a1476"
],
"SubnetIds": [
"subnet-3029a769",
"subnet-5ec0b928"
]
},
"Handler": "AWSServerlessInSiteDataGw::AWSServerlessInSiteDataGw.Functions::Get",
"Runtime": "dotnetcore2.0",
"CodeUri": "",
"MemorySize": 256,
"Timeout": 30,
"Role": null,
"Policies": [
"AWSLambdaBasicExecutionRole",
"AWSLambdaVPCAccessExecutionRole",
"AmazonSSMFullAccess"
],
"Events": {
"PutResource": {
"Type": "Api",
"Properties": {
"Path": "/",
"Method": "GET"
}
}
}
}
},
"GetTableBasic": {
"Type": "AWS::Serverless::Function",
"Properties": {
"VpcConfig": {
"SecurityGroupIds": [
"sg-111a1476"
],
"SubnetIds": [
"subnet-3029a769",
"subnet-5ec0b928"
]
},
"Handler": "AWSServerlessInSiteDataGw::AWSServerlessInSiteDataGw.Functions::GetTableBasic",
"Runtime": "dotnetcore2.0",
"CodeUri": "",
"MemorySize": 256,
"Timeout": 30,
"Role": null,
"Policies": [
"AWSLambdaBasicExecutionRole",
"AWSLambdaVPCAccessExecutionRole",
"AmazonSSMFullAccess"
],
"Events": {
"PutResource": {
"Type": "Api",
"Properties": {
"Path": "/tables/{tableid}/{columnid}",
"Method": "GET"
}
}
}
}
},
"GetColumnList": {
"Type": "AWS::Serverless::Function",
"Properties": {
"VpcConfig": {
"SecurityGroupIds": [
"sg-111a1476"
],
"SubnetIds": [
"subnet-3029a769",
"subnet-5ec0b928"
]
},
"Handler": "AWSServerlessInSiteDataGw::AWSServerlessInSiteDataGw.Functions::GetColumnList",
"Runtime": "dotnetcore2.0",
"CodeUri": "",
"MemorySize": 256,
"Timeout": 30,
"Role": null,
"Policies": [
"AWSLambdaBasicExecutionRole",
"AWSLambdaVPCAccessExecutionRole",
"AmazonSSMFullAccess"
],
"Events": {
"PutResource": {
"Type": "Api",
"Properties": {
"Path": "/list/columns/{tableid}",
"Method": "GET"
}
}
}
}
},
"GetTableList": {
"Type": "AWS::Serverless::Function",
"Properties": {
"VpcConfig": {
"SecurityGroupIds": [
"sg-111a1476"
],
"SubnetIds": [
"subnet-3029a769",
"subnet-5ec0b928"
]
},
"Handler": "AWSServerlessInSiteDataGw::AWSServerlessInSiteDataGw.Functions::GetTableList",
"Runtime": "dotnetcore2.0",
"CodeUri": "",
"MemorySize": 256,
"Timeout": 30,
"Role": null,
"Policies": [
"AWSLambdaBasicExecutionRole",
"AWSLambdaVPCAccessExecutionRole",
"AmazonSSMFullAccess"
],
"Events": {
"PutResource": {
"Type": "Api",
"Properties": {
"Path": "/list/tables",
"Method": "GET"
}
}
}
}
},
"PostClickCollectNotification": {
"Type": "AWS::Serverless::Function",
"Properties": {
"VpcConfig": {
"SecurityGroupIds": [
"sg-111a1476"
],
"SubnetIds": [
"subnet-3029a769",
"subnet-5ec0b928"
]
},
"Handler": "AWSServerlessInSiteDataGw::AWSServerlessInSiteDataGw.Functions::PostClickCollectNotification",
"Runtime": "dotnetcore2.0",
"CodeUri": "",
"MemorySize": 256,
"Timeout": 30,
"Role": null,
"Policies": [
"AWSLambdaBasicExecutionRole",
"AWSLambdaVPCAccessExecutionRole",
"AmazonSSMFullAccess"
],
"Events": {
"PutResource": {
"Type": "Api",
"Properties": {
"Path": "/datagw/general/webhook/ccnotify",
"Method": "POST"
}
}
}
}
},
"PostClickCollectStockUpdate": {
"Type": "AWS::Serverless::Function",
"Properties": {
"VpcConfig": {
"SecurityGroupIds": [
"sg-111a1476"
],
"SubnetIds": [
"subnet-3029a769",
"subnet-5ec0b928"
]
},
"Handler": "AWSServerlessInSiteDataGw::AWSServerlessInSiteDataGw.Functions::PostClickCollectStockUpdate",
"Runtime": "dotnetcore2.0",
"CodeUri": "",
"MemorySize": 256,
"Timeout": 30,
"Role": null,
"Policies": [
"AWSLambdaBasicExecutionRole",
"AWSLambdaVPCAccessExecutionRole",
"AmazonSSMFullAccess"
],
"Events": {
"PutResource": {
"Type": "Api",
"Properties": {
"Path": "/datagw/general/post/sohupdate",
"Method": "POST"
}
}
}
}
},
"GetTableResponse": {
"Type": "AWS::Serverless::Function",
"Properties": {
"VpcConfig": {
"SecurityGroupIds": [
"sg-111a1476"
],
"SubnetIds": [
"subnet-3029a769",
"subnet-5ec0b928"
]
},
"Handler": "AWSServerlessInSiteDataGw::AWSServerlessInSiteDataGw.Functions::GetTableResponse",
"Runtime": "dotnetcore2.0",
"CodeUri": "",
"MemorySize": 256,
"Timeout": 30,
"Role": null,
"Policies": [
"AWSLambdaBasicExecutionRole",
"AWSLambdaVPCAccessExecutionRole",
"AmazonSSMFullAccess"
],
"Events": {
"PutResource": {
"Type": "Api",
"Properties": {
"Path": "datagw/general/table/get/{tableid}",
"Method": "GET"
}
}
}
}
},
"ServerlessRestApi": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"Description":"This is a placeholder for the description of this web api",
"ApiKeySourceType":"HEADER",
"Body": {
"info": {
"version": "1.0",
"title": {
"Ref": "AWS::StackName"
}
},
"paths": {
"/list/tables": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetTableList.Arn}/invocations"
}
},
"responses": {}
}
},
"/list/columns/{tableid}": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetColumnList.Arn}/invocations"
}
},
"responses": {}
}
},
"datagw/general/table/get/{tableid}": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetTableResponse.Arn}/invocations"
}
},
"responses": {}
}
},
"/": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Get.Arn}/invocations"
}
},
"responses": {}
}
},
"/tables/{tableid}/{columnid}": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetTableBasic.Arn}/invocations"
}
},
"responses": {}
}
}
},
"swagger": "2.0"
}
}
},
"ServerlessRestApiProdStage": {
"Type": "AWS::ApiGateway::Stage",
"Properties": {
"DeploymentId": {
"Ref": "ServerlessRestApiDeployment26aad1646f"
},
"RestApiId": {
"Ref": "ServerlessRestApi"
},
"StageName": "Prod"
}
},
"CustomLambdaExecutionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
},
"Action": [
"sts:AssumeRole"
]
}
]
},
"Policies": [
{
"PolicyName": "lambdaAccessApiKeys",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"apigateway:GET"
],
"Resource": {
"Fn::Sub": [
"arn:aws:apigateway:ap-southeast-2::/apikeys/${__keyId__}",
{
"__keyId__": {
"Ref": "APIGatewayHeartInHandKey"
}
}
]
}
}
]
}
}
]
}
},
"GetApiKeyValueLambdaFunction": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"ZipFile": {
"Fn::Join": [
"\n",
[
"import json",
"import boto3",
"client = boto3.client('apigateway')",
"def lambda_handler(event, context):",
" response = client.get_api_key(",
" apiKey= event['apiKeyId'],",
" includeValue = True",
")",
" return {",
" 'statusCode': 200,",
" 'body': response['value']}"
]
]
}
},
"Handler": "index.lambda_handler",
"Runtime": "python3.6",
"Timeout": 30,
"Role": {
"Fn::GetAtt": [
"CustomLambdaExecutionRole",
"Arn"
]
}
}
},
"APIGatewayUsagePlanInternal": {
"Type": "AWS::ApiGateway::UsagePlan",
"Properties": {
"ApiStages": [
{
"ApiId": {
"Ref": "ServerlessRestApi"
},
"Stage": {
"Ref": "ServerlessRestApiProdStage"
}
}
],
"Description": "Internal Apps Usage Plan",
"UsagePlanName": "Insite-datagw-InternalAppPlan"
}
},
"APIGatewayUsagePlanExternal": {
"Type": "AWS::ApiGateway::UsagePlan",
"Properties": {
"ApiStages": [
{
"ApiId": {
"Ref": "ServerlessRestApi"
},
"Stage": {
"Ref": "ServerlessRestApiProdStage"
}
}
],
"Description": "External Apps Usage Plan",
"UsagePlanName": "InSite-datagw-ExternalAppPlan"
}
},
"APIGatewayHeartInHandKey": {
"Type": "AWS::ApiGateway::ApiKey",
"DependsOn": [
"ServerlessRestApi",
"ServerlessRestApiProdStage"
],
"Properties": {
"Name": "HeartInHandApiKey",
"Description": "Api Key for Heart In Hand",
"Enabled": true,
"GenerateDistinctId": true,
"StageKeys": [
{
"RestApiId": {
"Ref": "ServerlessRestApi"
},
"StageName": {
"Ref": "ServerlessRestApiProdStage"
}
}
]
}
},
"LinkHeartInHandKey": {
"Type": "AWS::ApiGateway::UsagePlanKey",
"Properties": {
"KeyId": {
"Ref": "APIGatewayHeartInHandKey"
},
"KeyType": "API_KEY",
"UsagePlanId": {
"Ref": "APIGatewayUsagePlanInternal"
}
}
},
"APIGatewayPricelineSiteKey": {
"Type": "AWS::ApiGateway::ApiKey",
"DependsOn": [
"ServerlessRestApi",
"ServerlessRestApiProdStage"
],
"Properties": {
"Name": "PricelineSiteApiKey",
"Description": "Api Key for Priceline Website",
"Enabled": true,
"GenerateDistinctId": true,
"StageKeys": [
{
"RestApiId": {
"Ref": "ServerlessRestApi"
},
"StageName": {
"Ref": "ServerlessRestApiProdStage"
}
}
]
}
},
"LinkPricelineSiteKey": {
"Type": "AWS::ApiGateway::UsagePlanKey",
"Properties": {
"KeyId": {
"Ref": "APIGatewayPricelineSiteKey"
},
"KeyType": "API_KEY",
"UsagePlanId": {
"Ref": "APIGatewayUsagePlanInternal"
}
}
}
},
"Outputs": {
"ApiURL": {
"Description": "API endpoint URL for Prod environment",
"Value": {
"Fn::Sub": "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
}
}
}
}
it looks like you're trying to use features of the AWS::Serverless::Api resource from SAM without defining an AWS::Serverless::Api in your template.
In order to fix the issues you've brought up, it looks like you need to:
Remove the ServerlessRestApiProdStage resource
Sam will generate this resource (and the deployment resource) for you if you use an AWS::Serverless::Api resource.
Convert your AWS::ApiGateway::RestApi resource into an AWS::Serverless::Api resource:
Remove ApiKeySourceType property and add "x-amazon-apigateway-api-key-source" : "HEADER", to the swagger,
Change the Type from AWS::ApiGateway::RestApi to AWS::Serverless::Api
"ServerlessRestApi": {
"Type": "AWS::Serverless::RestApi",
"Properties": {
"Description":"This is a placeholder for the description of this web api",
"Body": {
"info": {
"version": "1.0",
"title": {
"Ref": "AWS::StackName"
}
},
"x-amazon-apigateway-api-key-source" : "HEADER",
"paths": {
...
Created an IAM policy that should restrict user to now to allow ec2 instance creation when tags value not met
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowToDescribeAll",
"Effect": "Allow",
"Action": [
"ec2:Describe*"
],
"Resource": ""
},
{
"Sid": "AllowRunInstances",
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": [
"arn:aws:ec2:::image/",
"arn:aws:ec2:::snapshot/",
"arn:aws:ec2:::subnet/",
"arn:aws:ec2:::network-interface/",
"arn:aws:ec2:::security-group/",
"arn:aws:ec2:::key-pair/"
]
},
{
"Sid": "AllowRunInstancesWithRestrictions",
"Effect": "Allow",
"Action": [
"ec2:CreateVolume",
"ec2:RunInstances"
],
"Resource": [
"arn:aws:ec2:::volume/",
"arn:aws:ec2:::instance/"
],
"Condition": {
"StringEquals": {
"aws:RequestTag/shutdown": "true",
"aws:RequestTag/terminate": "true"
},
"ForAllValues:StringEquals": {
"aws:TagKeys": [
"shutdown",
"terminate"
]
}
}
},
{
"Sid": "AllowCreateTagsOnlyLaunching",
"Effect": "Allow",
"Action": [
"ec2:CreateTags"
],
"Resource": [
"arn:aws:ec2:::volume/",
"arn:aws:ec2:::instance/*"
],
"Condition": {
"StringEquals": {
"ec2:CreateAction": "RunInstances"
}
}
}
]
}
Please check with the policy simulator at https://policysim.aws.amazon.com/home/index.jsp?#
With the following policy, I'm able to confirm that it works:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowToDescribeAll",
"Effect": "Allow",
"Action": [
"ec2:Describe*"
],
"Resource": "*"
},
{
"Sid": "AllowRunInstances",
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": [
"arn:aws:ec2:*::image/*",
"arn:aws:ec2:*::snapshot/*",
"arn:aws:ec2:*:*:subnet/*",
"arn:aws:ec2:*:*:network-interface/*",
"arn:aws:ec2:*:*:security-group/*",
"arn:aws:ec2:*:*:key-pair/*"
]
},
{
"Sid": "AllowRunInstancesWithRestrictions",
"Effect": "Allow",
"Action": [
"ec2:CreateVolume",
"ec2:RunInstances"
],
"Resource": [
"arn:aws:ec2:*:*:volume/*",
"arn:aws:ec2:*:*:instance/*"
],
"Condition": {
"StringEquals": {
"aws:RequestTag/terminate": "true",
"aws:RequestTag/shutdown": "true"
},
"ForAllValues:StringEquals": {
"aws:TagKeys": [
"terminate",
"shutdown"
]
}
}
},
{
"Sid": "AllowCreateTagsOnlyLaunching",
"Effect": "Allow",
"Action": [
"ec2:CreateTags"
],
"Resource": [
"arn:aws:ec2:*:*:volume/*",
"arn:aws:ec2:*:*:instance/*"
],
"Condition": {
"StringEquals": {
"ec2:CreateAction": "RunInstances"
}
}
}
]
}
You may use something like this
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"ForAllValues:StringEquals": {
"aws:TagKeys": [
"Application",
"Environment"
]
},
"StringEqualsIfExists": {
"aws:RequestTag/Application": [
"app-01",
"app-02"
],
"aws:RequestTag/Environment": [
"development",
"production"
]
}
}
}
]
}
When posting the FHIR example that uses the ZIB for tobacco use to the Vonk FHIR server in a transaction, Vonk responds with an error.
Request body:
{
"type": "transaction",
"entry": [
{
"resource": {
"resourceType": "Observation",
"id": "medmij-bgz-tobaccouse-ts-01",
"meta": {
"profile": [
"http://nictiz.nl/fhir/StructureDefinition/zib-TobaccoUse"
]
},
"status": "final",
"code": {
"coding": [
{
"system": "http://snomed.info/sct",
"code": "365980008",
"display": "Finding of tobacco use and exposure (finding)"
}
]
},
"subject": {
"reference": "Patient/medmij-bgz-patient-ts-01",
"display": "Johan XXX_Helleman"
},
"effectivePeriod": {
"start": "1980",
"end": "1983"
},
"valueCodeableConcept": {
"coding": [
{
"system": "http://snomed.info/sct",
"code": "8517006",
"display": "Ex-smoker (finding)"
}
]
},
"component": [
{
"code": {
"coding": [
{
"system": "http://snomed.info/sct",
"code": "53661000146106",
"display": "Type of tobacco used (observable entity)"
}
]
},
"valueCodeableConcept": {
"coding": [
{
"system": "http://snomed.info/sct",
"code": "65568007",
"display": "Cigarette smoker (finding)"
}
]
}
},
{
"code": {
"coding": [
{
"system": "http://snomed.info/sct",
"code": "266918002",
"display": "Tobacco smoking consumption (observable entity)"
}
]
},
"valueQuantity": {
"value": "2",
"unit": "packs per week",
"system": "http://unitsofmeasure.org",
"code": "{packs}/wk"
}
},
{
"code": {
"coding": [
{
"system": "http://snomed.info/sct",
"code": "401201003",
"display": "Cigarette pack-years (observable entity)"
}
]
},
"valueQuantity": {
"value": "1",
"unit": "PackYears",
"system": "http://unitsofmeasure.org",
"code": "{PackYears}"
}
}
]
},
"request": {
"url": "Observation/medmij-bgz-tobaccouse-ts-01",
"method": "PUT"
}
}
],
"resourceType": "Bundle"
}
Response:
{
"resourceType": "OperationOutcome",
"id": "d230a0cd-5487-489b-8f19-098f66e55744",
"meta": {
"versionId": "ca7e8081-6557-4eba-9a9f-14df426a0ff2",
"lastUpdated": "2019-03-11T09:07:56.638+00:00"
},
"issue": [
{
"severity": "error",
"code": "invalid",
"details": {
"coding": [
{
"system": "http://hl7.org/fhir/dotnet-api-operation-outcome",
"code": "1008"
}
],
"text": "Value is not exactly equal to fixed value 'http://unitsofmeasure.org'"
},
"location": [
"Observation.component[2].value[0].system[0]"
]
},
{
"severity": "warning",
"code": "not-supported",
"details": {
"coding": [
{
"system": "http://hl7.org/fhir/dotnet-api-operation-outcome",
"code": "5003"
}
],
"text": "Argument is not supported"
},
"location": [
"/Observation"
]
},
{
"severity": "warning",
"code": "not-supported",
"details": {
"coding": [
{
"system": "http://hl7.org/fhir/dotnet-api-operation-outcome",
"code": "5003"
}
],
"text": "Argument is not supported"
},
"location": [
"/medmij-bgz-tobaccouse-ts-01"
]
}
]
}
It seems the error complains about an URL mismatch in the PackYears component, however, that is exactly using the url http://unitsofmeasure.org as indicated should be used in the error. Does anybody know if the request is wrong here or Vonk has an issue?
Notice that posting without a transaction to /Observation/ does NOT give an error but completes successfully.
Also notice that the /Bundle/$validate request for the same bundle does NOT indicate any errors, but responds with The operation was successful.
We are using Vonk 1.1.0 and have configured it to use a SQL Server database.
The error is in Vonk. I can reproduce it with Vonk version 1.1.0. We will release a new version of Vonk next week, where this has been resolved.
I have the following error when I want to create a stack with cloudformation:
The following resource(s) failed to create: [ApiSyncLogsPost]. . Rollback requested by user.
CREATE_FAILED AWS::ApiGateway::Method ApiSyncLogsPost Integrations of type 'AWS_PROXY' currently only supports Lambda function and Firehose stream invocations. (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException; Request ID: 8bff48b0-93e4-11e8-a183-5de2b976f282)
I didn't find anything relevant regarding this error on google, when I search about it I just get a lot of AWS cloudformation documentation.
What I think is happening is that ApiSyncLogsPost resource is not defined properly, but the examples I found on the internet are similar.
What needs to be changed to solve that error?
Here is the cloudformation json:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Metadata": {
"AWS::CloudFormation::Designer": {
"a73e3686-2291-49a2-b052-565c5f85a9c9": {
"size": {
"width": 60,
"height": 60
},
"position": {
"x": 270,
"y": 120
},
"z": 2,
"parent": "d68e59d4-72c0-425a-9b7b-227cbac3252d",
"embeds": []
},
"0665ec07-964b-4c90-86c5-5f7731cece7b": {
"size": {
"width": 60,
"height": 60
},
"position": {
"x": 420,
"y": 120
},
"z": 1,
"embeds": []
},
"d68e59d4-72c0-425a-9b7b-227cbac3252d": {
"size": {
"width": 300,
"height": 240
},
"position": {
"x": 60,
"y": 90
},
"z": 1,
"embeds": [
"a73e3686-2291-49a2-b052-565c5f85a9c9",
"2cefafdd-86fd-4cbe-b42e-c638a8c23a19"
],
"iscontainedinside": [
"a86c6b83-5254-4848-943e-db6e35f09bf6"
]
},
"2cefafdd-86fd-4cbe-b42e-c638a8c23a19": {
"size": {
"width": 60,
"height": 60
},
"position": {
"x": 60,
"y": 120
},
"z": 2,
"parent": "d68e59d4-72c0-425a-9b7b-227cbac3252d",
"embeds": [],
"iscontainedinside": [
"d68e59d4-72c0-425a-9b7b-227cbac3252d",
"d68e59d4-72c0-425a-9b7b-227cbac3252d",
"a86c6b83-5254-4848-943e-db6e35f09bf6"
]
},
"a86c6b83-5254-4848-943e-db6e35f09bf6": {
"size": {
"width": 330,
"height": 330
},
"position": {
"x": 510,
"y": 90
},
"z": 1,
"embeds": [
"66745c5a-f3ad-4b8c-b575-e90d73cbf19b",
"cf340921-6a8b-45f2-8a2a-14ffb0e537e8",
"925587cf-52b3-4507-9131-6be6777905fe"
]
},
"66745c5a-f3ad-4b8c-b575-e90d73cbf19b": {
"size": {
"width": 60,
"height": 60
},
"position": {
"x": 540,
"y": 150
},
"z": 2,
"parent": "a86c6b83-5254-4848-943e-db6e35f09bf6",
"embeds": [],
"iscontainedinside": [
"a86c6b83-5254-4848-943e-db6e35f09bf6"
]
},
"cf340921-6a8b-45f2-8a2a-14ffb0e537e8": {
"size": {
"width": 60,
"height": 60
},
"position": {
"x": 680,
"y": 200
},
"z": 2,
"parent": "a86c6b83-5254-4848-943e-db6e35f09bf6",
"embeds": [],
"iscontainedinside": [
"a86c6b83-5254-4848-943e-db6e35f09bf6"
]
},
"925587cf-52b3-4507-9131-6be6777905fe": {
"size": {
"width": 60,
"height": 60
},
"position": {
"x": 540,
"y": 270
},
"z": 2,
"parent": "a86c6b83-5254-4848-943e-db6e35f09bf6",
"embeds": [],
"iscontainedinside": [
"a86c6b83-5254-4848-943e-db6e35f09bf6"
],
"dependson": [
"2cefafdd-86fd-4cbe-b42e-c638a8c23a19"
]
}
}
},
"Parameters": {
"DatabaseUrl": {
"Description": "DATABASE_URL taken from elastic bean. Example: postgres://my_own_user:my_own_access#my_own_link.rds.amazonaws.com:PORT/my_database_name",
"Type": "String"
},
"LogentriesToken": {
"Description": "",
"Type": "String"
},
"RedisUrl": {
"Description": "",
"Type": "String"
},
"DeploymentStage": {
"Description": "",
"Type": "String",
"Default": "staging"
},
"StackResourcePrefix": {
"Description": "The name will be used to create all the resources that belongs to the same stack.",
"Default": "StagingSyncLogs",
"Type": "String"
}
},
"Resources": {
"ErrorCfn": {
"Type": "AWS::ApiGateway::Model",
"Properties": {
"ContentType": "application/json",
"Name": "ErrorCfn",
"RestApiId": {
"Ref": "SyncLogsApi"
},
"Schema": {
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Error Schema",
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
},
"Metadata": {
"AWS::CloudFormation::Designer": {
"id": "cf340921-6a8b-45f2-8a2a-14ffb0e537e8"
}
}
},
"UserPropertyModel": {
"Type": "AWS::ApiGateway::Model",
"Properties": {
"ContentType": "application/json",
"Name": "UserPropertyModel",
"RestApiId": {
"Ref": "SyncLogsApi"
},
"Schema": {
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "UserPropertyModel",
"type": "object",
"properties": {
"Name": {
"type": "string"
}
}
}
},
"Metadata": {
"AWS::CloudFormation::Designer": {
"id": "66745c5a-f3ad-4b8c-b575-e90d73cbf19b"
}
}
},
"LambdaExecutionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
},
"Action": [
"sts:AssumeRole"
]
}
]
},
"Path": "/",
"Policies": [
{
"PolicyName": "PolicyNameForLambdaRole",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction"
],
"Resource": [
"*"
]
},
{
"Sid": "2",
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"*"
]
}
]
}
}
],
"RoleName": {
"Fn::Join": [
"_",
[
{
"Ref": "StackResourcePrefix"
},
"PostgresCron",
"Role"
]
]
}
},
"Metadata": {
"AWS::CloudFormation::Designer": {
"id": "0665ec07-964b-4c90-86c5-5f7731cece7b"
}
}
},
"SyncLogsLambda": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": "myBucket456464",
"S3Key": "myCode34535.zip"
},
"Environment": {
"Variables": {
"DATABASE_URL": {
"Ref": "DatabaseUrl"
},
"LOGENTRIES_TOKEN": {
"Ref": "LogentriesToken"
},
"REDIS_URL": {
"Ref": "RedisUrl"
}
}
},
"Tags": [
{
"Key": "DeploymentStage",
"Value": {
"Ref": "DeploymentStage"
}
}
],
"FunctionName": {
"Fn::Join": [
"",
[
{
"Ref": "StackResourcePrefix"
},
"_",
"lambda"
]
]
},
"Description": "Lambda function for syncing logs to logentries",
"Handler": "index.handler",
"Runtime": "nodejs6.10",
"MemorySize": 128,
"Timeout": 300,
"Role": {
"Fn::GetAtt": [
"LambdaExecutionRole",
"Arn"
]
}
},
"Metadata": {
"AWS::CloudFormation::Designer": {
"id": "a73e3686-2291-49a2-b052-565c5f85a9c9"
}
}
},
"ProxyResource": {
"Type": "AWS::ApiGateway::Resource",
"Properties": {
"RestApiId": {
"Ref": "SyncLogsApi"
},
"ParentId": {
"Fn::GetAtt": [
"SyncLogsApi",
"RootResourceId"
]
},
"PathPart": "synclogs"
},
"Metadata": {
"AWS::CloudFormation::Designer": {
"id": "d68e59d4-72c0-425a-9b7b-227cbac3252d"
}
}
},
"SyncLogsApi": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"Name": "Sync logs Api",
"Description": "Sync logs when this link is called.",
"FailOnWarnings": true
},
"Metadata": {
"AWS::CloudFormation::Designer": {
"id": "a86c6b83-5254-4848-943e-db6e35f09bf6"
}
}
},
"ApiSyncLogsPost": {
"Type": "AWS::ApiGateway::Method",
"Properties": {
"ResourceId": {
"Ref": "ProxyResource"
},
"RestApiId": {
"Ref": "SyncLogsApi"
},
"HttpMethod": "POST",
"AuthorizationType": "NONE",
"Integration": {
"Type": "AWS_PROXY",
"IntegrationHttpMethod": "POST",
"Uri": {
"Fn::Join": [
"",
[
"arn:aws:apigateway:",
{
"Ref": "AWS::Region"
},
":lambda:path/2015-03-31/functions/",
{
"Fn::GetAtt": [
"SyncLogsLambda",
"Arn"
]
},
"/synclogs"
]
]
}
},
"MethodResponses": [
{
"ResponseModels": {
"application/json": {
"Ref": "UserPropertyModel"
}
},
"StatusCode": 200
},
{
"ResponseModels": {
"application/json": {
"Ref": "ErrorCfn"
}
},
"StatusCode": 404
},
{
"ResponseModels": {
"application/json": {
"Ref": "ErrorCfn"
}
},
"StatusCode": 500
}
]
},
"Metadata": {
"AWS::CloudFormation::Designer": {
"id": "2cefafdd-86fd-4cbe-b42e-c638a8c23a19"
}
}
},
"RestApiDeployment": {
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"RestApiId": {
"Ref": "SyncLogsApi"
},
"StageName": "Staging"
},
"DependsOn": [
"ApiSyncLogsPost"
],
"Metadata": {
"AWS::CloudFormation::Designer": {
"id": "925587cf-52b3-4507-9131-6be6777905fe"
}
}
}
}
}
The error is due to improper value for Integration.Uri in the ApiSyncLogsPost resource. The Uri should have the form:
arn:aws:apigateway:{region}:{subdomain.service|service}:path|action/{service_api}
Example:
arn:aws:apigateway:eu-west-1:lambda:path/2015-03-31/functions/arn:aws:lambda:eu-west-1:012345678901:function:MyLambda/invocations
In your case, the string "/synclogs" at the end which should actually be "/invocations"
The following Integration.Uri for ApiSyncLogsPost should fix the issue:
{
"Uri": {
"Fn::Join": [
"",
[
"arn:aws:apigateway:",
{
"Ref": "AWS::Region"
},
":lambda:path/2015-03-31/functions/",
{
"Fn::GetAtt": [
"SyncLogsLambda",
"Arn"
]
},
"/invocations"
]
]
}
}