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

Secrets Manager: Support Secret Replication #17943

Closed
TomTucka opened this issue Mar 5, 2021 · 11 comments · Fixed by #20293
Closed

Secrets Manager: Support Secret Replication #17943

TomTucka opened this issue Mar 5, 2021 · 11 comments · Fixed by #20293
Assignees
Labels
enhancement Requests to existing resources that expand the functionality or scope. service/secretsmanager Issues and PRs that pertain to the secretsmanager service.
Milestone

Comments

@TomTucka
Copy link
Contributor

TomTucka commented Mar 5, 2021

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Description

AWS has launched support for replicating secrets between regions. We should add the ability to configure this in Terraform

New or Affected Resource(s)

  • aws_secretsmanager_secret

References

@TomTucka TomTucka added the enhancement Requests to existing resources that expand the functionality or scope. label Mar 5, 2021
@ghost ghost added the service/secretsmanager Issues and PRs that pertain to the secretsmanager service. label Mar 5, 2021
@TomTucka
Copy link
Contributor Author

TomTucka commented Mar 5, 2021

Worth mentioning support for this was added into the aws-sdk-go in this PR.

@mattburgess
Copy link
Collaborator

I took a look at implementing this but have run into an issue with the API.

Here's my proposed TF config:

resource "aws_secretsmanager_replication" "example" {
  secret_id = aws_secretsmanger_secret.example.id
  add_replica_regions {
    region = "us-east-1"
    kms_key_id = aws_kms_key.example.id
  }
  force_overwrite_replica_secret = false

The problem I've got is that DescribeSecret returns a list of all of the replication statuses on the given secret, but our resource only needs to handle one of those. At the moment, I can't find any examples where a resource's Read() function has to filter the AWS API response using the current state so as to only operate on a single 'sub-resource'. I also couldn't immediately see such a pattern described at https://github.com/hashicorp/terraform-provider-aws/blob/main/docs/contributing/data-handling-and-conversion.md#nested-typelist-of-resource-and-aws-list-of-structure so I fear I may have modelled this incorrectly.

@generalov
Copy link

Just a naming thing: aws_dynamodb_table has a similar replica option:

replica {
    region_name = "us-east-2"
}

@mpescetto
Copy link

mpescetto commented Mar 19, 2021

@TomTucka Pardon my ignorance, but I know secrets allows for multiple replications, does your configuration block allow for that? i.e.

replication_configuration {
   force_overwrite_replica_secret = false

   replica_region {
       region     = "us-east-1"
       kms_key_id = aws_kms_key.example.id
  }

   replica_region {
       region     = "us-west-2"
       kms_key_id = "alias/foo"
  }
}

Thanks for your work on this! This feature will help me out biiiiigggg time!

@TomTucka
Copy link
Contributor Author

Hey @mpescetto, It will do yes!

@thiagolsfortunato
Copy link

Any news?!

Today, I'm implementing using null_resources, but would be great to do this using nested blocks

resource "null_resource" "multi-region" {
  provisioner "local-exec" {
    command = "aws secretsmanager replicate-secret-to-regions --secret-id ${aws_secretsmanager_secret.secret.id} --force-overwrite-replica-secret --add-replica-regions  \"Region=${var.ssm-replicate-region}\""
  }

  depends_on = [
    aws_secretsmanager_secret.secret
  ]
}

@KyleKotowick
Copy link
Contributor

In the meantime, I've created a module that simulates the aws_secretsmanager_secret and adds the replicated_regions functionality by internally using CloudFormation. You can check it out on the Terraform Registry.

@ghost
Copy link

ghost commented Jun 15, 2021

I enhanced @thiagolsfortunato work around.

I have the below in a "secret" module, with an input argument of replica_regions which is just a list of strings ie: ["us-east-2", ...]

This will destroy the replicated secret if the region list changes.

resource "null_resource" "replica_region" {
  for_each = toset(var.replica_regions)

  triggers = {
    region = each.key
    secret_id = aws_secretsmanager_secret.secret.id
  }

  provisioner "local-exec" {
    command = "aws secretsmanager replicate-secret-to-regions --secret-id ${self.triggers.secret_id} --force-overwrite-replica-secret --add-replica-regions \"Region=${self.triggers.region}\""
  }

  provisioner "local-exec" {
    when    = destroy
    command = "aws secretsmanager remove-regions-from-replication --secret-id ${self.triggers.secret_id} --remove-replica-regions ${self.triggers.region}"
  }

  depends_on = [
    aws_secretsmanager_secret.secret
  ]
}

@KyleKotowick
Copy link
Contributor

KyleKotowick commented Jul 5, 2021

I enhanced @thiagolsfortunato work around.

I have the below in a "secret" module, with an input argument of replica_regions which is just a list of strings ie: ["us-east-2", ...]

This will destroy the replicated secret if the region list changes.

resource "null_resource" "replica_region" {
  for_each = toset(var.replica_regions)

  triggers = {
    region = each.key
    secret_id = aws_secretsmanager_secret.secret.id
  }

  provisioner "local-exec" {
    command = "aws secretsmanager replicate-secret-to-regions --secret-id ${self.triggers.secret_id} --force-overwrite-replica-secret --add-replica-regions \"Region=${self.triggers.region}\""
  }

  provisioner "local-exec" {
    when    = destroy
    command = "aws secretsmanager remove-regions-from-replication --secret-id ${self.triggers.secret_id} --remove-replica-regions ${self.triggers.region}"
  }

  depends_on = [
    aws_secretsmanager_secret.secret
  ]
}

@bdriggs-axian This requires having default credentials set for AWS on the CLI though right? That often doesn't work if multiple developers work on it, if it's being run in Terraform Cloud, if the Terraform files manage multiple AWS accounts (organization accounts), etc. Not to mention it also requires having the AWS CLI installed, which isn't always the case either. Unless I'm missing something, I don't see why using a CloudFormation resource wouldn't be preferable.

@github-actions
Copy link

This functionality has been released in v3.52.0 of the Terraform AWS Provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading.

For further feature requests or bug reports with this functionality, please create a new GitHub issue following the template. Thank you!

@github-actions
Copy link

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 29, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement Requests to existing resources that expand the functionality or scope. service/secretsmanager Issues and PRs that pertain to the secretsmanager service.
Projects
None yet
7 participants