lgallard / terraform-aws-secrets-manager

Terraform module to create Amazon Secrets Manager resources.
Apache License 2.0
63 stars 50 forks source link

Importing an existing secret #9

Closed atiffarrukh closed 3 years ago

atiffarrukh commented 3 years ago

How can I import and existing secret? I tried following

terraform import module.secrets-manager-2[0] <arn-of-secret>

but I am getting

Error: Invalid address

  on <import-address> line 1:
   1: module.secrets-manager-2[0]

A resource instance address is required here. The module path must be followed
by a resource instance specification.
lgallard commented 3 years ago

@atiffarrukh you have to import two resources, the secret itself and its version.

Example

Let's extend the plaintext example, and add a new secret definition.

module "secrets-manager-1" {

  source = "lgallard/secrets-manager/aws"

  secrets = [
    {
      name                    = "secret-1"
      description             = "My secret 1"
      recovery_window_in_days = 7
      secret_string           = "This is an example"
    },
    {
      name                    = "secret-2"
      description             = "My secret 2"
      recovery_window_in_days = 7
      secret_string           = "This is another example"
    },
    {
      name                    = "secret-3"
      description             = "My secret 3"
      recovery_window_in_days = 0
      secret_string           = "Secret to be imported"
    }
  ]

  tags = {
    Owner       = "DevOps team"
    Environment = "dev"
    Terraform   = true

  }
}

In this case, secret-3 is the secret to be imported. I went to the AWS console and created it with the above data and tags.

Take into account that the recovery_window_in_days is set to 0, because when creating a secret from the console it set this value to 0.

At this point, running a plan shows Terraform is about to create new resources:

$ terraform plan 

module.secrets-manager-1.aws_secretsmanager_secret.sm[0]: Refreshing state... [id=arn:aws:secretsmanager:us-east-1:123456789101:secret:secret-1-jfeQCL]
module.secrets-manager-1.aws_secretsmanager_secret.sm[1]: Refreshing state... [id=arn:aws:secretsmanager:us-east-1:123456789101:secret:secret-2-d3j5Jw]
module.secrets-manager-1.aws_secretsmanager_secret_version.sm-sv[0]: Refreshing state... [id=arn:aws:secretsmanager:us-east-1:123456789101:secret:secret-1-jfeQCL|61DBD200-C20C-422B-8CA1-EE2828015AC5]
module.secrets-manager-1.aws_secretsmanager_secret_version.sm-sv[1]: Refreshing state... [id=arn:aws:secretsmanager:us-east-1:123456789101:secret:secret-2-d3j5Jw|9E86A928-6F82-454C-B1C0-5C0F8510592D]

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # module.secrets-manager-1.aws_secretsmanager_secret.sm[2] will be created
  + resource "aws_secretsmanager_secret" "sm" {
      + arn                     = (known after apply)
      + description             = "My secret 3"
      + id                      = (known after apply)
      + name                    = "secret-3"
      + name_prefix             = (known after apply)
      + policy                  = (known after apply)
      + recovery_window_in_days = 0
      + rotation_enabled        = (known after apply)
      + rotation_lambda_arn     = (known after apply)
      + tags                    = {
          + "Environment" = "dev"
          + "Owner"       = "DevOps team"
          + "Terraform"   = "true"
        }

      + rotation_rules {
          + automatically_after_days = (known after apply)
        }
    }

  # module.secrets-manager-1.aws_secretsmanager_secret_version.sm-sv[2] will be created
  + resource "aws_secretsmanager_secret_version" "sm-sv" {
      + arn            = (known after apply)
      + id             = (known after apply)
      + secret_id      = (known after apply)
      + secret_string  = (sensitive value)
      + version_id     = (known after apply)
      + version_stages = (known after apply)
    }

Plan: 2 to add, 0 to change, 0 to destroy.

As you can see, you need to import those resources. The first one is easy to import, just got to the console and find the secret's ARN. Then import it as follows:

terraform import module.secrets-manager-1.aws_secretsmanager_secret.sm[2] arn:aws:secretsmanager:us-east-1:123456789101:secret:secret-3-PBzzk1

This will be the output got the above command:

module.secrets-manager-1.aws_secretsmanager_secret.sm[2]: Importing from ID "arn:aws:secretsmanager:us-east-1:123456789101:secret:secret-3-PBzzk1"...
module.secrets-manager-1.aws_secretsmanager_secret.sm[2]: Import prepared!
  Prepared aws_secretsmanager_secret for import
module.secrets-manager-1.aws_secretsmanager_secret.sm[2]: Refreshing state... [id=arn:aws:secretsmanager:us-east-1:123456789101:secret:secret-3-PBzzk1

Import successful!

The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.

Now to import the secret's version you'll need to use the AWS CLI to retrieve all versions for that secret (its seems, there no such as option from the console) and use the current version:

$ aws secretsmanager list-secret-version-ids --secret-id  arn:aws:secretsmanager:us-east-1:123456789101:secret:secret-3-PBzzk1 --region us-east-1 

The output in this case was:

{
    "Versions": [
        {
            "VersionId": "9c0f4e27-7a06-4a1a-ae53-a37fd4f58dc1",
            "VersionStages": [
                "AWSCURRENT"
            ],
            "LastAccessedDate": "2021-02-24T21:00:00-03:00",
            "CreatedDate": "2021-02-25T00:55:55.381000-03:00"
        }
    ],
    "ARN": "arn:aws:secretsmanager:us-east-1:123456789101:secret:secret-3-PBzzk1",
    "Name": "secret-3"
}

According to Terraform's documentation, you need to pass the secret ARN or name, and a versión ID as follows:

terraform import module.secrets-manager-1.aws_secretsmanager_secret_version.sm-sv[2] "arn:aws:secretsmanager:us-east-1:123456789101:secret:secret-3-PBzzk1|9c0f4e27-7a06-4a1a-ae53-a37fd4f58dc1"

Bear in mind you need to pass the string as follow: "SECRET_ARN| VERSION_ID".

This will import the versión ID as shown:

module.secrets-manager-1.aws_secretsmanager_secret_version.sm-sv[2]: Importing from ID "arn:aws:secretsmanager:us-east-1:123456789101:secret:secret-3-PBzzk1|9c0f4e27-7a06-4a1a-ae53-a37fd4f58dc1"...
module.secrets-manager-1.aws_secretsmanager_secret_version.sm-sv[2]: Import prepared!
  Prepared aws_secretsmanager_secret_version for import
module.secrets-manager-1.aws_secretsmanager_secret_version.sm-sv[2]: Refreshing state... [id=arn:aws:secretsmanager:us-east-1:123456789101:secret:secret-3-PBzzk1|9c0f4e27-7a06-4a1a-ae53-a37fd4f58dc1]

Import successful!

The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.

If you run the plan again, it must show that the infra is up-to-date:

$ terraform plan 

module.secrets-manager-1.aws_secretsmanager_secret.sm[1]: Refreshing state... [id=arn:aws:secretsmanager:us-east-1:123456789101:secret:secret-2-d3j5Jw]
module.secrets-manager-1.aws_secretsmanager_secret.sm[0]: Refreshing state... [id=arn:aws:secretsmanager:us-east-1:123456789101:secret:secret-1-jfeQCL]
module.secrets-manager-1.aws_secretsmanager_secret.sm[2]: Refreshing state... [id=arn:aws:secretsmanager:us-east-1:123456789101:secret:secret-3-PBzzk1]
module.secrets-manager-1.aws_secretsmanager_secret_version.sm-sv[1]: Refreshing state... [id=arn:aws:secretsmanager:us-east-1:123456789101:secret:secret-2-d3j5Jw|9E86A928-6F82-454C-B1C0-5C0F8510592D]
module.secrets-manager-1.aws_secretsmanager_secret_version.sm-sv[0]: Refreshing state... [id=arn:aws:secretsmanager:us-east-1:123456789101:secret:secret-1-jfeQCL|61DBD200-C20C-422B-8CA1-EE2828015AC5]
module.secrets-manager-1.aws_secretsmanager_secret_version.sm-sv[2]: Refreshing state... [id=arn:aws:secretsmanager:us-east-1:123456789101:secret:secret-3-PBzzk1|9c0f4e27-7a06-4a1a-ae53-a37fd4f58dc1]

No changes. Infrastructure is up-to-date.

This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed.

I hope this answer / guide help you out.

References

atiffarrukh commented 3 years ago

thank you. I will give it a go.