Enforce tagging in ec2 - amazon-ec2

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"
]
}
}
}
]
}

Related

AWS Config unable to write to S3 bucket. Incorrect policy

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

Add extension to R4 Patient

How do I add the below to an R4 Patient?
"search": {
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/match-grade",
"valueCode": "certain"
}
],
"mode": "match",
"score": 1.0
}
The objects that were under stu2 and stu3 (I think) have been deprecated.
DSTU3 and Later
// Create an example patient
Patient patient = new Patient();
patient.addIdentifier().setUse(Identifier.IdentifierUse.OFFICIAL).setSystem("urn:example").setValue("7000135");
// Create an extension
Extension ext = new Extension();
ext.setUrl("http://example.com/extensions#someext");
ext.setValue(new DateTimeType("2011-01-02T11:13:15"));
// Add the extension to the resource
patient.addExtension(ext);
Full "response" json from patient match below (sample data, not real data !! )
{
"resourceType": "Bundle",
"id": "94897c77-4120-482f-bdb4-4c8b9a71ade1",
"meta": {
"versionId": "1",
"lastUpdated": "2020-11-24T08:45:49.445-05:00"
},
"type": "searchset",
"total": 1,
"link": [
{
"relation": "self",
"url": "http://wildfhir4.aegis.net/fhir4-0-0/Patient/$match?"
}
],
"entry": [
{
"fullUrl": "http://wildfhir4.aegis.net/fhir4-0-0/Patient/9126db824dcf4d5ab3f68e63bd5eaced",
"resource": {
"resourceType": "Patient",
"id": "9126db824dcf4d5ab3f68e63bd5eaced",
"meta": {
"versionId": "1",
"lastUpdated": "2020-09-03T09:03:28.193-04:00",
"tag": [
{
"system": "http://terminology.hl7.org/CodeSystem/v3-ActReason",
"code": "HTEST",
"display": "test health data"
}
]
},
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><table><tbody><tr><td>Name</td><td>Peter James \n <b>Chalmers</b> ("Jim") \n </td></tr><tr><td>Address</td><td>534 Erewhon, Pleasantville, Vic, 3999</td></tr><tr><td>Contacts</td><td>Home: unknown. Work: (03) 5555 6473</td></tr><tr><td>Id</td><td>MRN: 12345 (Acme Healthcare)</td></tr></tbody></table></div>"
},
"identifier": [
{
"use": "usual",
"type": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/v2-0203",
"code": "MR"
}
]
},
"system": "urn:oid:1.2.36.146.595.217.0.1",
"value": "12345",
"period": {
"start": "2001-05-06"
},
"assigner": {
"display": "Acme Healthcare"
}
}
],
"active": true,
"name": [
{
"use": "official",
"family": "Chalmers",
"given": [
"Peter",
"James"
]
},
{
"use": "usual",
"given": [
"Jim"
]
},
{
"use": "maiden",
"family": "Windsor",
"given": [
"Peter",
"James"
],
"period": {
"end": "2002"
}
}
],
"telecom": [
{
"use": "home"
},
{
"system": "phone",
"value": "(03) 5555 6473",
"use": "work",
"rank": 1
},
{
"system": "phone",
"value": "(03) 3410 5613",
"use": "mobile",
"rank": 2
},
{
"system": "phone",
"value": "(03) 5555 8834",
"use": "old",
"period": {
"end": "2014"
}
}
],
"gender": "male",
"birthDate": "1974-12-25",
"_birthDate": {
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/patient-birthTime",
"valueDateTime": "1974-12-25T14:35:45-05:00"
}
]
},
"deceasedBoolean": false,
"address": [
{
"use": "home",
"type": "both",
"text": "534 Erewhon St PeasantVille, Rainbow, Vic 3999",
"line": [
"534 Erewhon St"
],
"city": "PleasantVille",
"district": "Rainbow",
"state": "Vic",
"postalCode": "3999",
"period": {
"start": "1974-12-25"
}
}
],
"contact": [
{
"relationship": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/v2-0131",
"code": "N"
}
]
}
],
"name": {
"family": "du Marché",
"_family": {
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/humanname-own-prefix",
"valueString": "VV"
}
]
},
"given": [
"Bénédicte"
]
},
"telecom": [
{
"system": "phone",
"value": "+33 (237) 998327"
}
],
"address": {
"use": "home",
"type": "both",
"line": [
"534 Erewhon St"
],
"city": "PleasantVille",
"district": "Rainbow",
"state": "Vic",
"postalCode": "3999",
"period": {
"start": "1974-12-25"
}
},
"gender": "female",
"period": {
"start": "2012"
}
}
],
"managingOrganization": {
"reference": "Organization/1"
}
},
"search": {
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/match-grade",
"valueCode": "certain"
}
],
"mode": "match",
"score": 1.0
}
}
]
}
APPEND: I found this:
https://hapifhir.io/hapi-fhir/apidocs/hapi-fhir-structures-r4/org/hl7/fhir/r4/model/codesystems/MatchGrade.html
That extension isn't allowed on Patient. It's defined with a context of Bundle.entry.search. It's not a characteristic of the patient themselves, it's a characteristic of a particular entry in a search result based on a specific set of search criteria. The same Patient instance might well be a good result on one search and a poor result on a different search. So to add the extension, you'd have to add it on a 'search' object, not patient.
Ok.
Here it is. The primary objects were inner/nested objects under Bundle....thus why I didn't see them early. (example : Bundle.BundleEntrySearchComponent)
// a java example with the import statements. #shocking!
//import org.hl7.fhir.r4.model.Bundle;
//import org.hl7.fhir.r4.model.CodeType;
//import org.hl7.fhir.r4.model.Extension;
//import org.hl7.fhir.r4.model.Patient;
//import org.hl7.fhir.r4.model.codesystems.MatchGrade;
//import java.util.Collections;
Bundle innerBundle = new Bundle();
innerBundle.setType(Bundle.BundleType.SEARCHSET);
innerBundle.setTotal(1);
Patient pat = new Patient();
HumanName hn = new HumanName();
hn.setFamily("Smith");
p.setName(Collections.singletonList(hn));
Bundle.BundleEntrySearchComponent besc = new Bundle.BundleEntrySearchComponent();
besc.setScore(0.88);
besc.setMode(Bundle.SearchEntryMode.MATCH);
Bundle.BundleEntryComponent bec = new Bundle.BundleEntryComponent();
Extension matchGradeExtension = besc.addExtension();
matchGradeExtension.setUrl("http://hl7.org/fhir/StructureDefinition/match-grade");
matchGradeExtension.setValue(new CodeType(MatchGrade.PROBABLE.toCode()));
bec.setResource(pat);
bec.setSearch(besc);
innerBundle.setEntry(Collections.singletonList(bec));
Json looks like this:
{
"resourceType": "Bundle",
"type": "searchset",
"total": 1,
"entry": [
{
"resource": {
"resourceType": "Patient",
"name": [
{
"family": "Smith"
}
]
},
"search": {
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/match-grade",
"valueCode": "certain"
}
],
"mode": "match",
"score": 0.88
}
}
]
}

Vonk FHIR server Bundle validation issue

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.

Cloudformation - 'AWS_PROXY' currently only supports Lambda function

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"
]
]
}
}

Cloudformation IAM role timeout "resource did not stabilize"

I have a cloudformation template that experiences timeout during IAM role creation:
Role XXX is not stabilized
here is the resource in question:
"LambdaExecutionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": {
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
},
"Policies": [
{
"PolicyName": "WriteLogs",
"PolicyDocument": {
"Statement": {
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": {
"Fn::Join": ["", [
"arn:aws:logs:*:*:log-group:/aws/lambda/",
{
"Ref": "AWS::StackName"
},
"-*"
]]}
}
}
},
{
"PolicyName": "CreateStack",
"PolicyDocument": {
"Statement": {
"Effect": "Allow",
"Action": [
"cloudformation:CreateStack"
],
"Resource": "*"
}
}
}
]
}
}
Any ideas what I could be doing wrong?

Resources