網頁

2021/12/22

Terraform 設定Secrets Manager secret範例

Terraform在AWS Secrets Manager建立secret的範例如下。


範例環境:

  • AWS CLI 2.2.44
  • Terraform v1.0.10

開始前必須安裝好Terraform並確認AWS CLI設定好access key並可存取AWS服務。


建立配置檔

在任意資料夾新增一個Terraform配置文件main.tf 內容如下。此文件用來設定terraform配置provider aws及要建立的Secrets Manager resource aws_secretsmanager_secretaws_secretsmanager_secret_version

main.tf

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.27"
    }
  }

  required_version = ">= 0.14.9"
}

provider "aws" {
  profile = "default"
  region  = "ap-northeast-1" // Tokyo
}

// secret manager configs
resource "aws_secretsmanager_secret" "demo_secret" {
  name                    = "terraform/secret1"
  recovery_window_in_days = 7
}

variable "key_value_pairs" {
  default = {
    secret = "12345"
  }

  type = map(string)
}

resource "aws_secretsmanager_secret_version" "demo_secret_value" {
  secret_id     = aws_secretsmanager_secret.demo_secret.id
  secret_string = jsonencode(var.key_value_pairs)
}

Resource aws_secretsmanager_secret的選填參數kms_key_id用來指定加密secret的KMS key,若未設定則預設以AWS管理的key aws/secretsmanager做加密。


套用配置

輸入terraform apply執行配置計畫。

~/../terraform-demo$ terraform apply

Terraform used the selected providers to generate the following execution plan. Resource actions are
indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_secretsmanager_secret.demo_secret will be created
  + resource "aws_secretsmanager_secret" "demo_secret" {
      + arn                            = (known after apply)
      + force_overwrite_replica_secret = false
      + id                             = (known after apply)
      + name                           = "terraform/secret1"
      + name_prefix                    = (known after apply)
      + policy                         = (known after apply)
      + recovery_window_in_days        = 7
      + rotation_enabled               = (known after apply)
      + rotation_lambda_arn            = (known after apply)
      + tags_all                       = (known after apply)

      + replica {
          + kms_key_id         = (known after apply)
          + last_accessed_date = (known after apply)
          + region             = (known after apply)
          + status             = (known after apply)
          + status_message     = (known after apply)
        }

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

  # aws_secretsmanager_secret_version.demo_secret_value will be created
  + resource "aws_secretsmanager_secret_version" "demo_secret_value" {
      + 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.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_secretsmanager_secret.demo_secret: Creating...
aws_secretsmanager_secret.demo_secret: Creation complete after 1s [id=arn:aws:secretsmanager:ap-northeast-1:400361196721:secret:terraform/secret1-cRy7lp]
aws_secretsmanager_secret_version.demo_secret_value: Creating...
aws_secretsmanager_secret_version.demo_secret_value: Creation complete after 0s [id=arn:aws:secretsmanager:ap-northeast-1:400361196721:secret:terraform/secret1-cRy7lp|02959A9C-7AA3-48F7-B479-504BFC4F7547]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.


檢視資源狀態

輸入terraform show檢視terraform.tfstate目前的資源狀態。

$ terraform show
# aws_secretsmanager_secret.demo_secret:
resource "aws_secretsmanager_secret" "demo_secret" {
    arn                            = "arn:aws:secretsmanager:ap-northeast-1:400361196721:secret:terraform/secret1-cRy7lp"
    force_overwrite_replica_secret = false
    id                             = "arn:aws:secretsmanager:ap-northeast-1:400361196721:secret:terraform/secret1-cRy7lp"
    name                           = "terraform/secret1"
    recovery_window_in_days        = 7
    rotation_enabled               = false
    tags_all                       = {}
}

# aws_secretsmanager_secret_version.demo_secret_value:
resource "aws_secretsmanager_secret_version" "demo_secret_value" {
    arn            = "arn:aws:secretsmanager:ap-northeast-1:400361196721:secret:terraform/secret1-cRy7lp"
    id             = "arn:aws:secretsmanager:ap-northeast-1:400361196721:secret:terraform/secret1-cRy7lp|02959A9C-7AA3-48F7-B479-504BFC4F7547"
    secret_id      = "arn:aws:secretsmanager:ap-northeast-1:400361196721:secret:terraform/secret1-cRy7lp"
    secret_string  = (sensitive value)
    version_id     = "02959A9C-7AA3-48F7-B479-504BFC4F7547"
    version_stages = [
        "AWSCURRENT",
    ]
}


確認secret已建立

在AWS console的Secerts Manager確認secret已建立,可看到Terraform建立的secret terraform/secret1



terraform/secret1的secret值。



github


刪除secret

main.tf的Secrets Manager配置移除後執行terraform applyterraform/secret1刪除。

~/../terraform-demo$ terraform apply
aws_secretsmanager_secret_version.demo_secret_value: Refreshing state... [id=arn:aws:secretsmanager:ap-northeast-1:400361196721:secret:terraform/secret1-cRy7lp|02959A9C-7AA3-48F7-B479-504BFC4F7547]
aws_secretsmanager_secret.demo_secret: Refreshing state... [id=arn:aws:secretsmanager:ap-northeast-1:400361196721:secret:terraform/secret1-cRy7lp]

...

Terraform used the selected providers to generate the following execution plan. Resource actions are
indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  # aws_secretsmanager_secret.demo_secret will be destroyed
  - resource "aws_secretsmanager_secret" "demo_secret" {
      - arn                            = "arn:aws:secretsmanager:ap-northeast-1:400361196721:secret:terraform/secret1-cRy7lp" -> null
      - force_overwrite_replica_secret = false -> null
      - id                             = "arn:aws:secretsmanager:ap-northeast-1:400361196721:secret:terraform/secret1-cRy7lp" -> null
      - name                           = "terraform/secret1" -> null
      - recovery_window_in_days        = 7 -> null
      - rotation_enabled               = false -> null
      - tags                           = {} -> null
      - tags_all                       = {} -> null
    }

  # aws_secretsmanager_secret_version.demo_secret_value will be destroyed
  - resource "aws_secretsmanager_secret_version" "demo_secret_value" {
      - arn            = "arn:aws:secretsmanager:ap-northeast-1:400361196721:secret:terraform/secret1-cRy7lp" -> null
      - id             = "arn:aws:secretsmanager:ap-northeast-1:400361196721:secret:terraform/secret1-cRy7lp|02959A9C-7AA3-48F7-B479-504BFC4F7547" -> null
      - secret_id      = "arn:aws:secretsmanager:ap-northeast-1:400361196721:secret:terraform/secret1-cRy7lp" -> null
      - secret_string  = (sensitive value)
      - version_id     = "02959A9C-7AA3-48F7-B479-504BFC4F7547" -> null
      - version_stages = [
          - "AWSCURRENT",
        ] -> null
    }

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

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_secretsmanager_secret_version.demo_secret_value: Destroying... [id=arn:aws:secretsmanager:ap-northeast-1:400361196721:secret:terraform/secret1-cRy7lp|02959A9C-7AA3-48F7-B479-504BFC4F7547]
aws_secretsmanager_secret_version.demo_secret_value: Destruction complete after 0s
aws_secretsmanager_secret.demo_secret: Destroying... [id=arn:aws:secretsmanager:ap-northeast-1:400361196721:secret:terraform/secret1-cRy7lp]
aws_secretsmanager_secret.demo_secret: Destruction complete after 0s

Apply complete! Resources: 0 added, 0 changed, 2 destroyed.


確認secret已刪除

在AWS console檢視Secrets Manager的Secrets可以看到之前建立的terraform/secret1不見了。



開啟Secrets的[Preferences]並勾選[Show secrets scheduled for deletion]可看到已安排刪除的secrets,包括terraform/secret1






重建secret

回復main.tf原本建立terraform/secret1的配置,執行terraform apply會出現該secret已排入刪除無法建立的錯誤訊息:

Error: error creating Secrets Manager Secret: InvalidRequestException: You can't create this secret because a secret with this name is already scheduled for deletion.

~/../terraform-demo$ terraform apply
...
aws_secretsmanager_secret.demo_secret: Creating...
...
aws_secretsmanager_secret.demo_secret: Still creating... [2m0s elapsed]
╷
│ Error: error creating Secrets Manager Secret: InvalidRequestException: You can't create this secret because a secret with this name is already scheduled for deletion.
│
│   with aws_secretsmanager_secret.demo_secret,
│   on main.tf line 17, in resource "aws_secretsmanager_secret" "demo_secret":
│   17: resource "aws_secretsmanager_secret" "demo_secret" {
│
╵


取消刪除secret

在AWS console進入已安排刪除的terraform/secret1點選[Cancel deletion]取消刪除。



然後執行原本建立terraform/secret1的配置,會出現secret已存在的錯誤:

Error: error creating Secrets Manager Secret: ResourceExistsException: The operation failed because the secret terraform/secret1 already exists.

aws_secretsmanager_secret.demo_secret: Creating...
╷
│ Error: error creating Secrets Manager Secret: ResourceExistsException: The operation failed because the secret terraform/secret1 already exists.
│
│   with aws_secretsmanager_secret.demo_secret,
│   on main.tf line 17, in resource "aws_secretsmanager_secret" "demo_secret":
│   17: resource "aws_secretsmanager_secret" "demo_secret" {
│
╵

所以從AWS console取消刪除的terraform/secret1已不被原來的terraform狀態掌握。


強制刪除secret

可在AWS CLI輸入下面指令強制立刻刪除secret來解決無法重建的問題:

aws secretsmanager delete-secret --secret-id your-secret --force-delete-without-recovery --region your-region

your-secret改成要立刻刪除的secret名稱。範例為terraform/secret1
your-region改成要立刻刪除secret所在的region。範例為ap-northeast-1

$ aws secretsmanager delete-secret --secret-id terraform/secret1 --force-delete-without-recovery --region ap-northeast-1
{
    "ARN": "arn:aws:secretsmanager:ap-northeast-1:400361196721:secret:terraform/secret1-cRy7lp",
    "Name": "terraform/secret1",
    "DeletionDate": "2021-12-23T09:36:02.907000+08:00"
}

此刪除指令為異步執行所以會有點延遲,稍微等一下在AWS console Secrets Manager就看到terraform/secret1已經完全不見了。


設定secret recover window為0

把原本main.tf的resource aws_secretsmanager_secret屬性recovery_window_in_days設為0,則terraform刪除secret時會立刻刪除而非進入刪除排程。

resource "aws_secretsmanager_secret" "demo_secret" {
  name                    = "terraform/secret1"
  recovery_window_in_days = 0
}



沒有留言:

張貼留言