You can use Terraform to create and manage secrets. This topic provides an example of how to create a secret.
Overview
Key Management Service (KMS) uses a specified key to encrypt and protect secrets. Therefore, you must create a key before you create a secret. For more information about secrets, see Overview of Secrets Management.
Usage notes
An Alibaba Cloud account has full permissions on all resources. If the credentials of an Alibaba Cloud account are leaked, your resources are exposed to high security risks. As a security best practice, create a Resource Access Management (RAM) user and an AccessKey pair for the RAM user. For more information, see Create a RAM user and Create an AccessKey pair.
Grant the RAM user the following permissions: AliyunKMSFullAccess (for managing Key Management Service) and AliyunRAMFullAccess (for managing Resource Access Management). For more information, see Grant permissions to a RAM user.
{ "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" } ] }Prepare a Terraform environment. You can use Terraform in one of the following ways:
Use Terraform in Terraform Explorer: Alibaba Cloud provides an online environment for Terraform where you do not need to install Terraform. You can use and test Terraform online after you log on. This method is suitable for scenarios where you want to quickly and conveniently test and debug Terraform at no cost.
Cloud Shell: Terraform components are pre-installed in Alibaba Cloud Cloud Shell and identity credentials are configured. You can run Terraform commands directly in Cloud Shell. This method is suitable for scenarios where you want to access and use Terraform in a fast, convenient, and low-cost way.
Install and configure Terraform on your computer: This method is suitable for scenarios where you have poor network connectivity or need a custom development environment.
Your Terraform version must be v0.12.28 or later. To check the version, run the terraform --version command.
Resources used
alicloud_kms_secret: Creates and manages secrets.
alicloud_vpc: Creates a virtual private cloud (VPC).
alicloud_vswitch: Creates a virtual switch (vSwitch) to divide a VPC into one or more subnets.
alicloud_kms_instance: Purchases and enables a software key management instance.
alicloud_kms_key: Creates and manages keys.
alicloud_kms_alias: Creates and manages aliases.
Procedure
Set sensitive = true for secret_data (the secret value) to prevent sensitive secret values from being printed in logs or on the console. For more information, see Protect Sensitive Input Variables.
This example shows how to create a generic secret.
Create a working directory and create a configuration file named
main.tfin the directory.Add the following content to
main.tf. Before you proceed, make sure that you have created a KMS instance and a key:ImportantThe key used to encrypt the secret value must be a symmetric key.
Create a KMS instance:
variable "region" { default = "cn-heyuan" } 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 the CIDR block 192.168.10.0/24. resource "alicloud_vswitch" "vsw" { vpc_id = alicloud_vpc.vpc.id cidr_block = "192.168.10.0/24" zone_id = "cn-heyuan-a" vswitch_name = "terraform-example-1" } # Create another vSwitch with the CIDR block 192.168.20.0/24. resource "alicloud_vswitch" "vsw1" { vpc_id = alicloud_vpc.vpc.id cidr_block = "192.168.20.0/24" zone_id = "cn-heyuan-b" vswitch_name = "terraform-example-2" } # Create a software key management instance and start it with network parameters. resource "alicloud_kms_instance" "default" { # Software key management instance. product_version = "3" vpc_id = alicloud_vpc.vpc.id # Specify the zones for the KMS instance. Use the zone IDs obtained earlier. zone_ids = [ "cn-heyuan-a", "cn-heyuan-b", ] # vSwitch IDs. vswitch_ids = [ alicloud_vswitch.vsw.id,alicloud_vswitch.vsw1.id ] # Computing performance, number of keys, number of secrets, and number of access management operations. 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 must first share the vSwitch. #bind_vpcs { #vpc_id = "vpc-j6cy0l32yz9ttxfy6****" #vswitch_id = "vsw-j6cv7rd1nz8x13ram****" #region_id = "cn-shanghai" #vpc_owner_id = "119285303511****" #} #bind_vpcs { #vpc_id = "vpc-j6cy0l32yz9ttd7g3****" #vswitch_id = "vsw-3h4yrd1nz8x13ram****" #region_id = "cn-shanghai" #vpc_owner_id = "119285303511****" #} } # Save the CA certificate of the KMS instance 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 key in the KMS instance:
# The key has a specification of Aliyun_AES_256 and is used for encryption and decryption (ENCRYPT/DECRYPT). resource "alicloud_kms_key" "kms_software_key_encrypt_decrypt" { description = "default_key_encrypt_decrypt description" # The usage of the key. Default: ENCRYPT/DECRYPT. Valid value: ENCRYPT/DECRYPT, which indicates that the key is used to encrypt or decrypt data. key_usage = "ENCRYPT/DECRYPT" # The specification of the key. Default: 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 map of tags 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 must be unique within the 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 }Add the following content to
main.tfto create a secret.Generic secret
# Create a generic secret named kms_secret_general1 with the value 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" # Specifies whether to immediately delete the secret. Default: 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 ID. version_id = "v1" # The type of the value. Default: text. Valid values: text, binary. secret_data_type = "text" # Data. secret_data = "secret_data_kms_secret_general1" }RAM secret
# Example of creating a RAM secret. # Before you start, create a RAM user and an AccessKey for which you want to create a managed RAM secret. # This process consists of two steps. # Step 1: Grant KMS the permissions to manage the AccessKey of the RAM user. # 1.1 Create a custom policy named 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 named 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 Attach the AliyunKMSManagedRAMCrendentialsRolePolicy policy to the AliyunKMSManagedRAMCrendentialsRole role. 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 the RAM secret. resource "alicloud_kms_secret" "kms_secret_RAMCredentials" { # The name of the secret. secret_name = "my_secret" # The description. description = "secret_kms_secret_RAMCredentials" # The type of the secret. secret_type = "RAMCredentials" # The ID of the KMS instance. 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 # Specifies whether to immediately delete the secret. Default: false. Valid values: true, false. force_delete_without_recovery = true # Specifies whether to enable automatic rotation. Default: false. Valid values: true, false. enable_automatic_rotation = true # The interval for automatic rotation. rotation_interval = "7d" # The extended configuration. Replace the value of UserName with your username. extended_config = "{\"SecretSubType\":\"RamUserAccessKey\", \"UserName\":\"testuser\"}" # Version. version_id = "V1" # The type of the secret value. Default: text. Valid values: text, binary. secret_data_type ="text" # Data. secret_data = "{\"AccessKeys\":[{\"AccessKeyId\":\"LTAI****************\",\"AccessKeySecret\":\"yourAccessKeySecret\"}]}" }RDS secret
This example shows how to create an RDS secret in dual-account hosting mode.
variable "region" { default = "cn-hangzhou" } provider "alicloud" { region = var.region } variable "zone_id" { default = "cn-hangzhou-b" } 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 ApsaraDB RDS for 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" { # The name of the secret. secret_name = "rds_secret/${alicloud_db_instance.instance.id}" # Type. secret_type = "Rds" # The ID of the KMS instance. 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 # Specifies whether to enable automatic rotation. Default: false. Valid values: true, false. enable_automatic_rotation = true # The interval for automatic rotation. rotation_interval = "7d" # Specifies whether to immediately delete the secret. Default: false. Valid values: true, false. force_delete_without_recovery = true # Configuration. extended_config = "{\"SecretSubType\":\"DoubleUsers\", \"DBInstanceId\":\"rm-7xv1450tq4pj4****\" ,\"CustomData\": {}}" # Version. version_id = "V1" # The type of the secret value. Default: text. Valid values: text, binary. secret_data_type = "text" # Data. secret_data = "{\"Accounts\":[{\"AccountName\":\"rdsuser1\",\"AccountPassword\":\"Admin****\"},{\"AccountName\":\"rdsuser2\",\"AccountPassword\":\"Admin****\"}]}" }
Run the following command to initialize the Terraform environment.
terraform initTerraform has created a lock file .terraform.lock.hcl to record the provider selections it made above. Include this file in your version control repository so that Terraform can guarantee to make the same selections by default when you run "terraform init" in the future. Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure. All Terraform commands should now work. If you ever set or change modules or backend configuration for Terraform, rerun this command to reinitialize your working directory. If you forget, other commands will detect it and remind you to do so if necessary.Create an execution plan and preview the changes.
terraform planRun the following command to create the generic secret.
terraform applyAt the prompt, enter
yesand press Enter. Wait for the command to complete. If the following output is returned, the generic secret was created.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 ... alicloud_kms_key.kms_software_key_encrypt_decrypt: Creation complete after 0s [id=key-shh6715c21812y8i7z***] alicloud_kms_alias.kms_software_key_encrypt_decrypt_alias: Creating... alicloud_kms_secret.kms_secret_general: Creating... alicloud_kms_alias.kms_software_key_encrypt_decrypt_alias: Creation complete after 0s [id=alias/kms_secret] alicloud_kms_secret.kms_secret_general: Creation complete after 1s [id=kms_secret_general1] ... Apply complete! Resources: 2 added, 0 changed, 0 destroyed.Verify the results.
Run the terraform show command
Run the following command to query the details of the resources that you created using Terraform:
terraform show
Log on to the Key Management Service console
Log on to the Key Management Service console to view the secret that you created.
Clean up resources
If you no longer need the resources that were created or managed by Terraform, run the following command to release them. For more information about the terraform destroy command, see Common commands.
terraform destroy