Skip to content

Add support for “desired state” deployment styles (e.g., AWS CDK or Terraform) #2597

@mauroservienti

Description

@mauroservienti

Describe the feature.

It would be helpful to output CDK- or Terraform-compatible artifacts to ease production deployments when using desired-state deployment styles, such as Cloud Formation.

This issue is related to but not dependent on:

To fully automate the generation of artifacts, it's important to remember that some of the required information, such as the list of subscribed events, is only known by NServiceBus Core.

An initial valuable step could be to provide, similarly to the transport CLI, a separate package allowing users to declare their infrastructure's desired state manually. For example, the following is a sample CDK resource that could be shipped as part of that package:

using Amazon.CDK;
using Amazon.CDK.AWS.DynamoDB;
using Amazon.CDK.AWS.IAM;
using Amazon.CDK.AWS.SQS;
using Attribute = Amazon.CDK.AWS.DynamoDB.Attribute;

namespace Deploy;

public class NServiceBusEndpointResource : Resource
{
    public NServiceBusEndpointResource(EndpointDetails endpoint, Construct scope, string id, IResourceProps? props = null)
        : base(scope, id, props)

    {
        var queue = new Queue(this, endpoint.EndpointName, new QueueProps
        {
            QueueName = endpoint.FullQueueName,
            RetentionPeriod = Duration.Seconds(endpoint.RetentionPeriod.TotalSeconds),
        });

        // Generate a stricter policy statement
        var policyStatement = new PolicyStatement();
        policyStatement.Effect = Effect.ALLOW;
        policyStatement.AddAllResources();
        policyStatement.AddAnyPrincipal();
        policyStatement.AddActions(["sqs:*"]);

        queue.AddToResourcePolicy(policyStatement);
        var delay = new Queue(this, $"{endpoint.EndpointName}-delay", new QueueProps
        {
            QueueName = endpoint.DelayQueueName,
            Fifo = true,
            DeliveryDelay = Duration.Seconds(900),
            RetentionPeriod = Duration.Seconds(endpoint.RetentionPeriod.TotalSeconds)
        });
        delay.AddToResourcePolicy(policyStatement);

        if (endpoint.EventsToSubscribe != null)
        {
            foreach (var evtType in endpoint.EventsToSubscribe)
            {
                //TODO: create the needed topic and subscribe
            }
        }
    }
}

public class EndpointDetails(string endpointName)
{
    public string EndpointName => endpointName;
    public string? Prefix { get; set; }
    public string FullQueueName => $"{Prefix}{endpointName}";
    public string DelayQueueName => $"{FullQueueName}-delay.fifo";
    public TimeSpan RetentionPeriod { get; set; } = TimeSpan.FromDays(4);
    public Type[]? EventsToSubscribe { get; set; }
}

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions