Skip to content

Multi AZ example and Terratest #94

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions .github/workflows/terratest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
---
name: Terratest
on: # yamllint disable-line rule:truthy
pull_request:
types: [opened]
workflow_dispatch:
inputs:
pr_number:
description: 'Pull Request Number'
required: true

permissions:
id-token: write
contents: read
statuses: write # Required for setting commit status

jobs:
terratest:
runs-on: ubuntu-latest
name: Terratest Checks

env:
PR_NUMBER: >-
${{ github.event_name == 'workflow_dispatch' &&
github.event.inputs.pr_number || github.event.pull_request.number }}


steps:
- name: Checkout PR code
uses: actions/checkout@v4
with:
ref: refs/pull/${{ env.PR_NUMBER }}/head

- name: Configure AWS credentials via OIDC
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: ${{ secrets.ARC_IAC_TERRATEST_ROLE }}
aws-region: us-east-1
role-duration-seconds: 7200

- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.24'

- name: Set up Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_version: 1.7.5
terraform_wrapper: false

- name: Create test directory and download go from S3
run: |
mkdir -p terra-test
aws s3 cp ${{ secrets.ARC_TERRATEST_GO_FILE }} terra-test/terra_test.go
- name: Initialize Go module and install dependencies
run: |
cd terra-test
ls
go mod init terraform-test || true
go get github.com/gruntwork-io/terratest/modules/terraform
go get github.com/stretchr/testify/assert
go mod tidy
go test -v -timeout 240m
- name: Report check status manually
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const pr_number = parseInt(process.env.PR_NUMBER);
const pr = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr_number,
});
const sha = pr.data.head.sha;
await github.rest.repos.createCommitStatus({
owner: context.repo.owner,
repo: context.repo.repo,
sha: sha,
state: 'success',
context: 'terratest',
description: 'Manual terratest completed successfully',
target_url:
`https://github.com/${context.repo.owner}/${context.repo.repo}` +
`/actions/runs/${process.env.GITHUB_RUN_ID}`,
});
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ To see a full example, check out the [main.tf](https://github.com/sourcefuse/ter
| <a name="input_iops"></a> [iops](#input\_iops) | The amount of provisioned IOPS. Required if using io1 storage type. | `number` | `0` | no |
| <a name="input_kms_data"></a> [kms\_data](#input\_kms\_data) | Configuration for KMS key settings for RDS encryption and performance insights:<br>- create: (Optional) If true, a new KMS key is created.<br>- kms\_key\_id: (Optional) The ID of an existing KMS key for RDS encryption. If null it used AWS managed keys<br>- performance\_insights\_kms\_key\_id: (Optional) Key ID for Performance Insights. If null it used AWS managed keys<br>- description: (Optional) description for the KMS key.<br>- policy: (Optional) Specific policy for the KMS key.<br>- deletion\_window\_in\_days: (Optional) Number of days before deletion, default is 7.<br>- enable\_key\_rotation: (Optional) Enables key rotation for security; defaults to true. | <pre>object({<br> create = optional(bool, true)<br> kms_key_id = optional(string, null)<br> performance_insights_kms_key_id = optional(string, null)<br> name = optional(string, null)<br> description = optional(string, null)<br> policy = optional(string, null)<br> deletion_window_in_days = optional(number, 7)<br> enable_key_rotation = optional(bool, true)<br> })</pre> | <pre>{<br> "create": false<br>}</pre> | no |
| <a name="input_license_model"></a> [license\_model](#input\_license\_model) | The license model for the DB instance (e.g., license-included, bring-your-own-license, general-public-license). | `string` | n/a | yes |
| <a name="input_manage_user_password"></a> [manage\_user\_password](#input\_manage\_user\_password) | (optional) Set to true to allow RDS to manage the master user password in Secrets Manager. Cannot be set if master\_password is provided."<br>null - is equal to 'false', don't set it to false , known bug : https://github.com/hashicorp/terraform-provider-aws/issues/31179 | `bool` | `null` | no |
| <a name="input_manage_user_password"></a> [manage\_user\_password](#input\_manage\_user\_password) | (optional) Set to true to allow RDS to manage the master user password in Secrets Manager. Cannot be set if master\_password is provided. | `bool` | `true` | no |
| <a name="input_monitoring_interval"></a> [monitoring\_interval](#input\_monitoring\_interval) | The interval, in seconds, between points when Enhanced Monitoring metrics are collected. Valid values are 0, 1, 5, 10, 15, 30, 60. | `number` | `0` | no |
| <a name="input_monitoring_role_arn"></a> [monitoring\_role\_arn](#input\_monitoring\_role\_arn) | The ARN for the IAM role that allows RDS to send Enhanced Monitoring metrics to CloudWatch Logs. | `string` | `null` | no |
| <a name="input_name"></a> [name](#input\_name) | The identifier for the RDS instance or cluster. | `string` | n/a | yes |
Expand Down Expand Up @@ -141,6 +141,7 @@ To see a full example, check out the [main.tf](https://github.com/sourcefuse/ter
| <a name="output_id"></a> [id](#output\_id) | Instance or Cluster ID |
| <a name="output_identifier"></a> [identifier](#output\_identifier) | Instance or Cluster Identifier |
| <a name="output_kms_key_id"></a> [kms\_key\_id](#output\_kms\_key\_id) | Instance or Cluster KM Key ID |
| <a name="output_master_user_secret"></a> [master\_user\_secret](#output\_master\_user\_secret) | Secret ARN |
| <a name="output_monitoring_role_arn"></a> [monitoring\_role\_arn](#output\_monitoring\_role\_arn) | Instance or Cluster Monitoring role arn |
| <a name="output_performance_insights_kms_key_id"></a> [performance\_insights\_kms\_key\_id](#output\_performance\_insights\_kms\_key\_id) | Instance or Cluster Performance insight KM Key ID |
| <a name="output_port"></a> [port](#output\_port) | Dtabase server port |
Expand Down
4 changes: 2 additions & 2 deletions aurora-cluster.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
resource "random_password" "master" {
count = var.password == null && var.manage_user_password == null ? 1 : 0
count = var.password == null && local.manage_user_password == false ? 1 : 0

length = 41
special = true
Expand Down Expand Up @@ -29,7 +29,7 @@ resource "aws_rds_cluster" "this" {
engine_mode = var.engine_mode == "serverless" ? "provisioned" : var.engine_mode
port = var.port
master_username = var.username
master_password = var.password == null && var.manage_user_password == null ? random_password.master[0].result : var.password
master_password = var.password == null && local.manage_user_password == false ? random_password.master[0].result : var.password
manage_master_user_password = var.manage_user_password
database_name = var.database_name
db_cluster_instance_class = strcontains(var.engine, "aurora") ? null : var.db_server_class
Expand Down
4 changes: 2 additions & 2 deletions common.tf
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,14 @@ resource "aws_kms_key" "this" {
enable_key_rotation = var.kms_data.enable_key_rotation

tags = merge(var.tags, {
Name = var.kms_data.name == null ? "${local.prefix}-${var.name}-kms-key" : var.kms_data.name
Name = var.kms_data.name == null ? "${var.name}-kms-key" : var.kms_data.name
})
}

resource "aws_kms_alias" "this" {
count = var.kms_data.create ? 1 : 0

name = var.kms_data.name == null ? "alias/${local.prefix}-${var.name}-kms-key" : "alias/${var.kms_data.name}"
name = var.kms_data.name == null ? "alias/${var.name}-kms-key" : "alias/${var.kms_data.name}"
target_key_id = aws_kms_key.this[0].id
}

Expand Down
1 change: 1 addition & 0 deletions examples/aurora-multi-az/.terraform-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
latest:^1.7
65 changes: 65 additions & 0 deletions examples/aurora-multi-az/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 50 additions & 0 deletions examples/aurora-multi-az/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | ~> 1.3, < 2.0.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.0, < 6.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.74.0 |

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_aurora"></a> [aurora](#module\_aurora) | ../../ | n/a |

## Resources

| Name | Type |
|------|------|
| [aws_subnets.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnets) | data source |
| [aws_vpc.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_environment"></a> [environment](#input\_environment) | ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT' | `string` | `"poc"` | no |
| <a name="input_namespace"></a> [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `"arc"` | no |
| <a name="input_region"></a> [region](#input\_region) | AWS region | `string` | `"us-east-1"` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_arn"></a> [arn](#output\_arn) | Instance or Cluster ARN |
| <a name="output_endpoint"></a> [endpoint](#output\_endpoint) | Instance or Cluster Endpoint |
| <a name="output_id"></a> [id](#output\_id) | Instance or Cluster ID |
| <a name="output_identifier"></a> [identifier](#output\_identifier) | Instance or Cluster Identifier |
| <a name="output_kms_key_id"></a> [kms\_key\_id](#output\_kms\_key\_id) | Instance or Cluster KMS Key ID |
| <a name="output_master_user_secret"></a> [master\_user\_secret](#output\_master\_user\_secret) | Secret ARN |
| <a name="output_monitoring_role_arn"></a> [monitoring\_role\_arn](#output\_monitoring\_role\_arn) | Instance or Cluster Monitoring Role ARN |
| <a name="output_performance_insights_kms_key_id"></a> [performance\_insights\_kms\_key\_id](#output\_performance\_insights\_kms\_key\_id) | Instance or Cluster Performance Insights KMS Key ID |
| <a name="output_port"></a> [port](#output\_port) | Database server port |
| <a name="output_username"></a> [username](#output\_username) | Username for the Database |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
24 changes: 24 additions & 0 deletions examples/aurora-multi-az/data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
################################################
## imports
################################################
## vpc
data "aws_vpc" "this" {
filter {
name = "tag:Name"
values = ["${var.namespace}-poc-vpc"]
}
}

## network
data "aws_subnets" "private" {
filter {
name = "vpc-id"
values = [data.aws_vpc.this.id]
}
filter {
name = "tag:Name"
values = [
"*private*"
]
}
}
26 changes: 26 additions & 0 deletions examples/aurora-multi-az/local.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
locals {
security_group_data = {
create = true
description = "Security Group for Aurora Cluster"

ingress_rules = [
{
description = "Allow Aurora traffic"
cidr_block = data.aws_vpc.this.cidr_block
from_port = 5432
ip_protocol = "tcp"
to_port = 5432
}
]

egress_rules = [
{
description = "Allow all outbound traffic"
cidr_block = "0.0.0.0/0"
from_port = -1
ip_protocol = "-1"
to_port = -1
}
]
}
}
65 changes: 65 additions & 0 deletions examples/aurora-multi-az/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
################################################################################
## defaults
################################################################################
terraform {
required_version = "~> 1.3, < 2.0.0"

required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.0, < 6.0"
}
}
}

provider "aws" {
region = var.region
}

module "aurora" {
source = "../../"

environment = var.environment
namespace = var.namespace
vpc_id = data.aws_vpc.this.id

name = "${var.namespace}-${var.environment}-multi-az"
engine_type = "cluster"
port = 5432
username = "postgres"
engine = "aurora-postgresql"
engine_version = "16.2"
security_group_data = local.security_group_data

license_model = "postgresql-license"
rds_cluster_instances = [
{
instance_class = "db.t3.medium"
db_parameter_group_name = "default.aurora-postgresql16"
apply_immediately = true
promotion_tier = 1
},
{
instance_class = "db.t3.medium"
db_parameter_group_name = "default.aurora-postgresql16"
apply_immediately = true
promotion_tier = 2
}
]

db_subnet_group_data = {
name = "${var.namespace}-${var.environment}-subnet-group"
create = true
description = "Subnet group for rds instance"
subnet_ids = data.aws_subnets.private.ids
}

performance_insights_enabled = true

kms_data = {
create = true
description = "KMS for Performance insight and storage"
deletion_window_in_days = 7
enable_key_rotation = true
}
}
Loading