By using AWS re:Post, you agree to the Terms of Use

CDK v1: Deploy RDS SQL Server and use credential in a connection string for fargate docker instance

0

I have been trying to find an answer in documentation, github, here and the old forums, but I fail to find the answer to my question.

In my CDK v1 (python) I create a RDS instance of SQL Server and set credentials with aws_rds.Cerednetials.from_generated_secret(), but when I later on want to provide environment/sercrets values to the docker container I want to run in fargate I have the following environment variable that I need to be set: DB_CONNECTION_STRING, which has the following syntax: Server=<somehost.aws.com>,144;Database=<databasename>; User Id=<databaseuser>;Password=<databasepassword>

All the examples I have seen uses multiple variables like DB_USER/DB_PASS/DB_HOST and then you can easily set those with help of secret_value, but there is no example on generating a connection string.

How do you solve this? I took a look at aws glue, but it didn't feel like the right optionand I'm not too keen on making a dockerfile to try to pull the official docker image and then create a kind of a wrapper to have environment/sercret variables and then a script that builds up the connection string and sets it before calling the start script for the application (this has other downsides).

The reason why I'm not using the CDK v2 is that the current version seems to be broken when you create a new project in WSL (seems to think it's pure ms-windows and fails to create a number of files needed).

Thanks in advance for any reply.

  • I'm not 100% sure I follow the issue you're facing - are you trying to build the connection string from secrets manager dynamically? If so, I see maybe a couple of options:

    1. Create a custom value secret in secrets manager with the full connection string as your value, and then reference that. (Seems less desirable)
    2. I'm not sure if this will work in fargate, but can you reference a var from another var? So, you have your individual values for DB_USER, DB_PASS, etc. referenced using secret_value, and then you have another var that is something like: DB_CONNECTION_STRING="Server=${DB_HOST},144;Database=${DB_NAME}..."

    But, I'm not sure if that's a bad idea or not. Ideally, you'd break up the reference in your config files to reference the individual values, and not a full string. So, essentially, #2 above, but you're doing that in your config file and not in the env vars. But I know that's not always a possibility.

  • @dozenyommer:

    1. Still need manual steps, as far as I know you won't be able to build that custom secret from secret with help of CDK.
    2. That would require that the variables are always set in sequence
    container = fargateTask.add_container(
    ...,
    sercrets={
      'DBUSER': ecs.Secret.from_secrets_manager(self.database.secret, 'username'),
      'DBPASS': ecs.Secret.from_secrets_manager(self.database.secret, 'password'),
      'DB_CONNECTION_STRING': '...;User Id=${DBUSER};Password=${DBPASS};...'
    },
    ...
    

    So that both DBUSER/DBPASS are set before DB_CONNECTION_STRING, it's worth a try at least.

    The issue is that the docker image is an official image provide by the company who done the application, so I do not have a say on what variables can be used and I'm trying to avoid to make my own docker image based on that official docker image where I do build up the variable in the docker and then execute the binary, but sure I have to in worst case :(

  • @dozenyommer: Sadly the second suggestion of building the connection string from environment variables do not work, it will be literal as you wrote without any value substitutions. I guess I have to go the step and create a Dockerfile which based on the official package and try to build the connection string as a variable and start the application with the environment variable set.

1 Answer
0

Hello,

I understand that you are trying to figure out how to set the DB_CONNECTION_STRING environment variable for a Fargate container.

If are using CDK to create ECS resources, then you should be able to pass environment variables to the container with your Task definition - https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-ecs.TaskDefinition.html

ECS allow you declare environment variables to be populated with secret values from SecretsManager. Since the secret values does not get evaluated until ECS is running the container, there is no good way to inject those values into another string, unless you do it from inside the container. Since MS SQL seems to want to use DB_CONNECTION_STRING containing these details, you would have to either have that connection string stored in secrets manager, or assemble the connection string at your end by generating it from the DBUSER and DBPASS values.

The links below would help shed light into how to achieve your use case - https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-rds.Credentials.html

I hope this information can help achieve your use case.

If the information above does not help, please open a support case with AWS using the following https://console.aws.amazon.com/support/home#/case/create and provide details on the code snippet and also please let us know if you are using CDK to create ECS resources in the support case.

SUPPORT ENGINEER
answered 8 months ago
  • It's not the creating the secret that is the issue, but transforming the secret to the connection string format that mssql wants. I would have liked that secret had a function that could take a format string ( for example "User Id={username};Password={password}") and generate the string when deploying the image to fargate. secrets = { CONNECTION_STRING=yourSecretObject.string_format("User Id={username};Password={password}") }

    I'm sadly now building a new docker image based on the official docker image and generating a script that builds the connection string from environment variables and executing the original entrypoint command and then setting my custom script as the entrypoint. This causes the problem that I have to keep an eye that the original docker image do not change entrypoint between releases, which makes the whole solution less automated than one would like.

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.

Guidelines for Answering Questions