I am trying to setup cloudwatch alarms using the auto-generated metrics via CDK on a CfnDeliveryStream which is a part of #aws-cdk/aws-kinesisfirehose. From the documentation here, https://docs.aws.amazon.com/cdk/api/latest/docs/#aws-cdk_aws-kinesisfirehose.CfnDeliveryStream.html it looks like there is no metric() that can be used for this. However the DeliveryStream class in the same library has that method, is it possible to leverage that?
There are basically two strategies:
Use the DeliveryStream construct primarily (let mystream = new DeliveryStream(...)) and then modify the underlying CfnDeliverystream by accessing the underlying Cfn object ( let cfnstream = mystream.node.defaultChild) and then modify that construct.
Create the Cfn stream first and then convert it to a DeliveryStream by using the DeliveryStream.fromDeliveryStreamAttributes(scope, id, attrs) or fromDeliveryStreamArn(scope, id, attrs) or fromDeliveryStreamName(scope, id, attrs). These methods have the downside that this way of using the construct often does limit the amount of properties and methods that can be used properly, since it does not import all info of the original stream. fromDeliveryStreamAttributes is the most complete one but it's quite verbose since you need to pass all attributes that you need to use.
Related
I'm importing an ARN from another stack with the cdk.Fn.importValue method. This works fine if I know that the output value is always present, but I don't know how to handle the case when the value I try to import is optional.
How can I get something similar to: (checking if the value exists before importing it)
if(value exists) {
cdk.Fn.importValue("value")
}
AFAIK there currently is no way in CDK to perform a lookup of a CloudFormation exports during synthesis time.
If you don't want to fiddle around with performing CloudFormation API calls with the aws-sdk before creating the CDK stack, in my opinion the most elegant way to share conditional values between stacks, is to use SSM parameters instead of CloudFormation exports.
SSM parameters can be looked up during synthesis time. See docs: https://docs.aws.amazon.com/cdk/v2/guide/get_ssm_value.html
So, with StringParameter.valueFromLookup you are then able to only use the value if it exists (IIRC the method throws an error if the parameter doesn't exist, so try-catch is your friend here, but not 100% sure).
I am putting together a POC to see if AWS step-functions would be a good choice to orchestrate a flow we have.
the basic idea is that we will have a flow with a number of steps in and then at various points we will trigger a aub-workflow (a separate state machine). I am comfortable with how to do that.
however, we will have multiple versions of each sub-workflow (which would each exist as a separate set of steps), and depending on where the initial request came from we would want the flow to trigger a specific version of the sub-workflow.
I thought this might be possible by naming each version of the workflow in a way that would enable us to have a lambda that could build up the Arn of the state machine to trigger based on the incoming request, store it as a variable and pass that variable into the statemachineArn field, something like this...
"Parameters": {
"StateMachineArn": $.arnToTrigger
but when I tried this it didn't work. is anyone able to advise me whether or not what I want to do is possible? I would like to avoid using a choice step as there will be a lot of possibilities and one of the requirements is to add more without having to alter the step functions config
Would be better with more code example, but I guess that you should check the way you are passing the parameter from the previous step.
In this case you wrote:
"Parameters": { "StateMachineArn": $.arnToTrigger
But you should put a ".$" before the key, like:
"Parameters": { "StateMachineArn.$": $.arnToTrigger
This could be causing your issues.
Is there a way to store variables in Cloudformation?
I've created a resource with a name which is a stage specific name in the following form:
DeliveryStreamName: {'Fn::Sub': ['firehose-events-${Stage}', 'Stage': {'Ref' : 'Stage' }]}
Now if I've to create a cloudwatch alarm on that resource I'm again following the same pattern:
Dimensions:
- Value: {'Fn::Sub': ['firehose-events-${Stage}', 'Stage': {'Ref' : 'Stage' }]}
Instead if I could store the whole value in one variable, it would be much easier for me to refer it.
I thought initially storing it in parameters, like this:
Parameters:
FirehoseEvent: {Type:String, Default: 'firehose-events-${Stage}'}
But the stage value doesn't seem to get passed in here. And there is no non default value either for this resource name.
The other option I considered was using mapping, but that defeats the purpose of using ${Stage}.
Is there some other way which I've missed?
Sadly you haven't missed anything. Parameters can't reference other parameters in their definition.
The only way I can think of doing what you which would be through a custom macro. In its simplest form the macro would just perform traditional find-and-replace type of template processing.
However, the time required to develop such macro could be not worth its benefits, at least in this simple example you've provided in the question.
I'm writing code for my GraphQL resolvers in AWS AppSync with resolver mapping template.
I know that there is a put mehtod that I can use for add a field to input object or any other object. Like this (for example):
$util.qr($name.put("firstName", "$ctx.args.input.firstName"))
But now I want to remove a field from an object, for example, the input object.
Is there any mehtod similar to the put method but for removing a field. something like:
$util.qr($ctx.args.input.remove("firstName"))
I am new to AWS and DynamoDB and AppSync.( you can consider me as an absolute beginner. )
Use foreach and make a new array.
#set($newInput={})
#foreach ($key in $ctx.args.input.keySet())
#if($key!="firstName")
$util.qr($newInput.put($key, $ctx.args.input.get($key)))
#end
#end
Yes, generally you can use $myObject.remove("myKey") on objects that you create in a mapping template, however, I will add the disclaimer that this will not always work on objects in the $ctx as some parts are immutable. AppSync bundles utility methods that make dealing with objects in mapping templates easier (e.g. making copies of objects). This functionality is actually tied to that of Apache Velocity so you can read more about how it works in those docs.
In AppSync, the arguments in a query or mutation are exposed in the request mapping template as $context.args. If you have passed in an argument named input you can remove it as follows:
$util.quiet($context.args.remove("input"))
or its using the alias for quiet (identical to the above):
$util.qr($context.args.remove("input"))
This can be used in both the request and response mapping template. It can also be used to remove nested properties:
$util.qr($context.args.input.remove("nestedProp"))
I've an OpenDDS node that's both a DataDriver and DataReader. The consequence is that if the node send a topic, the same topic is received from the same node.
Is there a QoS policy that avoid this behaviour? I want that a node can receive the topic from all nodes but itself.
I want that a node can receive the topic from all nodes but itself.
If you are in a situation where your data type for the relevant Topic includes an attribute that contains information about the source of the data, then you can use that attribute to filter on via a ContentFilteredTopic. Suppose that your data type has a field nodeId that identifies your node, then you can use a ContentFilter expression like nodeId <> %0 and set the parameter to your own nodeId. The middleware would deliver all updates to your DataReaders, except for those that have your own nodeId. Check out the DDS specification for more details.
Given that your application wants to ignore data coming from your own node, I would argue that your data type actually needs that nodeId as an attribute, because apparently that is information relevant for your application. So if you do not have it at the moment, you might have to add it.
If you are not allowed or do not want to add such a field your data type, you can also use another, more convoluted mechanism by leveraging the ignore_publication() or ignore_participant() methods. These are explained in the specification as well. If you want to go that route, let me know if you have questions about it.
Finally, there might be vendor-specific extensions to the API that provide you with easier ways to achieve what you are looking for. For example, see How do I get a DataReader to ignore a DataWriter that belongs to the same DomainParticipant? for a solution using the RTI product.