Welcome to Day 15 of 21 Days of AWS using Terraform. The topic for today is Introduction to KMS using Terraform.
What is KMS?
AWS Key Management Service (AWS KMS) is a managed service that makes it easy for you to create and control the encryption keys used to encrypt your data.
Advantage
- We can use IAM Policies for KMS access
- AWS Services(RDS,S3,DynamoDB,EBS…) integrated directly with KMS https://docs.aws.amazon.com/kms/latest/developerguide/service-integration.html
- It uses FIPS 140–2 compliant hardware module to manage access to key material.
- Integrated fully with CloudTrail for auditing function
Concepts
- KMS stores Customer Master Keys(CMK) which is a logical representation of a key.
- Key can be generated by KMS or imported.
- The encrypted data keys are stored with the data
- CMK never leaves KMS and never leaves a region
- CMK can encrypt or decrypt data up to 4KB in size.
How KMS Encrypt Data
Reference: https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#enveloping
- We start with the plain text and then uses data keys along with an algorithm and come up with encrypted data.
- Encrypted data is finally stored in a storage that can be anything(eg:EBS, EFS, S3…)
- KMS then took data key, Encrypt it with a master key along with an encryption algorithm, resulted in it an encrypted data key, that stored alongside with data.
KMS in action
# To access KMS
Go to AWS Console --> Security, Identity, & Compliance --> Key Management Service --> Create a key
NOTE: YAY!!!, Now Key Management Service got its a new home but you can still access it via old way i.e
AWS Console --> IAM --> Encryption keys
Step1:
* Alias: Enter an alias and descrption for the key(eg: Alias: mydemotestkey, similarly Descrption)
* Key material origin: Choose KMS(External: You can bring your own Key(BUOY),CloudHSM(More about it later)
Step2:
* Adding Tag is Optional but its a good practice
resource "aws_kms_key" "my-kms-key" {
description = "My KMS Keys for Data Encryption"
enable_key_rotation = true
tags = {
Name = "my-kms-keys"
}
resource "aws_kms_alias" "smc-kms-alias" {
target_key_id = "${aws_kms_key.my-kms-key.key_id}"
name = "alias/my-terraform-final-encryption-key"
}
Step3:
- Choose the users and roles who can administer this key.
- This is critical as an administrator have right to delete these keys and after that, your data will become unusable
Step4: Define key usage permissions,select the IAM users and roles that can use the CMK to encrypt and decrypt data with the AWS KMS API
Step5: Review and edit key policy
Key Deletion
- You can’t delete key immediately, rather then you need to schedule it
- The waiting period is from 7–30 days, this is to make sure you understand that deleting a key makes all data encrypted under that key unrecoverable
- AWS managed CMKs. You cannot manage key rotation for AWS managed CMKs. AWS KMS automatically rotates AWS managed keys every three years (1095 days).
- When you enable automatic key rotation, AWS KMS rotates the CMK 365 days after the enable date and every 365 days thereafter.
policy = <<EOF
{
"Id": "key-consolepolicy-3",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "${var.user_arn}"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow access for Key Administrators",
"Effect": "Allow",
"Principal": {
"AWS": "${var.user_arn}"
},
"Action": [
"kms:Create*",
"kms:Describe*",
"kms:Enable*",
"kms:List*",
"kms:Put*",
"kms:Update*",
"kms:Revoke*",
"kms:Disable*",
"kms:Get*",
"kms:Delete*",
"kms:TagResource",
"kms:UntagResource",
"kms:ScheduleKeyDeletion",
"kms:CancelKeyDeletion"
],
"Resource": "*"
},
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Principal": {
"AWS": "${var.user_arn}"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*"
},
{
"Sid": "Allow attachment of persistent resources",
"Effect": "Allow",
"Principal": {
"AWS": "${var.user_arn}"
},
"Action": [
"kms:CreateGrant",
"kms:ListGrants",
"kms:RevokeGrant"
],
"Resource": "*",
"Condition": {
"Bool": {
"kms:GrantIsForAWSResource": "true"
}
}
}
]
}
EOF
}
variables.tf
variable "user_arn" {
}
Final KMS Module will look like this
module "kms" {
source = "./kms"
user_arn = "${module.iam.aws_iam_user}"
}
KMS Limits
NOTE: When a request is throttled, AWS KMS returns a ThrottlingException
error
GitHub Link
https://github.com/100daysofdevops/21_days_of_aws_using_terraform/tree/master/kms
Please join me with my journey by following any of the below link
- Website: https://100daysofdevops.com/
- Twitter: @100daysofdevops OR @lakhera2015
- Facebook: https://www.facebook.com/groups/795382630808645/
- Medium: https://medium.com/@devopslearning
- GitHub: https://github.com/100daysofdevops/100daysofdevops
- Slack: https://join.slack.com/t/100daysofdevops/shared_invite/enQtNzg1MjUzMzQzMzgxLWM4Yjk0ZWJiMjY4ZWE3ODBjZjgyYTllZmUxNzFkNTgxZjQ4NDlmZjkzODAwNDczOTYwOTM2MzlhZDNkM2FkMDA
- YouTube Channel: https://www.youtube.com/user/laprashant/videos?view_as=subscriber