diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..12911c9
--- /dev/null
+++ b/README.md
@@ -0,0 +1,185 @@
+
+
+
+
+ Terraform AWS KMS
+
+
+
+ This terraform module creates a KMS Customer Master Key (CMK) and its alias.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## Prerequisites
+
+This module has a few dependencies:
+
+- [Terraform 0.13](https://learn.hashicorp.com/terraform/getting-started/install.html)
+- [Go](https://golang.org/doc/install)
+- [github.com/stretchr/testify/assert](https://github.com/stretchr/testify)
+- [github.com/gruntwork-io/terratest/modules/terraform](https://github.com/gruntwork-io/terratest)
+
+## Examples
+
+
+**IMPORTANT:** Since the `master` branch used in `source` varies based on new modifications, we suggest that you use the release versions [here](https://github.com/devops4mecode/terraform-aws-kms/releases).
+
+
+### Simple Example
+Here is an example of how you can use this module in your inventory structure:
+```hcl
+ module "kms_key" {
+ source = "devops4mecode/kms/aws"
+ version = "0.13.0"
+ name = "kms"
+ application = "devops4me"
+ environment = "test"
+ label_order = ["environment", "application", "name"]
+ enabled = true
+ description = "KMS key for cloudtrail"
+ deletion_window_in_days = 7
+ enable_key_rotation = true
+ alias = "alias/cloudtrail"
+ policy = data.aws_iam_policy_document.default.json
+ }
+
+ data "aws_iam_policy_document" "default" {
+ version = "2012-10-17"
+ statement {
+ sid = "Enable IAM User Permissions"
+ effect = "Allow"
+ principals {
+ type = "AWS"
+ identifiers = ["*"]
+ }
+ actions = ["kms:*"]
+ resources = ["*"]
+ }
+ statement {
+ sid = "Allow CloudTrail to encrypt logs"
+ effect = "Allow"
+ principals {
+ type = "Service"
+ identifiers = ["cloudtrail.amazonaws.com"]
+ }
+ actions = ["kms:GenerateDataKey*"]
+ resources = ["*"]
+ condition {
+ test = "StringLike"
+ variable = "kms:EncryptionContext:aws:cloudtrail:arn"
+ values = ["arn:aws:cloudtrail:*:XXXXXXXXXXXX:trail/*"]
+ }
+ }
+
+ statement {
+ sid = "Allow CloudTrail to describe key"
+ effect = "Allow"
+ principals {
+ type = "Service"
+ identifiers = ["cloudtrail.amazonaws.com"]
+ }
+ actions = ["kms:DescribeKey"]
+ resources = ["*"]
+ }
+
+ statement {
+ sid = "Allow principals in the account to decrypt log files"
+ effect = "Allow"
+ principals {
+ type = "AWS"
+ identifiers = ["*"]
+ }
+ actions = [
+ "kms:Decrypt",
+ "kms:ReEncryptFrom"
+ ]
+ resources = ["*"]
+ condition {
+ test = "StringEquals"
+ variable = "kms:CallerAccount"
+ values = [
+ "XXXXXXXXXXXX"]
+ }
+ condition {
+ test = "StringLike"
+ variable = "kms:EncryptionContext:aws:cloudtrail:arn"
+ values = ["arn:aws:cloudtrail:*:XXXXXXXXXXXX:trail/*"]
+ }
+ }
+
+ statement {
+ sid = "Allow alias creation during setup"
+ effect = "Allow"
+ principals {
+ type = "AWS"
+ identifiers = ["*"]
+ }
+ actions = ["kms:CreateAlias"]
+ resources = ["*"]
+ }
+ }
+
+```
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| alias | The display name of the alias. The name must start with the word `alias` followed by a forward slash. | `string` | `""` | no |
+| application | Application (e.g. `do4m` or `devops4me`). | `string` | `""` | no |
+| attributes | Additional attributes (e.g. `1`). | `list(string)` | `[]` | no |
+| customer\_master\_key\_spec | Specifies whether the key contains a symmetric key or an asymmetric key pair and the encryption algorithms or signing algorithms that the key supports. Valid values: SYMMETRIC\_DEFAULT, RSA\_2048, RSA\_3072, RSA\_4096, ECC\_NIST\_P256, ECC\_NIST\_P384, ECC\_NIST\_P521, or ECC\_SECG\_P256K1. Defaults to SYMMETRIC\_DEFAULT. | `string` | `"SYMMETRIC_DEFAULT"` | no |
+| deletion\_window\_in\_days | Duration in days after which the key is deleted after destruction of the resource. | `number` | `10` | no |
+| description | The description of the key as viewed in AWS console. | `string` | `"Parameter Store KMS master key"` | no |
+| enable\_key\_rotation | Specifies whether key rotation is enabled. | `bool` | `true` | no |
+| enabled | Specifies whether the kms is enabled or disabled. | `bool` | `true` | no |
+| environment | Environment (e.g. `prod`, `dev`, `staging`). | `string` | `""` | no |
+| is\_enabled | Specifies whether the key is enabled. | `bool` | `true` | no |
+| key\_usage | Specifies the intended use of the key. Defaults to ENCRYPT\_DECRYPT, and only symmetric encryption and decryption are supported. | `string` | `"ENCRYPT_DECRYPT"` | no |
+| label\_order | label order, e.g. `name`,`application`. | `list` | `[]` | no |
+| managedby | ManagedBy, eg 'DevOps4Me' or 'NajibRadzuan'. | `string` | `"najibradzuan@devops4me.com"` | no |
+| name | Name (e.g. `app` or `cluster`). | `string` | `""` | no |
+| policy | A valid policy JSON document. For more information about building AWS IAM policy documents with Terraform. | `string` | `""` | no |
+| tags | Additional tags (e.g. map(`BusinessUnit`,`XYZ`). | `map(string)` | `{}` | no |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| alias\_arn | Alias ARN. |
+| alias\_name | Alias name. |
+| key\_arn | Key ARN. |
+| key\_id | Key ID. |
+| tags | A mapping of tags to assign to the resource. |
+
+## Testing
+In this module testing is performed with [terratest](https://github.com/gruntwork-io/terratest) and it creates a small piece of infrastructure, matches the output like ARN, ID and Tags name etc and destroy infrastructure in your AWS account. This testing is written in GO, so you need a [GO environment](https://golang.org/doc/install) in your system.
+
+You need to run the following command in the testing folder:
+```hcl
+ go test -run Test
+```
\ No newline at end of file
diff --git a/gorun/kms.tf b/gorun/kms.tf
new file mode 100644
index 0000000..9b0325d
--- /dev/null
+++ b/gorun/kms.tf
@@ -0,0 +1,95 @@
+provider "aws" {
+ region = "ap-southeast-1"
+}
+
+module "kms_key" {
+ source = "./../"
+
+ name = "kms"
+ application = "devops4me"
+ environment = "test"
+ label_order = ["environment", "application", "name"]
+ enabled = true
+
+ description = "KMS key for cloudtrail"
+ deletion_window_in_days = 7
+ enable_key_rotation = true
+ alias = "alias/cloudtrail_Name"
+ policy = data.aws_iam_policy_document.default.json
+}
+
+data "aws_iam_policy_document" "default" {
+ version = "2012-10-17"
+ statement {
+ sid = "Enable IAM User Permissions"
+ effect = "Allow"
+ principals {
+ type = "AWS"
+ identifiers = ["*"]
+ }
+ actions = ["kms:*"]
+ resources = ["*"]
+ }
+ statement {
+ sid = "Allow CloudTrail to encrypt logs"
+ effect = "Allow"
+ principals {
+ type = "Service"
+ identifiers = ["cloudtrail.amazonaws.com"]
+ }
+ actions = ["kms:GenerateDataKey*"]
+ resources = ["*"]
+ condition {
+ test = "StringLike"
+ variable = "kms:EncryptionContext:aws:cloudtrail:arn"
+ values = ["arn:aws:cloudtrail:*:XXXXXXXXXXXX:trail/*"]
+ }
+ }
+
+ statement {
+ sid = "Allow CloudTrail to describe key"
+ effect = "Allow"
+ principals {
+ type = "Service"
+ identifiers = ["cloudtrail.amazonaws.com"]
+ }
+ actions = ["kms:DescribeKey"]
+ resources = ["*"]
+ }
+
+ statement {
+ sid = "Allow principals in the account to decrypt log files"
+ effect = "Allow"
+ principals {
+ type = "AWS"
+ identifiers = ["*"]
+ }
+ actions = [
+ "kms:Decrypt",
+ "kms:ReEncryptFrom"
+ ]
+ resources = ["*"]
+ condition {
+ test = "StringEquals"
+ variable = "kms:CallerAccount"
+ values = [
+ "XXXXXXXXXXXX"]
+ }
+ condition {
+ test = "StringLike"
+ variable = "kms:EncryptionContext:aws:cloudtrail:arn"
+ values = ["arn:aws:cloudtrail:*:XXXXXXXXXXXX:trail/*"]
+ }
+ }
+
+ statement {
+ sid = "Allow alias creation during setup"
+ effect = "Allow"
+ principals {
+ type = "AWS"
+ identifiers = ["*"]
+ }
+ actions = ["kms:CreateAlias"]
+ resources = ["*"]
+ }
+}
\ No newline at end of file
diff --git a/gorun/output.tf b/gorun/output.tf
new file mode 100644
index 0000000..10cd3ac
--- /dev/null
+++ b/gorun/output.tf
@@ -0,0 +1,9 @@
+output "key_arn" {
+ value = module.kms_key.key_arn
+ description = "Key ARN."
+}
+
+output "tags" {
+ value = module.kms_key.tags
+ description = "A mapping of tags to assign to the KMS."
+}
\ No newline at end of file
diff --git a/main.tf b/main.tf
new file mode 100644
index 0000000..b67d3e5
--- /dev/null
+++ b/main.tf
@@ -0,0 +1,39 @@
+## Managed By : DevOps4Me
+# Description : This Script is used to create Cloudfront CDN on AWS.
+## Copyright @ DevOps4Me. All Right Reserved.
+
+#Module : label
+#Description : This terraform module is designed to generate consistent label names and tags
+# for resources. You can use terraform-labels to implement a strict naming
+# convention.
+module "labels" {
+source = "git::https://gitlab.com/devops4me-automation/terraform-label.git"
+
+ name = var.name
+ application = var.application
+ environment = var.environment
+ managedby = var.managedby
+ label_order = var.label_order
+}
+
+# Module : KMS KEY
+# Description : This terraform module creates a KMS Customer Master Key (CMK) and its alias.
+resource "aws_kms_key" "default" {
+ count = var.enabled ? 1 : 0
+ description = var.description
+ key_usage = var.key_usage
+ deletion_window_in_days = var.deletion_window_in_days
+ is_enabled = var.is_enabled
+ enable_key_rotation = var.enable_key_rotation
+ customer_master_key_spec = var.customer_master_key_spec
+ policy = var.policy
+ tags = module.labels.tags
+}
+
+# Module : KMS ALIAS
+# Description : Provides an alias for a KMS customer master key..
+resource "aws_kms_alias" "default" {
+ count = var.enabled ? 1 : 0
+ name = coalesce(var.alias, format("alias/%v", module.labels.id))
+ target_key_id = join("", aws_kms_key.default.*.id)
+}
\ No newline at end of file
diff --git a/output.tf b/output.tf
new file mode 100644
index 0000000..ff71878
--- /dev/null
+++ b/output.tf
@@ -0,0 +1,26 @@
+# Module : KMS KEY
+# Description : This terraform module creates a KMS Customer Master Key (CMK) and its alias.
+output "key_arn" {
+ value = join("", aws_kms_key.default.*.arn)
+ description = "Key ARN."
+}
+
+output "key_id" {
+ value = join("", aws_kms_key.default.*.key_id)
+ description = "Key ID."
+}
+
+output "alias_arn" {
+ value = join("", aws_kms_alias.default.*.arn)
+ description = "Alias ARN."
+}
+
+output "alias_name" {
+ value = join("", aws_kms_alias.default.*.name)
+ description = "Alias name."
+}
+
+output "tags" {
+ value = module.labels.tags
+ description = "A mapping of tags to assign to the resource."
+}
\ No newline at end of file
diff --git a/test/go.mod b/test/go.mod
new file mode 100644
index 0000000..ada19cb
--- /dev/null
+++ b/test/go.mod
@@ -0,0 +1,8 @@
+module github.com/devops4mecode/terraform-aws-kms
+
+go 1.13
+
+require (
+ github.com/gruntwork-io/terratest v0.30.6
+ github.com/stretchr/testify v1.6.1
+)
diff --git a/test/kms_test.go b/test/kms_test.go
new file mode 100644
index 0000000..6231e17
--- /dev/null
+++ b/test/kms_test.go
@@ -0,0 +1,34 @@
+// Managed By : DevOps4Me
+// Description : This Terratest is used to test the Terraform VPC module.
+// Copyright @ DevOps4Me. All Right Reserved.
+
+package test
+
+import (
+ "testing"
+
+ "github.com/gruntwork-io/terratest/modules/terraform"
+ "github.com/stretchr/testify/assert"
+)
+
+func Test(t *testing.T) {
+ t.Parallel()
+
+ terraformOptions := &terraform.Options{
+ // Source path of Terraform directory.
+ TerraformDir: "../gorun",
+ }
+
+ // This will run `terraform init` and `terraform apply` and fail the test if there are any errors
+ terraform.InitAndApply(t, terraformOptions)
+
+ // To clean up any resources that have been created, run 'terraform destroy' towards the end of the test
+ defer terraform.Destroy(t, terraformOptions)
+
+ // To get the value of an output variable, run 'terraform output'
+ keyArn := terraform.Output(t, terraformOptions, "key_arn")
+ Tags := terraform.OutputMap(t, terraformOptions, "tags")
+
+ // Check that we get back the outputs that we expect
+ assert.Contains(t, keyArn, "arn:aws:kms")
+ assert.Equal(t, "test-devops4me-kms", Tags["Name"])
diff --git a/variables.tf b/variables.tf
new file mode 100644
index 0000000..28986ec
--- /dev/null
+++ b/variables.tf
@@ -0,0 +1,99 @@
+#Module : LABEL
+#Description : Terraform label module variables.
+variable "name" {
+ type = string
+ default = ""
+ description = "Name (e.g. `app` or `cluster`)."
+}
+
+variable "application" {
+ type = string
+ default = ""
+ description = "Application (e.g. `do4m` or `devops4me`)."
+}
+
+variable "environment" {
+ type = string
+ default = ""
+ description = "Environment (e.g. `prod`, `dev`, `staging`)."
+}
+
+variable "label_order" {
+ type = list
+ default = []
+ description = "label order, e.g. `name`,`application`."
+}
+
+variable "attributes" {
+ type = list(string)
+ default = []
+ description = "Additional attributes (e.g. `1`)."
+}
+
+variable "tags" {
+ type = map(string)
+ default = {}
+ description = "Additional tags (e.g. map(`BusinessUnit`,`XYZ`)."
+}
+
+variable "managedby" {
+ type = string
+ default = "najibradzuan@devops4me.com"
+ description = "ManagedBy, eg 'DevOps4Me' or 'NajibRadzuan'."
+}
+
+# Module : KMS KEY
+# Description : Provides a KMS customer master key.
+variable "deletion_window_in_days" {
+ type = number
+ default = 10
+ description = "Duration in days after which the key is deleted after destruction of the resource."
+}
+
+variable "enable_key_rotation" {
+ type = bool
+ default = true
+ description = "Specifies whether key rotation is enabled."
+}
+
+variable "description" {
+ type = string
+ default = "Parameter Store KMS master key"
+ description = "The description of the key as viewed in AWS console."
+}
+
+variable "is_enabled" {
+ type = bool
+ default = true
+ description = "Specifies whether the key is enabled."
+}
+
+variable "enabled" {
+ type = bool
+ default = true
+ description = "Specifies whether the kms is enabled or disabled."
+}
+
+variable "key_usage" {
+ type = string
+ default = "ENCRYPT_DECRYPT"
+ description = "Specifies the intended use of the key. Defaults to ENCRYPT_DECRYPT, and only symmetric encryption and decryption are supported."
+}
+
+variable "alias" {
+ type = string
+ default = ""
+ description = "The display name of the alias. The name must start with the word `alias` followed by a forward slash."
+}
+
+variable "policy" {
+ type = string
+ default = ""
+ description = "A valid policy JSON document. For more information about building AWS IAM policy documents with Terraform."
+}
+
+variable "customer_master_key_spec" {
+ type = string
+ default = "SYMMETRIC_DEFAULT"
+ description = "Specifies whether the key contains a symmetric key or an asymmetric key pair and the encryption algorithms or signing algorithms that the key supports. Valid values: SYMMETRIC_DEFAULT, RSA_2048, RSA_3072, RSA_4096, ECC_NIST_P256, ECC_NIST_P384, ECC_NIST_P521, or ECC_SECG_P256K1. Defaults to SYMMETRIC_DEFAULT."
+}
\ No newline at end of file
diff --git a/version.tf b/version.tf
new file mode 100644
index 0000000..5587ad2
--- /dev/null
+++ b/version.tf
@@ -0,0 +1,9 @@
+# Terraform version
+terraform {
+ required_version = ">= 0.12.0, < 0.14.0"
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ }
+ }
+}