Thing Types in CloudFormation template - aws-cloudformation

From the documentation, there is a syntax for creating things in AWS IoT but I can't find how to connect it to Things Type. Is it possible to write it like this?
AWSTemplateFormatVersion: "2010-09-09"
Resources:
MyThing:
Type: "AWS::IoT::Thing"
Properties:
ThingName: "coffeemachine-12"
ThingType: "coffeemachine"
AttributePayload:
Attributes:
temp: "celcius"
How do I configure/create AWS IoT Thing Types in AWS CloudFormation template?

You can't currently manage thing types via CloudFormation. You can, however, reference existing thing types when creating things.
The semantics of thing types don't lend themselves to automation via CloudFormation. For example :
They are immutable
Deletion requires deprecation, followed by a 5-minute cool down period.
This is undoubtedly why they aren't supported by CloudFormation.

Are you asking about how to make ThingType configurable when updating the CloudFormation stack?
If so, you might want to do something like:
Parameters:
ThingType:
Description: 'Description for ThingType'
Type: String
Resources:
MyThing:
Type: "AWS::IoT::Thing"
Properties:
ThingName: "coffeemachine-12"
ThingType: !Ref ThingType
AttributePayload:
Attributes:
temp: "celcius"
basically, you declare ThingType as a parameter and add the reference to this variable when create your resources.
Hope that helps

Related

Using Fn::Sub with a common string in a Cloud Formation Template

I'm struggling a little with Fn::Sub and Fn::FindInMap in order to create a dynamic value for a resource.
I would like something in the mapping like
Mappings:
Mapping01:
common:
SyncName: "archive-uploader-${AWS::Region}-synchronisation-a2"
Then I'd like to use it something like
Name: !Sub !FindInMap [Mapping01, common, SyncName]
Which I know I can't do because the Sub function cannot take intrinsic functions at the String parameter. But I cannot see a neat way to do this. At the moment I just use Sub and the hardcoded string where I need it.
I'd prefer to have a single place for the string and then use it with Sub where I need it. How can I do that in a CFT?
I don't want to have a large map that just varies the name's region. That's what most of the documentation shows.
As you pointed out you can't do this in plain CFN. Your only options to work around this is through development of CFN macro or custom resource.
Alternative is simply not to use CFN, there are far superior IaC tools (terraform, AWS CDK), pre-process all templates before applying them, or keep hardcoding these values in your templates.

Cloudformation Export Outputs / Input parameters cross-account

I have a parent cloudformation script that launches two child cloudformation scripts, each in separate accounts. Is there a way I can get outputs from one of the child stacks and use them as inputs in the other child stack, all done from this parent template? The user should be able to input different account numbers as a parameter as this script will be run across several different accounts.
Parent template sample code:
Resources:
ChildAccountA:
Type: Custom::StackA
Properties:
ServiceToken: example
TemplateURL: https://s3.amazonaws.com/exampleA
ChildAccountB:
Type: Custom::StackB
Properties:
ServiceToken: example
TemplateURL: https://s3.amazonaws.com/exampleB
If I correctly understand, then yes. Your custom resource lambda should return the outputs to the parent stack.
The custom lambda obviously needs to have correct permissions to be able to deploy stacks in other accounts and get their outputs to be returned to the parent stack.
Since you haven't written if there are any issues with development of custom resources, I will just put the link to AWS crhelper. The helper simplify development of custom resources and returning results to it.
Just for completeness, for deployment of stacks in different regions and accounts, StackSets.

CFT to CDK migration - how to reference CFT created objects from CDK code

I read this description on how to import a Cloud Formation Template (CFT) into your CDK code.
This is interesting but there doesn't appear to be a way to use any of the objects created by the CFT in the CDK code. So if for example you have an apigateway or appsync instance defined in CFT and want to use the really nice mechanism for creating Lambda functions in CDK, there doesn't appear to be a way to attach the Lambda function to the apigateway or appsync instance.
This means it's a complete fork lift upgrade to move from CFT to CDK if there's no way to reference CFT objects from the CDK. That doesn't sound right though, it would be a significant barrier to adoption.
How would one reference a CFT-created object in CDK code? Here are four possible examples, a solution to any one of them should be able to answer the question by revealing the pattern of code to be used:
Lambda function created by CDK uses a DynamoDB table created in a CFT
Lambda function created by CDK attached to an API gateway that was created in a CFT
Lambda function created by CDK attached to an appsync resolver created in a CFT
Or any other example where a CFT object is used by CDK code.
I note the documentation tells you how to get an an ARN, but doesn't tell you what you can do with that ARN in CDK code.
The second part of the blog series that you referenced gives two examples, one for VPC and one for ALB.
How can I reference existing resources?
Most of the time it’s necessary to reference existing resources which have already been created in your AWS account. Either by another CloudFormation Stack or by another CDK App.
To do that, many of the CDK Constructs support fromXXX() methods.
Example VPC
const vpc = Vpc.fromLookup(this, 'MyExistingVPC', { isDefault: true });
Example ALB
const existingAlb = elb.ApplicationLoadBalancer.fromApplicationLoadBalancerAttributes(this, "ImportedALB", {
loadBalancerArn: "arn:aws:elasticloadbalancing:eu-west-1:123456789012...",
securityGroupId: "MyAlbSecurityGroupA12345AB"
});
You can then use the existing resource references as objects in your CDK code. Here is an example using the VPC.
const fn = new lambda.Function(this, 'MyFunction', {
runtime: lambda.Runtime.NODEJS_10_X,
handler: 'index.handler',
code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')),
vpc: vpc
});
Some APIs explicitly support referencing an existing or to-be-created instance. Some do not. So the asked-for use cases cannot be all supported. Here's the status of the list and the support as it currently stands, followed by a full example for one that works. Alas, the most simple stuff works and the most complex constructs such as ApiGateway and AppSync do not. This means fork-lift upgrade.
Note: AWS might fix this issue, see for updates
Lambda function created by CDK uses a DynamoDB table created in a CFT - Works. See example below.
Lambda function created by CDK attached to an API gateway that was created in a CFT - ApiGateway has a fromXXX function but doesn't resolve to a useful object. See
Lambda function created by CDK attached to an appsync resolver created in a CFT - AppSync is in Public beta and does not have a fromXXX function. See
Example DynamoDB instance in CFT, add a lambda function that uses the table
const existingTemplate = new cdk.CfnInclude(this, "ExistingInfrastructure", {
template: yamlParse(fs.readFileSync("aws-stack.yaml").toString())
});
const ddbArn = cdk.Fn.getAtt("DynamoDBUserTable", "Arn"); // DynamoDBUserTable is a named element in aws-stack.yaml of type DynamoDB::Table
const userTable = dynamodb.Table.fromTableArn(this, 'importedTable', ddbArn.toString());
const handler = new lambda.Function(this, "UserGetHandler", {
runtime: lambda.Runtime.NODEJS_10_X, // So we can use async in user-get.js
code: lambda.Code.asset("resources"),
handler: "user-get.main",
});
userTable.grantReadWriteData(handler);

What is the package `unstructured` used for in k8s.io /apimachinery?

I could not understand what the package can do, the offical doc show nothing about unstructured. What the package used for ? Is it used for converting map[string]interface{} to K8S Obj ?
https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured
It looks like unstructured provides an interface to kubernetes objects, when you don't know object type upfront, i.e. dynamic package in client-go uses it extensively
As #kseniia-churiumova suggested it is used when you don't know the object type. Here is the use case to understand it better. Let us say your organisation has a policy that all Kubernetes object must have annotation "owner" with value pointing to email ID of a person or group. You have tasked with finding all the resources that violates this policy.
You can have a configuration file that has list of GroupVersionKind and use unstructured to query them. If a new type needs a check you can add to configuration without changing the code.
Note: This is just an example. In production you will have to use something like Gatekeeper that implements OPA specification to enforce policies.

Why does GetAttr not work on cloudformation template parameters?

Have a collection of cloudformation templates in a parent-child relationship and want to pass an AWS::IAM::Role into the parameters of a child stack and use GetAttr to get the Arn.
This fails validation because can only call GetAttr on resources, not on parameters.
Anyone know/guess why this is designed in this way?
It's not a problem as it can be worked around by just passing the Arn into the stack, I'm just curious really
What Fn::GetAttr and Parameters are trying to do in AWS CloudFormation is fundamentally different. As per AWS docs:
The intrinsic function Fn::GetAtt returns the value of an attribute
from a resource in the template.
[1] http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html
You can use the optional Parameters section to pass values into your
template when you create a stack. With parameters, you can create
templates that are customized each time you create a stack.
[2] http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html
I believe your confusion is stemming from the fact that you're trying to think of this in terms of the object-oriented/some other programming paradigm, where Resources and Parameters are some kind of objects and Fn::GetAttr is a generic function which retrieves the value of a reference that's passed in as an argument.
In my case, I wanted to access the resource attributes like ARN and Name in the nested stack. If I pass resource string and use GetAtt to get these, I dont need to pass them as two parameters. With this limitation, I had to pass them as two parameters.