- Newest
- Most votes
- Most comments
There are a couple of ways to approach this. You will need to follow a few steps. AWS CloudFormation does not provide a direct "fromArn" function for IoT rules but you can accomplish this using AWS CDK (Cloud Development Kit) or by directly using the AWS SDK.
Here is one way of accomplishing this by using AWS CDK:
-
Create the IoT Rule in Stack A and make note of the ARN.
-
In Stack B, you can then use the AWS CDK to import the IoT Rule by its ARN and then add an action to it.
I have provided an example below:
from aws_cdk import core.
from aws_cdk.aws_iot import CfnTopicRule
class StackA(core.Stack):
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
# Create IoT Rule
self.iot_rule = CfnTopicRule(self, "MyIoTRule",
rule_name="MyIoTRule",
topic_rule_payload={
"sql": "SELECT * FROM 'some/topic'",
"actions": []
})
core.CfnOutput(self, "IoTRuleArn", value=self.iot_rule.attr_arn)
class StackB(core.Stack):
def __init__(self, scope: core.Construct, id: str, iot_rule_arn: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
# Add action to IoT Rule
CfnTopicRule(self, "MyIoTRuleWithAction",
rule_name="MyIoTRule",
topic_rule_payload={
"sql": "SELECT * FROM 'some/topic'",
"actions": [
{
"lambda": {
"functionArn": "arn:aws:lambda:region:account-id:function:MyFunction"
}
}
]
})
app = core.App()
stack_a = StackA(app, "StackA")
stack_b = StackB(app, "StackB", iot_rule_arn=stack_a.iot_rule.attr_arn)
app.synth()
If you prefer to use CloudFormation templates directly, you would need to use custom resources or Lambda-backed custom resources to update the IoT Rule. Here is one way of accomplishing this with AWS SDK.
-
You can use a Lambda function to modify the IoT Rule from Stack B Here is an example.
Resources: UpdateIoTRule: Type: "AWS::Lambda::Function" Properties: Handler: index.handler Role: arn:aws:iam::account-id:role/service-role/role-name Code: ZipFile: | import boto3 import cfnresponse def handler(event, context): client = boto3.client('iot') try: response = client.replace_topic_rule( ruleName='MyIoTRule', topicRulePayload={ 'sql': "SELECT * FROM 'some/topic'", 'actions': [ { 'lambda': { 'functionArn': 'arn:aws:lambda:region:account-id:function:MyFunction' } } ] } ) cfnresponse.send(event, context, cfnresponse.SUCCESS, {}) except Exception as e: cfnresponse.send(event, context, cfnresponse.FAILED, {'Message': str(e)}) Runtime: python3.8
In your Stack B template, invoke this Lambda function:
Resources:
UpdateIoTRuleCustomResource:
Type: Custom::UpdateIoTRule
Properties:
ServiceToken: !GetAtt UpdateIoTRule.Arn
Both AWS CDK and AWS SDK allow you to manage and update your IoT rules across stacks. AWS CDK provides a clean and programmatic way to handle this task while the AWS SDK and CloudFormation custom resources offer a more traditional approach.
For more details on this topic, refer to the following:
AWS CDK Python Reference Documentation
AWS SDK for Python (Boto3) Documentation
Relevant content
- asked a year ago
- Accepted Answer
- asked 6 months ago
- AWS OFFICIALUpdated 10 months ago
- AWS OFFICIALUpdated 10 months ago
- AWS OFFICIALUpdated 3 months ago
- AWS OFFICIALUpdated 2 years ago
Hi! Thanks for you help! But I do not fully understand. You created the argument "iot_rule_arn" for the constructor in StackB, but I can't see using it. Am I missing something?
By the way: I'm using TypeScript, but I guess it's fully translatable, isn't it?