diff --git a/.github/workflows/code-scan.yml b/.github/workflows/code-scan.yml
index 5a97381..2e0ae35 100644
--- a/.github/workflows/code-scan.yml
+++ b/.github/workflows/code-scan.yml
@@ -34,6 +34,8 @@ jobs:
# This will add both a CLI output to the console and create a results.sarif file
output_format: cli,sarif
output_file_path: console,results.sarif
+ #https://github.com/bridgecrewio/checkov/issues/6216
+ skip_check: CKV2_GHA_1
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@v2
diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml
new file mode 100644
index 0000000..9067d15
--- /dev/null
+++ b/.github/workflows/documentation.yml
@@ -0,0 +1,25 @@
+#https://github.com/terraform-docs/gh-actions
+name: generate-terraform-docs
+on:
+ - pull_request
+jobs:
+ docs:
+ runs-on: ubuntu-latest
+ permissions:
+ #checkov:skip=CKV2_GHA_1: This is required to add Terraform module details to the ReadMe.md
+ # Ensure top-level permissions are not set to write-all
+ contents: write
+ id-token: write
+ pull-requests: write
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ ref: ${{ github.event.pull_request.head.ref }}
+
+ - name: Render terraform docs inside the README.md and push changes back to PR branch
+ uses: terraform-docs/gh-actions@v1.3.0
+ with:
+ working-dir: .
+ output-file: README.md
+ output-method: inject
+ git-push: "true"
\ No newline at end of file
diff --git a/README.md b/README.md
index 05e8985..39b5d21 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-[![License: Unlicense](https://img.shields.io/badge/license-Unlicense-white.svg)](https://choosealicense.com/licenses/unlicense/)[![GitHub pull-requests closed](https://img.shields.io/github/issues-pr-closed/kunduso/amazon-elasticache-redis-tf)](https://github.com/kunduso/amazon-elasticache-redis-tf/pulls?q=is%3Apr+is%3Aclosed)[![GitHub pull-requests](https://img.shields.io/github/issues-pr/kunduso/amazon-elasticache-redis-tf)](https://GitHub.com/kunduso/amazon-elasticache-redis-tf/pull/)
-[![GitHub issues-closed](https://img.shields.io/github/issues-closed/kunduso/amazon-elasticache-redis-tf)](https://github.com/kunduso/amazon-elasticache-redis-tf/issues?q=is%3Aissue+is%3Aclosed)[![GitHub issues](https://img.shields.io/github/issues/kunduso/amazon-elasticache-redis-tf)](https://GitHub.com/kunduso/amazon-elasticache-redis-tf/issues/)
-[![terraform-infra-provisioning](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/terraform.yml/badge.svg?branch=main)](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/terraform.yml)[![checkov-static-analysis-scan](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/code-scan.yml/badge.svg?branch=main)](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/code-scan.yml)
+[![License: Unlicense](https://img.shields.io/badge/license-Unlicense-white.svg)](https://choosealicense.com/licenses/unlicense/) [![GitHub pull-requests closed](https://img.shields.io/github/issues-pr-closed/kunduso/amazon-elasticache-redis-tf)](https://github.com/kunduso/amazon-elasticache-redis-tf/pulls?q=is%3Apr+is%3Aclosed) [![GitHub pull-requests](https://img.shields.io/github/issues-pr/kunduso/amazon-elasticache-redis-tf)](https://GitHub.com/kunduso/amazon-elasticache-redis-tf/pull/)
+[![GitHub issues-closed](https://img.shields.io/github/issues-closed/kunduso/amazon-elasticache-redis-tf)](https://github.com/kunduso/amazon-elasticache-redis-tf/issues?q=is%3Aissue+is%3Aclosed) [![GitHub issues](https://img.shields.io/github/issues/kunduso/amazon-elasticache-redis-tf)](https://GitHub.com/kunduso/amazon-elasticache-redis-tf/issues/)
+[![terraform-infra-provisioning](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/terraform.yml/badge.svg?branch=main)](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/terraform.yml) [![checkov-static-analysis-scan](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/code-scan.yml/badge.svg?branch=main)](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/code-scan.yml) [![Generate terraform docs](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/documentation.yml/badge.svg)](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/documentation.yml)
![Image](https://skdevops.files.wordpress.com/2023/12/87-image-0-1.png)
@@ -28,10 +28,88 @@ For this code to function without errors, I created an **OpenID connect** identi
I stored the ARN of the IAM Role as a GitHub secret which is referred in the [`terraform.yml`](https://github.com/kunduso/amazon-elasticache-redis-tf/blob/eb148db2b9ff37cff9f1fb469d0c14b6479bd57a/.github/workflows/terraform.yml#L42) file.
Since I used Infracost in this repository, I stored the `INFRACOST_API_KEY` as a repository secret. It is referenced in the [`terraform.yml`](https://github.com/kunduso/amazon-elasticache-redis-tf/blob/eb148db2b9ff37cff9f1fb469d0c14b6479bd57a/.github/workflows/terraform.yml#L52) GitHub actions workflow file.
As part of the Infracost integration, I also created a `INFRACOST_API_KEY` and stored that as a GitHub Actions secret. I also managed the cost estimate process using a GitHub Actions variable `INFRACOST_SCAN_TYPE` where the value is either `hcl_code` or `tf_plan`, depending on the type of scan desired.
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [aws](#requirement\_aws) | 5.20.1 |
+| [random](#requirement\_random) | 3.6.3 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [aws](#provider\_aws) | 5.20.1 |
+| [random](#provider\_random) | 3.6.3 |
+
+## Modules
+
+| Name | Source | Version |
+|------|--------|---------|
+| [vpc](#module\_vpc) | github.com/kunduso/terraform-aws-vpc | v1.0.1 |
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [aws_cloudwatch_log_group.engine_log](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/cloudwatch_log_group) | resource |
+| [aws_cloudwatch_log_group.slow_log](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/cloudwatch_log_group) | resource |
+| [aws_elasticache_replication_group.app4](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/elasticache_replication_group) | resource |
+| [aws_elasticache_subnet_group.elasticache_subnet](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/elasticache_subnet_group) | resource |
+| [aws_iam_instance_profile.ec2_profile](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/iam_instance_profile) | resource |
+| [aws_iam_policy.secret_manager_policy](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/iam_policy) | resource |
+| [aws_iam_policy.ssm_parameter_policy](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/iam_policy) | resource |
+| [aws_iam_role.ec2_role](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/iam_role) | resource |
+| [aws_iam_role_policy_attachment.custom](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/iam_role_policy_attachment) | resource |
+| [aws_iam_role_policy_attachment.secret_policy_attachement](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/iam_role_policy_attachment) | resource |
+| [aws_iam_role_policy_attachment.ssm_policy_attachement](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/iam_role_policy_attachment) | resource |
+| [aws_instance.app-server-read](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/instance) | resource |
+| [aws_instance.app-server-write](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/instance) | resource |
+| [aws_kms_alias.encryption_rest](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/kms_alias) | resource |
+| [aws_kms_alias.encryption_secret](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/kms_alias) | resource |
+| [aws_kms_key.encryption_rest](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/kms_key) | resource |
+| [aws_kms_key.encryption_secret](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/kms_key) | resource |
+| [aws_kms_key_policy.encryption_rest_policy](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/kms_key_policy) | resource |
+| [aws_kms_key_policy.encryption_secret_policy](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/kms_key_policy) | resource |
+| [aws_secretsmanager_secret.elasticache_auth](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/secretsmanager_secret) | resource |
+| [aws_secretsmanager_secret_version.auth](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/secretsmanager_secret_version) | resource |
+| [aws_security_group.ec2_instance](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/security_group) | resource |
+| [aws_security_group.elasticache](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/security_group) | resource |
+| [aws_security_group_rule.ec2_instance_egress](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/security_group_rule) | resource |
+| [aws_security_group_rule.ec2_instance_ingress](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/security_group_rule) | resource |
+| [aws_security_group_rule.elasticache_egress](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/security_group_rule) | resource |
+| [aws_security_group_rule.elasticache_ingress](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/security_group_rule) | resource |
+| [aws_ssm_parameter.elasticache_ep](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/ssm_parameter) | resource |
+| [aws_ssm_parameter.elasticache_port](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/ssm_parameter) | resource |
+| [random_password.auth](https://registry.terraform.io/providers/hashicorp/random/3.6.3/docs/resources/password) | resource |
+| [aws_ami.amazon_ami](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/data-sources/ami) | data source |
+| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/data-sources/caller_identity) | data source |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [access\_key](#input\_access\_key) | The access\_key that belongs to the IAM user. | `string` | `""` | no |
+| [ami\_name](#input\_ami\_name) | The ami name of the image from where the instances will be created | `list(string)` |
[
"amzn2-ami-amd-hvm-2.0.20230727.0-x86_64-gp2"
]
| no |
+| [instance\_type](#input\_instance\_type) | The instance type of the EC2 instances | `string` | `"t3.medium"` | no |
+| [name](#input\_name) | The name of the application. | `string` | `"app-4"` | no |
+| [region](#input\_region) | AWS Cloud infrastructure region. | `string` | `"us-east-2"` | no |
+| [secret\_key](#input\_secret\_key) | The secret\_key that belongs to the IAM user. | `string` | `""` | no |
+| [subnet\_cidr\_private](#input\_subnet\_cidr\_private) | CIDR blocks for the private subnets. | `list(any)` | [
"10.20.32.0/27",
"10.20.32.32/27",
"10.20.32.64/27"
]
| no |
+| [subnet\_cidr\_public](#input\_subnet\_cidr\_public) | CIDR blocks for the public subnets. | `list(any)` | [
"10.20.32.96/27"
]
| no |
+| [vpc\_cidr](#input\_vpc\_cidr) | CIDR for the VPC. | `string` | `"10.20.32.0/25"` | no |
+
+## Outputs
+
+No outputs.
+
## Usage
Ensure that the policy attached to the IAM role whose credentials are being used in this configuration has permission to create and manage all the resources that are included in this repository.
Review the code including the [`terraform.yml`](./.github/workflows/terraform.yml) to understand the steps in the GitHub Actions pipeline. Also review the terraform code to understand all the concepts associated with creating an AWS VPC, subnets, internet gateway, route table, and route table association.
If you want to check the pipeline logs, click on the **Build Badge** (terrform-infra-provisioning) above the image in this ReadMe.
+## Contributing
+If you find any issues or have suggestions for improvement, feel free to open an issue or submit a pull request. Contributions are always welcome!
## License
This code is released under the Unlincse License. See [LICENSE](LICENSE).
\ No newline at end of file
diff --git a/cloudwatch.tf b/cloudwatch.tf
index 1aec471..3807120 100644
--- a/cloudwatch.tf
+++ b/cloudwatch.tf
@@ -1,10 +1,12 @@
+#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group
resource "aws_cloudwatch_log_group" "slow_log" {
- name = "/elasticache/${var.replication_group_id}/slow-log"
+ name = "/elasticache/${var.name}/slow-log"
retention_in_days = 365
kms_key_id = aws_kms_key.encryption_rest.arn
}
+#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group
resource "aws_cloudwatch_log_group" "engine_log" {
- name = "/elasticache/${var.replication_group_id}/engine-log"
+ name = "/elasticache/${var.name}/engine-log"
retention_in_days = 365
kms_key_id = aws_kms_key.encryption_rest.arn
}
\ No newline at end of file
diff --git a/data.tf b/data.tf
index 57db3ca..1949689 100644
--- a/data.tf
+++ b/data.tf
@@ -2,6 +2,6 @@ data "aws_caller_identity" "current" {}
locals {
principal_root_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"
principal_logs_arn = "logs.${var.region}.amazonaws.com"
- slow_log_arn = "arn:aws:logs:${var.region}:${data.aws_caller_identity.current.account_id}:log-group:/elasticache/${var.replication_group_id}/slow-log"
- engine_log_arn = "arn:aws:logs:${var.region}:${data.aws_caller_identity.current.account_id}:log-group:/elasticache/${var.replication_group_id}/engine-log"
+ slow_log_arn = "arn:aws:logs:${var.region}:${data.aws_caller_identity.current.account_id}:log-group:/elasticache/${var.name}/slow-log"
+ engine_log_arn = "arn:aws:logs:${var.region}:${data.aws_caller_identity.current.account_id}:log-group:/elasticache/${var.name}/engine-log"
}
\ No newline at end of file
diff --git a/ec2.tf b/ec2.tf
index ca2625e..380feda 100644
--- a/ec2.tf
+++ b/ec2.tf
@@ -1,36 +1,32 @@
-resource "aws_internet_gateway" "this-igw" {
- vpc_id = aws_vpc.this.id
- tags = {
- "Name" = "app-4-gateway"
- }
-}
-resource "aws_route" "internet-route" {
- destination_cidr_block = "0.0.0.0/0"
- route_table_id = aws_route_table.public.id
- gateway_id = aws_internet_gateway.this-igw.id
-}
# create a security group
+#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group
resource "aws_security_group" "ec2_instance" {
- name = "app-4-ec2"
+ name = "${var.name}-ec2"
description = "Allow inbound to and outbound access from the Amazon EC2 instance."
- ingress {
- from_port = 0
- to_port = 0
- protocol = "-1"
- cidr_blocks = [var.vpc_cidr]
- description = "Enable access from any resource inside the VPC."
- }
- egress {
- from_port = 0
- to_port = 0
- protocol = "-1"
- cidr_blocks = ["0.0.0.0/0"]
- description = "Enable access to the internet."
- }
- vpc_id = aws_vpc.this.id
+ vpc_id = module.vpc.vpc.id
+}
+#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule
+resource "aws_security_group_rule" "ec2_instance_ingress" {
+ type = "ingress"
+ security_group_id = aws_security_group.ec2_instance.id
+ from_port = 0
+ to_port = 0
+ protocol = "-1"
+ cidr_blocks = [var.vpc_cidr]
+ description = "Enable access from any resource inside the VPC."
+}
+#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule
+resource "aws_security_group_rule" "ec2_instance_egress" {
+ type = "egress"
+ security_group_id = aws_security_group.ec2_instance.id
+ from_port = 0
+ to_port = 0
+ protocol = "-1"
+ cidr_blocks = ["0.0.0.0/0"]
+ description = "Enable access to the internet."
}
-#create an EC2 in a public subnet
+#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami
data "aws_ami" "amazon_ami" {
filter {
name = "name"
@@ -43,6 +39,8 @@ data "aws_ami" "amazon_ami" {
most_recent = true
owners = ["amazon"]
}
+#create an EC2 in a public subnet
+#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance
resource "aws_instance" "app-server-read" {
instance_type = var.instance_type
ami = data.aws_ami.amazon_ami.id
@@ -50,7 +48,7 @@ resource "aws_instance" "app-server-read" {
iam_instance_profile = aws_iam_instance_profile.ec2_profile.name
associate_public_ip_address = true
#checkov:skip=CKV_AWS_88: Required for Session Manager access
- subnet_id = aws_subnet.public[0].id
+ subnet_id = module.vpc.private_subnets[0].id
ebs_optimized = true
monitoring = true
root_block_device {
@@ -61,7 +59,7 @@ resource "aws_instance" "app-server-read" {
http_tokens = "required"
}
tags = {
- Name = "app-4-server-read"
+ Name = "${var.name}-server-read"
}
user_data = templatefile("user_data/read_elasticache.tpl",
{
@@ -71,6 +69,7 @@ resource "aws_instance" "app-server-read" {
elasticache_auth_token = aws_secretsmanager_secret.elasticache_auth.name
})
}
+#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance
resource "aws_instance" "app-server-write" {
instance_type = var.instance_type
ami = data.aws_ami.amazon_ami.id
@@ -78,7 +77,7 @@ resource "aws_instance" "app-server-write" {
iam_instance_profile = aws_iam_instance_profile.ec2_profile.name
associate_public_ip_address = true
#checkov:skip=CKV_AWS_88: Required for Session Manager access
- subnet_id = aws_subnet.public[0].id
+ subnet_id = module.vpc.private_subnets[0].id
ebs_optimized = true
monitoring = true
root_block_device {
@@ -89,7 +88,7 @@ resource "aws_instance" "app-server-write" {
http_tokens = "required"
}
tags = {
- Name = "app-4-server-write"
+ Name = "${var.name}-server-write"
}
user_data = templatefile("user_data/write_elasticache.tpl",
{
diff --git a/ec2_role.tf b/ec2_role.tf
index 86db034..f03017f 100644
--- a/ec2_role.tf
+++ b/ec2_role.tf
@@ -1,7 +1,6 @@
# #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role
resource "aws_iam_role" "ec2_role" {
- name = "app-4-ec2-role"
-
+ name = "${var.name}-ec2-role"
# Terraform's "jsonencode" function converts a
# Terraform expression result to valid JSON syntax.
assume_role_policy = jsonencode({
@@ -24,11 +23,12 @@ resource "aws_iam_role_policy_attachment" "custom" {
role = aws_iam_role.ec2_role.name
policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
-
+#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment
resource "aws_iam_role_policy_attachment" "ssm_policy_attachement" {
role = aws_iam_role.ec2_role.name
policy_arn = aws_iam_policy.ssm_parameter_policy.arn
}
+##https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment
resource "aws_iam_role_policy_attachment" "secret_policy_attachement" {
role = aws_iam_role.ec2_role.name
policy_arn = aws_iam_policy.secret_manager_policy.arn
@@ -36,6 +36,6 @@ resource "aws_iam_role_policy_attachment" "secret_policy_attachement" {
#Attach role to an instance profile
#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile
resource "aws_iam_instance_profile" "ec2_profile" {
- name = "app-4-ec2-profile"
+ name = "${var.name}-ec2-profile"
role = aws_iam_role.ec2_role.name
}
\ No newline at end of file
diff --git a/elasticache.tf b/elasticache.tf
index f3b2af5..b21cbae 100644
--- a/elasticache.tf
+++ b/elasticache.tf
@@ -1,14 +1,16 @@
+#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/elasticache_subnet_group
resource "aws_elasticache_subnet_group" "elasticache_subnet" {
- name = "app-4-cache-subnet"
- subnet_ids = [for subnet in aws_subnet.private : subnet.id]
+ name = "${var.name}-cache-subnet"
+ subnet_ids = [for subnet in module.vpc.private_subnets : subnet.id]
}
-
+#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret
resource "aws_secretsmanager_secret" "elasticache_auth" {
- name = "app-4-elasticache-auth"
+ name = "${var.name}-elasticache-auth"
recovery_window_in_days = 0
kms_key_id = aws_kms_key.encryption_secret.id
#checkov:skip=CKV2_AWS_57: Disabled Secrets Manager secrets automatic rotation
}
+#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version
resource "aws_secretsmanager_secret_version" "auth" {
secret_id = aws_secretsmanager_secret.elasticache_auth.id
secret_string = random_password.auth.result
@@ -18,8 +20,8 @@ resource "aws_secretsmanager_secret_version" "auth" {
resource "aws_elasticache_replication_group" "app4" {
automatic_failover_enabled = true
subnet_group_name = aws_elasticache_subnet_group.elasticache_subnet.name
- replication_group_id = var.replication_group_id
- description = "ElastiCache cluster for app4"
+ replication_group_id = var.name
+ description = "ElastiCache cluster for ${var.name}"
node_type = "cache.t2.small"
parameter_group_name = "default.redis7.cluster.on"
port = 6379
diff --git a/iam_role.tf b/iam_role.tf
index 5f438f6..0f498c5 100644
--- a/iam_role.tf
+++ b/iam_role.tf
@@ -1,7 +1,7 @@
#Create a policy to read from the specific parameter store
#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy
resource "aws_iam_policy" "ssm_parameter_policy" {
- name = "app-4-ssm-parameter-read-policy"
+ name = "${var.name}-ssm-parameter-read-policy"
path = "/"
description = "Policy to read the ElastiCache endpoint and port number stored in the SSM Parameter Store."
# Terraform's "jsonencode" function converts a
@@ -29,7 +29,7 @@ resource "aws_iam_policy" "ssm_parameter_policy" {
}
#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy
resource "aws_iam_policy" "secret_manager_policy" {
- name = "app-4-secret-read-policy"
+ name = "${var.name}-secret-read-policy"
path = "/"
description = "Policy to read the ElastiCache AUTH Token stored in AWS Secrets Manager secret."
# Terraform's "jsonencode" function converts a
diff --git a/kms.tf b/kms.tf
index d8e1599..af3c5c2 100644
--- a/kms.tf
+++ b/kms.tf
@@ -1,31 +1,81 @@
-
+#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key
resource "aws_kms_key" "encryption_secret" {
enable_key_rotation = true
description = "Key to encrypt secret"
deletion_window_in_days = 7
- #checkov:skip=CKV2_AWS_64: Not including a KMS Key policy
+ tags = {
+ Name = "${var.name}-encryption-secret"
+ }
}
+#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias
resource "aws_kms_alias" "encryption_secret" {
- name = "alias/elasticache-app-4-in-transit"
+ name = "alias/${var.name}-encryption-secret"
target_key_id = aws_kms_key.encryption_secret.key_id
}
+#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key_policy
+resource "aws_kms_key_policy" "encryption_secret_policy" {
+ key_id = aws_kms_key.encryption_secret.id
+ policy = jsonencode({
+ Id = "${var.name}-encryption-secret"
+ Version = "2012-10-17"
+ Statement = [
+ {
+ Sid = "Enable IAM User Permissions"
+ Effect = "Allow"
+ Principal = {
+ AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"
+ }
+ Action = "kms:*"
+ Resource = "*"
+ },
+ {
+ Sid = "Allow access through AWS Secrets Manager for all principals in the account that are authorized to use AWS Secrets Manager"
+ Effect = "Allow"
+ Principal = {
+ AWS = ["*"]
+ }
+ Action = [
+ "kms:Encrypt",
+ "kms:Decrypt",
+ "kms:ReEncrypt*",
+ "kms:CreateGrant",
+ "kms:DescribeKey",
+ "kms:GenerateDataKey*"
+ ]
+ Resource = "*"
+ Condition = {
+ StringEquals = {
+ "kms:CallerAccount" = "${data.aws_caller_identity.current.account_id}"
+ "kms:ViaService" = "secretsmanager.${var.region}.amazonaws.com"
+ }
+ }
+ }
+ ]
+ })
+}
+
+#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key
resource "aws_kms_key" "encryption_rest" {
enable_key_rotation = true
description = "Key to encrypt cache at rest."
deletion_window_in_days = 7
- #checkov:skip=CKV2_AWS_64: KMS Key policy in a separate resource
+ tags = {
+ Name = "${var.name}-encryption-rest"
+ }
}
+#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias
resource "aws_kms_alias" "encryption_rest" {
- name = "alias/elasticache-app-4-at-rest"
+ name = "alias/${var.name}-encryption-rest"
target_key_id = aws_kms_key.encryption_rest.key_id
}
+#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key_policy
resource "aws_kms_key_policy" "encryption_rest_policy" {
key_id = aws_kms_key.encryption_rest.id
policy = jsonencode({
- Id = "encryption-rest"
+ Id = "${var.name}-encryption-rest"
Statement = [
{
- Action = "kms:*"
+ Action = ["kms:*"]
Effect = "Allow"
Principal = {
AWS = "${local.principal_root_arn}"
@@ -33,6 +83,22 @@ resource "aws_kms_key_policy" "encryption_rest_policy" {
Resource = "*"
Sid = "Enable IAM User Permissions"
},
+ {
+ Sid = "Allow ElastiCache to use the key"
+ Effect = "Allow"
+ Principal = {
+ Service = "elasticache.amazonaws.com"
+ }
+ Action = [
+ "kms:Decrypt",
+ "kms:Encrypt",
+ "kms:GenerateDataKey",
+ "kms:ReEncrypt*",
+ "kms:CreateGrant",
+ "kms:DescribeKey"
+ ]
+ Resource = "*"
+ },
{
Effect : "Allow",
Principal : {
diff --git a/network.tf b/network.tf
index 4d6f623..69d8cc9 100644
--- a/network.tf
+++ b/network.tf
@@ -1,56 +1,14 @@
-# https://docs.aws.amazon.com/glue/latest/dg/set-up-vpc-dns.html
-resource "aws_vpc" "this" {
- cidr_block = var.vpc_cidr
- # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc#enable_dns_support
- enable_dns_support = true
- # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc#enable_dns_hostnames
- enable_dns_hostnames = true
- #checkov:skip=CKV2_AWS_11: Not creating a flow log for this VPC
- tags = {
- "Name" = "app-4"
- }
-}
-data "aws_availability_zones" "available" {
- state = "available"
-}
-resource "aws_subnet" "private" {
- count = length(var.subnet_cidr_private)
- vpc_id = aws_vpc.this.id
- cidr_block = var.subnet_cidr_private[count.index]
- availability_zone = data.aws_availability_zones.available.names[(count.index) % length(data.aws_availability_zones.available.names)]
- tags = {
- "Name" = "app-4-private-${count.index + 1}"
- }
-}
-resource "aws_subnet" "public" {
- count = length(var.subnet_cidr_public)
- vpc_id = aws_vpc.this.id
- cidr_block = var.subnet_cidr_public[count.index]
- availability_zone = data.aws_availability_zones.available.names[(count.index) % length(data.aws_availability_zones.available.names)]
- tags = {
- "Name" = "app-4-public-${count.index + 1}"
- }
-}
-resource "aws_route_table" "private" {
- count = length(var.subnet_cidr_private)
- vpc_id = aws_vpc.this.id
- tags = {
- "Name" = "app-4-private-route-table-${count.index + 1}"
- }
-}
-resource "aws_route_table" "public" {
- vpc_id = aws_vpc.this.id
- tags = {
- "Name" = "app-4-public"
- }
-}
-resource "aws_route_table_association" "private" {
- count = length(var.subnet_cidr_private)
- subnet_id = element(aws_subnet.private.*.id, count.index)
- route_table_id = aws_route_table.private[count.index].id
-}
-resource "aws_route_table_association" "public" {
- count = length(var.subnet_cidr_public)
- subnet_id = element(aws_subnet.public.*.id, count.index)
- route_table_id = aws_route_table.public.id
+module "vpc" {
+ #CKV_TF_1: Ensure Terraform module sources use a commit hash
+ #checkov:skip=CKV_TF_1: This is a self hosted module where the version number is tagged rather than the commit hash.
+ source = "github.com/kunduso/terraform-aws-vpc?ref=v1.0.1"
+ region = var.region
+ vpc_cidr = var.vpc_cidr
+ enable_dns_support = "true"
+ enable_dns_hostnames = "true"
+ vpc_name = "app-4"
+ subnet_cidr_private = var.subnet_cidr_private
+ subnet_cidr_public = var.subnet_cidr_public
+ enable_internet_gateway = "true"
+ enable_flow_log = "true"
}
\ No newline at end of file
diff --git a/provider.tf b/provider.tf
index bee5e8d..98a3b46 100644
--- a/provider.tf
+++ b/provider.tf
@@ -6,7 +6,7 @@ terraform {
}
random = {
source = "hashicorp/random"
- version = "3.5.1"
+ version = "3.6.3"
}
}
}
diff --git a/security_group.tf b/security_group.tf
index 375202a..31d2142 100644
--- a/security_group.tf
+++ b/security_group.tf
@@ -1,22 +1,26 @@
-resource "aws_default_security_group" "default" {
- vpc_id = aws_vpc.this.id
-}
+#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group
resource "aws_security_group" "elasticache" {
- name = "app-4-elasticache-sg"
+ name = "${var.name}-elasticache-sg"
description = "Allow inbound to and outbound access from the Amazon ElastiCache cluster."
- ingress {
- from_port = 6379
- to_port = 6379
- protocol = "tcp"
- cidr_blocks = [var.vpc_cidr]
- description = "Enable communication to the Amazon ElastiCache for Redis cluster. "
- }
- egress {
- from_port = 0
- to_port = 0
- protocol = "-1"
- cidr_blocks = ["0.0.0.0/0"]
- description = "Enable access to the ElastiCache cluster."
- }
- vpc_id = aws_vpc.this.id
+ vpc_id = module.vpc.vpc.id
+}
+#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule
+resource "aws_security_group_rule" "elasticache_ingress" {
+ type = "ingress"
+ security_group_id = aws_security_group.elasticache.id
+ from_port = 6379
+ to_port = 6379
+ protocol = "tcp"
+ cidr_blocks = [var.vpc_cidr]
+ description = "Enable communication to the Amazon ElastiCache for Redis cluster."
+}
+#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule
+resource "aws_security_group_rule" "elasticache_egress" {
+ type = "egress"
+ security_group_id = aws_security_group.elasticache.id
+ from_port = 0
+ to_port = 0
+ protocol = "-1"
+ cidr_blocks = ["0.0.0.0/0"]
+ description = "Enable access to the ElastiCache cluster."
}
\ No newline at end of file
diff --git a/ssm_parameter.tf b/ssm_parameter.tf
index 9061c5c..d42af08 100644
--- a/ssm_parameter.tf
+++ b/ssm_parameter.tf
@@ -1,12 +1,13 @@
#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_parameter
resource "aws_ssm_parameter" "elasticache_ep" {
- name = "/elasticache/app-4/${aws_elasticache_replication_group.app4.replication_group_id}/endpoint"
+ name = "/elasticache/${var.name}/${aws_elasticache_replication_group.app4.replication_group_id}/endpoint"
type = "SecureString"
key_id = aws_kms_key.encryption_rest.id
value = aws_elasticache_replication_group.app4.configuration_endpoint_address
}
+#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_parameter
resource "aws_ssm_parameter" "elasticache_port" {
- name = "/elasticache/app-4/${aws_elasticache_replication_group.app4.replication_group_id}/port"
+ name = "/elasticache/${var.name}/${aws_elasticache_replication_group.app4.replication_group_id}/port"
type = "SecureString"
key_id = aws_kms_key.encryption_rest.id
value = aws_elasticache_replication_group.app4.port
diff --git a/variable.tf b/variable.tf
index 00ed7e3..4a9d923 100644
--- a/variable.tf
+++ b/variable.tf
@@ -18,6 +18,11 @@ variable "secret_key" {
sensitive = true
default = ""
}
+variable "name" {
+ description = "The name of the application."
+ type = string
+ default = "app-4"
+}
variable "vpc_cidr" {
description = "CIDR for the VPC."
default = "10.20.32.0/25"
@@ -41,8 +46,8 @@ variable "instance_type" {
description = "The instance type of the EC2 instances"
default = "t3.medium"
}
-variable "replication_group_id" {
- description = "The name of the ElastiCache replication group."
- default = "app-4-redis-cluster"
- type = string
-}
\ No newline at end of file
+# variable "replication_group_id" {
+# description = "The name of the ElastiCache replication group."
+# default = "app-4-redis-cluster"
+# type = string
+# }
\ No newline at end of file