Skip to content

Automatically restart ECS service tasks/containers after secret rotation

0

I'm using CDK to deploy a 3rd party application on ECS Fargate, that's configured to access a database via a secret in AWS Secrets Manager - using the direct integration from ECS something like the below:

    this.secret = new secretsmanager.Secret(this, "Secret", {
      generateSecretString: {
        secretStringTemplate: JSON.stringify({
          database: "default",
          user: "me",
        }),
        generateStringKey: "password",
        excludePunctuation: true,
        passwordLength: 24,
      },
    });

    ...

    const container = taskDefinition.addContainer("MyAppContainer", {
      containerName: "myapp",
      image: ecs.ContainerImage.fromEcrRepository(
        deployedImage.repository,
        deployedImage.imageTag,
      ),
      cpu,
      memoryLimitMiB,
      secrets: {
        SECRET_ENV_VAR: ecs.Secret.fromSecretsManager(this.secret, "password"),
      },
      ...
    });

    this.fargateService = new ecs.FargateService(this, "FargateService", {
      taskDefinition: taskDefinition,
      ...,
    });

The question is, if I configure rotation on the Secrets Manager Secret, what's the best / most direct way to automatically restart the service's containers whenever the rotation happens? Since it's a 3rd party app, I don't have direct control over the code to implement client-side secret caching as described here: I think we have no choice but to pass it as an environment variable and restart the container when it changes.

2 Answers
1

I had implemented something similar using EventBridge to trigger a StepFunction for task restart , you can do something similar

Refer to my blog post

const secretName = 'my-secret'; // Replace with your secret name
const rule = new events.Rule(this, 'SecretRotationRule', {
  ruleName: 'SecretRotationRule-' + secretName,
  eventPattern: {
    source: ['aws.secretsmanager'],
    detailType: ['AWS API Call via CloudTrail'],
    detail: {
      eventSource: ['secretsmanager.amazonaws.com'],
      eventName: ['RotateSecret'],
      requestParameters: {
        secretId: [secretName],
      },
    },
  },
});

rule.addTarget(new targets.SfnStateMachine(stateMachineL2));

EXPERT

answered 2 years ago

EXPERT

reviewed 3 months ago

0

Have you considered using Amazon EventBridge to automate the restart of your ECS service when the secret is rotated?

With EventBridge, you can listen for "RotateSecret" events from Secrets Manager and trigger an ECS service update, ensuring your containers always load the latest credentials.

answered 2 years ago

  • I agree with this! This was the EventBridge rule I created:

    {
      "$or": [{
        "detail": {
          "eventName": ["PutSecretValue", "UpdateSecret"],
          "eventSource": ["secretsmanager.amazonaws.com"],
          "responseElements": {
            "arn": [<your-arn>]
          }
        },
        "detail-type": ["AWS API Call via CloudTrail"]
      }, {
        "detail": {
          "additionalEventData": {
            "SecretId": [<your-arn>]
          },
          "eventName": ["RotationSucceeded"],
          "eventSource": ["secretsmanager.amazonaws.com"]
        },
        "detail-type": ["AWS Service Event via CloudTrail"]
      }],
      "source": ["aws.secretsmanager"]
    }
    

    I had this event trigger a Lambda function that would use the boto3 client in Python to update the service (see the Lambda source code here: https://github.com/epilogue-club/terraform-aws-ecs-secret-rotation/blob/main/lambda/main.py)

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.