Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[custom-resources] Allow passing a Secret value as a parameter to AwsCustomResource #9815

Open
1 of 2 tasks
blimmer opened this issue Aug 18, 2020 · 6 comments
Open
1 of 2 tasks
Labels
@aws-cdk/custom-resources Related to AWS CDK Custom Resources effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. needs-cfn This issue is waiting on changes to CloudFormation before it can be addressed. p1

Comments

@blimmer
Copy link
Contributor

blimmer commented Aug 18, 2020

It would be convenient to be able to pass a secret {{resolve}} token as a parameter to the AwsCustomResource class and have it resolved at runtime to the actual secret value.

Use Case

I created a custom resource that looked like this:

const systemUser = new cognito.CfnUserPoolUser(this, "CognitoSystemUser", {
  username: 'myUser',
  userPoolId: 'myUserPoolId',
});
const cognitoUserSecret = new secrets.Secret(this, "CognitoSystemUserSecret", {
  secretName: `auth/internal/MySystemUser`,
  generateSecretString: {
    secretStringTemplate: JSON.stringify({
      Username: user.username,
      UserPoolId: user.userPoolId,
      ClientId: 'myclientid',
    }),
    generateStringKey: "Password",
  },
});
const customResource = new cr.AwsCustomResource(this, "CognitoSystemUserPasswordSetter", {
  onCreate: {
    service: "CognitoIdentityServiceProvider",
    action: "adminSetUserPassword",
    parameters: {
      Username: systemUser.username,
      UserPoolId: systemUser.userPoolId,
      Password: cognitoUserSecret.secretValueFromJson("Password").toString(),
      Permanent: true,
    },
    physicalResourceId: cr.PhysicalResourceId.of(`${systemUser.username}-password-confirmation`),
  },
  policy: cr.AwsCustomResourcePolicy.fromStatements([
    new iam.PolicyStatement({
      sid: "AllowSetPasswordForUser",
      effect: iam.Effect.ALLOW,
      actions: ["cognito-idp:AdminSetUserPassword"],
      resources: [
        cdk.Arn.format(
          {
            region: "us-west-2",
            service: "cognito-idp",
            resource: "userpool",
            sep: "/",
            resourceName: systemUser.userPoolId,
          },
          this,
        ),
      ],
    }),
  ]),
});
cognitoUserSecret.grantRead(customResource);

This almost works, but it does not actually resolve the password to its value in Secrets Manager. In my case, it set the actual password to the literal string {{resolve:secretsmanager:arn:aws:secretsmanager:us-west-2:123456789:secret:auth/internal/MySystemUser-ABCDEF:SecretString:Password::}}.

Proposed Solution

It would be great if the custom resource code looked for {{resolve:secretsmanager}}-style references in the parameters passed to AwsCustomResource and resolved them to their underlying value.

Other

  • 👋 I may be able to implement this feature request
  • ⚠️ This feature might incur a breaking change

This is a 🚀 Feature Request

@blimmer blimmer added feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged. labels Aug 18, 2020
@github-actions github-actions bot added the @aws-cdk/custom-resources Related to AWS CDK Custom Resources label Aug 18, 2020
@jogold
Copy link
Contributor

jogold commented Aug 19, 2020

Indeed this is currently not supported in custom resources. This would require additional logic in the Lambda function implementing the AwsCustomResource.

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/dynamic-references.html

Dynamic references for secure values, such as ssm-secure and secretsmanager, are not currently supported in custom resources.

@rix0rrr
Copy link
Contributor

rix0rrr commented Aug 24, 2020

That is disappointing. One would have hoped that CloudFormation did this automatically

@rix0rrr rix0rrr added effort/medium Medium work item – several days of effort needs-cfn This issue is waiting on changes to CloudFormation before it can be addressed. p2 and removed needs-triage This issue or PR still needs to be triaged. labels Aug 24, 2020
@markussiebert
Copy link
Contributor

if you see this in the context of eks, i think this would be a nice feature. Creating rds outside the ecs cluster with secrets from the secretsmanager and passing them to a helm chart ... it would be great if this would be supported!

@A-Mckinlay
Copy link

Is there any timeline for this being implemented?

@rix0rrr rix0rrr removed their assignment Jun 3, 2021
@Dzhuneyt
Copy link
Contributor

I have a similar use case where I want to pass a SecretValue not to a CustomResource, but to a Lambda as an Environment Variable.

I guess the principle is pretty much the same.

Pseudo-code to demonstrate:

const esDomain = new elasticsearch.Domain();

const lambda = new lambda.Function();
lambda.addEnvironment('elasticsearch_password', esDomain.masterUserPassword);

Right now this is not supported since masterUserPassword is of type cdk.SecretValue and the Lambda environment variables don't support (and resolve) such values.

mergify bot pushed a commit that referenced this issue Sep 13, 2021
This feature allows users to manage Redshift database resources, such as users, tables, and grants, within their CDK application. Because these resources do not have CloudFormation handlers, this feature leverages custom resources and the Amazon Redshift Data API for creation and modification.

The generic construct for this type of resource is `DatabaseQuery`. This construct provides the base functionality required for interacting with Redshift database resources, including configuring administrator credentials, creating a custom resource handler, and granting necessary IAM permissions. The custom resource handler code contains utility functions for executing query statements against the Redshift database.

Specific resources that use the `DatabaseQuery` construct, such as `User` and `Table` are responsible for providing the following to `DatabaseQuery`: generic database configuration properties, specific configuration properties that will get passed to the custom resource handler (eg., `username` for `User`). Specific resources are also responsible for writing the lifecycle-management code within the handler. In general, this consists of: configuration extraction (eg., pulling `username` from the `AWSLambda.CloudFormationCustomResourceEvent` passed to the handler) and one method for each lifecycle event (create, update, delete) that queries the database using calls to the generic utility function.

Users have a fairly simple lifecycle that allows them to be created, deleted, and updated when a secret containing a password is updated (secret rotation has not been implemented yet). Because of #9815, the custom resource provider queries Secrets Manager in order to access the password.

Tables have a more complicated lifecycle because we want to allow columns to be added to the table without resource replacement, as well as ensuring that dropped columns do not lose data. For these reasons, we generate a unique name per-deployment when the table name is requested to be generated by the end user. We also notify create a new table (using a new generated name) if a column is to be dropped and let CFN lifecycle rules dictate whether the old table should be removed or kept.

User privileges on tables are implemented via the `UserTablePrivileges` construct. This construct is located in the `private` directory to ensure that it is not exported for direct public use. This means that user privileges must be managed through the `Table.grant` method or the `User.addTablePrivileges` method. Thus, each `User` will have at most one `UserTablePrivileges` construct to manage its privileges. This is to avoid a situation where privileges could be erroneously removed when the same privilege is managed from two different CDK applications. For more details, see the README, under "Granting Privileges".

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@kirintwn
Copy link
Contributor

@rix0rrr rix0rrr added p1 and removed p2 labels Mar 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/custom-resources Related to AWS CDK Custom Resources effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. needs-cfn This issue is waiting on changes to CloudFormation before it can be addressed. p1
Projects
None yet
Development

No branches or pull requests

7 participants