All Products
Search
Document Center

Key Management Service:Create a secret with Terraform

Last Updated:Apr 07, 2025

You can use Terraform to create and manage secrets. This topic describes how to create one.

Prerequisites

  • You have created a Resource Access Management (RAM) user and AccessKey pair for it. For instructions, see Create a RAM user and Create an AccessKey pair.

    To ensure security, we recommend using RAM users instead of an Alibaba Cloud account to manage your resources. The Alibaba Cloud account has full access to all resources, and if it is compromised, there will be significant security risks.

  • You have granted the RAM user the following permissions:

    • AliyunKMSFullAccess: Manage Key Management Service (KMS).

    • AliyunRAMFullAccess: Manage permissions for RAM access control.

      For instructions, see Grant permissions to a RAM user.

      An example of authorization policy

      {
          "Version": "1",
          "Statement": [
              {
                  "Action": "kms:*",
                  "Resource": "*",
                  "Effect": "Allow"
              },
              {
                  "Action": "ram:CreateServiceLinkedRole",
                  "Condition": {
                      "StringEquals": {
                          "ram:ServiceName": [
                              "secretsmanager-rds.kms.aliyuncs.com",
                              "keystore.kms.aliyuncs.com"
                          ]
                      }
                  },
                  "Resource": "*",
                  "Effect": "Allow"
              }
          ]
      }
  • You have prepared the Terraform environment.

    Ensure you are using Terraform V0.12.28 or later. To check your current version, run the command terraform --version.

    Environment preparation

    • Using Terraform Explorer: This tool, provided by Alibaba Cloud, allows users to debug Terraform configuration files online without installation. Based on the open-source Terraform, it enables quick and convenient debugging at zero cost. After logging in, you can get started immediately.

    • Using Terraform in Cloud Shell: Terraform components are pre-installed in Alibaba Cloud Cloud Shell, and the identity credentials are already configured. You can run Terraform commands directly in Cloud Shell for quick, low-cost access.

    • Install and configure Terraform: Suitable for situations where network connectivity is poor or where a custom development environment is needed.

Resources used

Procedure

Important

We recommend that you specify sensitive = true in secret_data to avoid printing sensitive secret values in logs or in the KMS console. For more information, see Protect sensitive input variables.

  1. Create a working directory and a file named main.tf in the directory.

    1. Add the following content to the main.tf file to create a KMS instance, and a symmetric key that is used to encrypt secret values.

      KMS uses keys to encrypt and protect secrets. To create a secret, you must first create a key. For more information about secrets, see Secrets.

      • Create a KMS instance:

        variable "region" {
          default = "Singapore"
        }
        provider "alicloud" {
          region = var.region
        }
        variable "instance_name" {
          default = "tf-kms-vpc-172-16"
        }
        # Create a VPC.
        resource "alicloud_vpc" "vpc" {
          vpc_name   = var.instance_name
          cidr_block = "192.168.0.0/16"
        }
        # Create a vSwitch with CIDR block of 192.168.10.0/24.
        resource "alicloud_vswitch" "vsw" {
          vpc_id     = alicloud_vpc.vpc.id
          cidr_block = "192.168.10.0/24"
          zone_id    = "ap-southeast-1a"
          vswitch_name = "terraform-example-1"
        }
        # Create another vSwitch with CIDR block of 192.168.20.0/24.
        resource "alicloud_vswitch" "vsw1" {
          vpc_id     = alicloud_vpc.vpc.id
          cidr_block = "192.168.20.0/24"
          zone_id    = "ap-southeast-1b"
          vswitch_name = "terraform-example-2"
        }
        # Create a KMS software key management instance and launch it using network parameters.
        resource "alicloud_kms_instance" "default" {
          # Software key management instance.
          product_version = "3"
          vpc_id          = alicloud_vpc.vpc.id
          # Specify zones for the KMS instance, using the previously obtained zone IDs.
          zone_ids = [
            "ap-southeast-1a",
            "ap-southeast-1b",
          ]
          # vSwitch IDs.
          vswitch_ids = [
            alicloud_vswitch.vsw.id,alicloud_vswitch.vsw1.id
          ]
          # Specify the number of VPC, number of keys, number of secrets, number of access management,and computing performance(QPS).
          vpc_num    = "1"
          key_num    = "1000"
          secret_num = "100"
          spec       = "1000"
          # Optional. Associate other VPCs with the KMS instance. 
          # If the VPC and the KMS instance's VPC belong to different Alibaba Cloud accounts, you need to share the VSwitch first.
          #bind_vpcs {
          #vpc_id = "vpc-j6cy0l32yz9ttxfy6****"
          #vswitch_id = "vsw-j6cv7rd1nz8x13ram****"
          #region_id = "Malaysia (Kuala Lumpur)"
          #vpc_owner_id = "119285303511****"
          #}
          #bind_vpcs {
          #vpc_id = "vpc-j6cy0l32yz9ttd7g3****"
          #vswitch_id = "vsw-3h4yrd1nz8x13ram****"
          #region_id = "Malaysia (Kuala Lumpur)"
          #vpc_owner_id = "119285303511****"
          #}
        }
        # Save the KMS instance CA certificate to a local file.
         resource "local_file" "ca_certificate_chain_pem" {
         content  = alicloud_kms_instance.default.ca_certificate_chain_pem
         filename = "ca.pem"
        }
      • Create a symmetric key within the KMS instance:

        # The key specification is Aliyun_AES_256, and the key usage is encryption and decryption (ENCRYPT/DECRYPT)
        resource "alicloud_kms_key" "kms_software_key_encrypt_decrypt" {
          description = "default_key_encrypt_decrypt description"
          # The key usage. Default value: ENCRYPT/DECRYPT. Valid values: ENCRYPT/DECRYPT: Encrypt or decrypt data.
          key_usage = "ENCRYPT/DECRYPT"
          # The key specification. Default value: Aliyun_AES_256.
          key_spec = "Aliyun_AES_256"
          # The ID of the KMS instance.
          dkms_instance_id       = alicloud_kms_instance.default.id
          pending_window_in_days = 7
          # Optional. The tag mapping to assign to the resource.
          # tags = {
            # "Environment" = "Production"
            # "Name"        = "KMS-01"
            # "SupportTeam" = "PlatformEngineering"
            # "Contact"     = "ali***@test.com"
          # }
        }
        # The key alias is alias/kms_software_key_encrypt_decrypt, which is unique within Alibaba Cloud account.
        resource "alicloud_kms_alias" "kms_software_key_encrypt_decrypt_alias" {
          # Alias
          alias_name = "alias/kms_software_key_encrypt_decrypt"
          # Key ID
          key_id = alicloud_kms_key.kms_software_key_encrypt_decrypt.id
        }
    2. Add the following content to main.tf to create secrets.

      • Create a generic secret:

        # Create a generic secret. The secret name is kms_secret_general1, and the secret value is secret_data_kms_secret_general1.
        resource "alicloud_kms_secret" "kms_secret_general" {
          # Name.
          secret_name = "kms_secret_general1"
          # Description.
          description = "secret_data_kms_secret_general"
          # Type.
          secret_type = "Generic"
          # Specify whether to delete immediately. Default value: false. Valid values: true, false.
          force_delete_without_recovery = true
          # The ID of the KMS instance.
          dkms_instance_id = alicloud_kms_instance.default.id
          # The ID of the KMS key.
          encryption_key_id = alicloud_kms_key.kms_software_key_encrypt_decrypt.id
          # Version number.
          version_id = "v1"
          # The type of value. Default value: text. Valid values: text, binary.
          secret_data_type = "text"
          # Data.
          secret_data = "secret_data_kms_secret_general1"
        }
      • Create a RAM secret:

        # An example of creating a RAM secret.
        # The prerequisite is that you have created a RAM user and AccessKey that need to host the RAM secret.
        # Two steps are required.
        
        # Step 1: Grant the KMS permission to manage the RAM user's AccessKey.
        # 1.1 Create a custom permission policy AliyunKMSManagedRAMCrendentialsRolePolicy.
        resource "alicloud_ram_policy" "AliyunKMSManagedRAMCrendentialsRolePolicy" {
          policy_name     = "AliyunKMSManagedRAMCrendentialsRolePolicy"
          policy_document = <<EOF
          {
              "Version": "1",
              "Statement": [
                  {
                      "Effect": "Allow",
                      "Action": [
                          "ram:ListAccessKeys",
                          "ram:CreateAccessKey",
                          "ram:DeleteAccessKey",
                          "ram:UpdateAccessKey"
                      ],
                      "Resource": "*"
                  }
              ]
          }
          EOF
          description     = "AliyunKMSManagedRAMCrendentialsRolePolicy"
          force           = true
        }
        
        # 1.2 Create a RAM role AliyunKMSManagedRAMCrendentialsRole.
        resource "alicloud_ram_role" "AliyunKMSManagedRAMCrendentialsRole" {
          name        = "AliyunKMSManagedRAMCrendentialsRole"
          description = "AliyunKMSManagedRAMCrendentialsRole"
          document    = <<EOF
          {
            "Statement": [
              {
                "Action": "sts:AssumeRole",
                "Effect": "Allow",
                "Principal": {
                  "Service": [
                    "kms.aliyuncs.com"
                  ]
                }
              }
            ],
            "Version": "1"
          }
          EOF
          force       = true
        }
        
        # 1.3 Grant the RAM role AliyunKMSManagedRAMCrendentialsRole the AliyunKMSManagedRAMCrendentialsRolePolicy.
        resource "alicloud_ram_role_policy_attachment" "attach" {
          policy_name = alicloud_ram_policy.AliyunKMSManagedRAMCrendentialsRolePolicy.policy_name
          policy_type = alicloud_ram_policy.AliyunKMSManagedRAMCrendentialsRolePolicy.type
          role_name   = alicloud_ram_role.AliyunKMSManagedRAMCrendentialsRole.name
        }
        
        # Step 2: Create RAM credentials.
        resource "alicloud_kms_secret" "kms_secret_RAMCredentials" {
          # Secret name.
          secret_name = "my_secret"
          # Description.
          description = "secret_kms_secret_RAMCredentials"
          # Type of the secret.
          secret_type = "RAMCredentials"
          # KMS instance ID.
          dkms_instance_id = alicloud_kms_instance.default.id
          # The ID of the key used to encrypt the secret value.
          encryption_key_id = alicloud_kms_key.kms_software_key_encrypt_decrypt.id
          # Specify whether to delete the secret immediately. Default value: false. Valid values: true, false.
          force_delete_without_recovery = true
          # Specify whether to enable automatic rotation. Default value: false. Valid values: true, false.
          enable_automatic_rotation = true
          # Interval for automatic rotation.
          rotation_interval = "7d"
          # Extended configuration. Replace with your UserName.
          extended_config = "{\"SecretSubType\":\"RamUserAccessKey\", \"UserName\":\"testuser\"}" 
          # Version.
          version_id = "V1"
          # Type of the secret value. Default value: text. Valid values: text, binary.
          secret_data_type ="text"
          # Data.
          secret_data = "{\"AccessKeys\":[{\"AccessKeyId\":\"LTAI****************\",\"AccessKeySecret\":\"yourAccessKeySecret\"}]}"
        }
      • Create an ApsaraDB RDS secret in Manage Dual Account mode:

        variable "region" {
          default = "Singapore"
        }
        
        provider "alicloud" {
          region = var.region
        }
        
        variable "zone_id" {
          default = "ap-southeast-1a"
        }
        
        variable "instance_type" {
          default = "pg.n2.2c.2m"
        }
        
        # Create a VPC.
        resource "alicloud_vpc" "main" {
          vpc_name   = "alicloud"
          cidr_block = "172.16.0.0/16"
        }
        
        # Create a vSwitch.
        resource "alicloud_vswitch" "main" {
          vpc_id     = alicloud_vpc.main.id
          cidr_block = "172.16.192.0/20"
          zone_id    = var.zone_id
          depends_on = [alicloud_vpc.main]
        }
        
        # Create an RDS PostgreSQL instance.
        resource "alicloud_db_instance" "instance" {
          engine               = "PostgreSQL"
          engine_version       = "13.0"
          instance_type        = var.instance_type
          instance_storage     = "30"
          instance_charge_type = "Postpaid"
          vswitch_id           = alicloud_vswitch.main.id
         
        }
        # Create an RDS secret.
        resource "alicloud_kms_secret" "kms_secret_RDS_MYSQL" {
          # Secret name.
          secret_name = "rds_secret/${alicloud_db_instance.id}"
          # Type.
          secret_type = "Rds"
          # KMS instance ID.
          dkms_instance_id = alicloud_kms_instance.default.id
          # The ID of the key used to encrypt the secret value.
          encryption_key_id = alicloud_kms_key.kms_software_key_encrypt_decrypt.id
          # Specify whether to enable automatic rotation. Default value: false. Valid values: true, false.
          enable_automatic_rotation = true
          # Interval for automatic rotation.
          rotation_interval = "7d"
          # Specify whether to delete immediately. Default value: false. Valid values: true, false.
          force_delete_without_recovery = true
          # Configuration.
          extended_config = "{\"SecretSubType\":\"DoubleUsers\", \"DBInstanceId\":\"rm-7xv1450tq4pj4****\" ,\"CustomData\": {}}"
          # Version.
          version_id = "V1"
          # Type of secret value. Default value: text. Valid values: text, binary.
          secret_data_type = "text"
          # Data.
          secret_data = "{\"Accounts\":[{\"AccountName\":\"rdsuser1\",\"AccountPassword\":\"Admin****\"},{\"AccountName\":\"rdsuser2\",\"AccountPassword\":\"Admin****\"}]}"
        }
  2. Run the terraform init command to initialize Terraform.

    This command downloads the necessary providers and initializes the Terraform backend. You'll see output similar to this:

    Terraform has created a lock file .terraform.lock.hcl to record the provider selections...Include this file in your version control repository...
    
    Terraform has been successfully initialized!
    
    You may now begin working with Terraform. Try running "terraform plan" to see any changes...
  3. Run the terraform plan command to plan and preview changes.

    This command creates an execution plan, detailing the resources that Terraform will create, modify, or destroy. Carefully review the output to ensure it matches your expectations.

  4. Run the terraform apply command to apply the configuration.

    Terraform will prompt you to confirm the changes. Type yes and press Enter to proceed. You'll see output indicating the progress of resource creation. Successful completion looks like this:

    alicloud_kms_key.kms_software_key_encrypt_decrypt: Creation complete after 0s ...
    ...
    Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
    
  5. Verify the result.

    You can verify the creation of secrets in the following two ways:

    • Using terraform show.

      This command displays the current state of your infrastructure, including the attributes of the created resources.

    • Using the KMS console.

      1. Log on to the KMS console, and in the top navigation bar, select the target region.

      2. In the left-side navigation pane, choose Resource > Secrets to verify the secrets you have created.

Clean up resources

If you no longer require the resources previously created or managed by Terraform, you can run the terraform destroy command to remove them. For more information , see Common commands.

Sample code

Important

The sample code in this topic supports one-click execution. You can run the code directly.

variable "region" {
  default = "Singapore"
}
provider "alicloud" {
  region = var.region
}
variable "instance_name" {
  default = "tf-kms-vpc-172-16"
}
# Create a VPC resource "alicloud_vpc" "vpc" {
  vpc_name   = var.instance_name
  cidr_block = "192.168.0.0/16"
}
# Create a vSwitch with a CIDR block of 192.168.10.0/24resource "alicloud_vswitch" "vsw" {
  vpc_id     = alicloud_vpc.vpc.id
  cidr_block = "192.168.10.0/24"
  zone_id    = "ap-southeast-1a"
  vswitch_name = "terraform-example-1"
}
# Create another vSwitch with a CIDR block of 192.168.20.0/24resource "alicloud_vswitch" "vsw1" {
  vpc_id     = alicloud_vpc.vpc.id
  cidr_block = "192.168.20.0/24"
  zone_id    = "ap-southeast-1b"
  vswitch_name = "terraform-example-2"
}
# Create a KMS software key management instance and start it with network parametersresource "alicloud_kms_instance" "default" {
  # Software key management instance
  product_version = "3"
  vpc_id          = alicloud_vpc.vpc.id
  # Specify the zone where the KMS instance is located. Use the zone ID obtained earlier.
  zone_ids = [
    "ap-southeast-1a",
    "ap-southeast-1b",
  ]
  # vSwitch IDs
  vswitch_ids = [
    alicloud_vswitch.vsw.id,alicloud_vswitch.vsw1.id
  ]
  # Compute performance, number of keys, number of credentials, number of access management
  vpc_num    = "1"
  key_num    = "1000"
  secret_num = "100"
  spec       = "1000"
}
# Save the KMS instance CA certificate to a local fileresource "local_file" "ca_certificate_chain_pem" {
 content  = alicloud_kms_instance.default.ca_certificate_chain_pem
 filename = "ca.pem"
}
# The key specification is Aliyun_AES_256, and the key usage is encryption and decryption (ENCRYPT/DECRYPT)resource "alicloud_kms_key" "kms_software_key_encrypt_decrypt" {
  timeouts {
    delete = "30m" # Set a timeout for deletion
  }
  description = "default_key_encrypt_decrypt description"# The key usage. Default value: ENCRYPT/DECRYPT. Valid values: ENCRYPT/DECRYPT: Encrypt or decrypt data.
  key_usage = "ENCRYPT/DECRYPT"# The key specification. Default value: Aliyun_AES_256.
  key_spec = "Aliyun_AES_256"# The ID of the KMS instance.
  dkms_instance_id       = alicloud_kms_instance.default.id
  pending_window_in_days = 7
}
# The key alias is alias/kms_software_key_encrypt_decrypt, which is unique across the entire Alibaba Cloud account.resource "alicloud_kms_alias" "kms_software_key_encrypt_decrypt_alias" {
  # Alias
  alias_name = "alias/kms_software_key_encrypt_decrypt"# Key ID
  key_id = alicloud_kms_key.kms_software_key_encrypt_decrypt.id
}
# Create a generic credential. The credential name is kms_secret_general1, and the credential value is secret_data_kms_secret_general1resource "alicloud_kms_secret" "kms_secret_general" {
  # Name
  secret_name = "kms_secret_general1"# Description
  description = "secret_data_kms_secret_general"# Type
  secret_type = "Generic"# Specify whether to delete immediately. Default value: false. Valid values: true, false.
  force_delete_without_recovery = true
  # The ID of the KMS instance.
  dkms_instance_id = alicloud_kms_instance.default.id
  # The ID of the KMS key
  encryption_key_id = alicloud_kms_key.kms_software_key_encrypt_decrypt.id
  # Version number
  version_id = "v1"# The type of value. Default value: text. Valid values: text, binary.
  secret_data_type = "text"# Data
  secret_data = "secret_data_kms_secret_general1"
}