Skip to content
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

Initial implementation #1

Merged
merged 17 commits into from
Jan 6, 2019
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Compiled files
*.tfstate
*.tfstate.backup

# Module directory
.terraform
.idea
*.iml

.build-harness
build-harness
16 changes: 16 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
addons:
apt:
packages:
- git
- make
- curl

install:
- make init

script:
- make terraform/install
- make terraform/get-plugins
- make terraform/get-modules
- make terraform/lint
- make terraform/validate
4 changes: 2 additions & 2 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -178,15 +178,15 @@
APPENDIX: How to apply the Apache License to your work.

To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright [yyyy] [name of copyright owner]
Copyright 2019 Cloud Posse, LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
10 changes: 10 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
SHELL := /bin/bash

# List of targets the `readme` target should call before generating the readme
export README_DEPS ?= docs/targets.md docs/terraform.md

-include $(shell curl -sSL -o .build-harness "https://git.io/build-harness"; echo .build-harness)

## Lint terraform code
lint:
$(SELF) terraform/install terraform/get-modules terraform/get-plugins terraform/lint terraform/validate
329 changes: 327 additions & 2 deletions README.md

Large diffs are not rendered by default.

111 changes: 111 additions & 0 deletions README.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
---
#
# This is the canonical configuration for the `README.md`
# Run `make readme` to rebuild the `README.md`
#

# Name of this project
name: terraform-aws-rds-replica

# Tags of this project
tags:
- aws
- terraform
- terraform-modules
- databases
- rds
- aws-rds
- postgres
- mysql

# Categories of this project
categories:
- terraform-modules/databases

# Logo for this project
#logo: docs/logo.png

# License of this project
license: "APACHE2"

# Canonical GitHub repo
github_repo: cloudposse/terraform-aws-rds-replica

# Badges to display
badges:
- name: "Build Status"
image: "https://travis-ci.org/cloudposse/terraform-aws-rds-replica.svg?branch=master"
url: "https://travis-ci.org/cloudposse/terraform-aws-rds-replica"
- name: "Latest Release"
image: "https://img.shields.io/github/release/cloudposse/terraform-aws-rds-replica.svg"
url: "https://github.com/cloudposse/terraform-aws-rds-replica/releases/latest"
- name: "Slack Community"
image: "https://slack.cloudposse.com/badge.svg"
url: "https://slack.cloudposse.com"

related:
- name: "terraform-aws-rds"
description: "Terraform module to provision AWS RDS instances for MySQL or Postgres"
url: "https://github.com/cloudposse/terraform-aws-rds"
- name: "terraform-aws-rds-cluster"
description: "Terraform module to provision an RDS Aurora cluster for MySQL or Postgres"
url: "https://github.com/cloudposse/terraform-aws-rds-cluster"
- name: "terraform-aws-rds-cloudwatch-sns-alarms"
description: "Terraform module that configures important RDS alerts using CloudWatch and sends them to an SNS topic"
url: "https://github.com/cloudposse/terraform-aws-rds-cloudwatch-sns-alarms"

# Short description of this project
description: |-
Terraform module to provision AWS [`RDS`](https://aws.amazon.com/rds/) replica instances. These are best suited for reporting purposes.

**IMPORTANT** It is not possible to create a read replica for a DB Instance that belongs to an Aurora DB Cluster.

introduction: |-
The module will create an RDS replica instance:

* RDS Replica instance (MySQL, Postgres, SQL Server, Oracle)
* RDS Subnet Group
* RDS DB Security Group
* DNS Record in Route53 for the DB endpoint

# How to use this project
usage: |-
```hcl
module "rds_replica" {
source = "git::https://github.com/cloudposse/terraform-aws-rds-replica.git?ref=master"
namespace = "eg"
stage = "prod"
name = "reporting"
replicate_source_db = "eg-prod-db
dns_zone_id = "Z89FN1IW975KPE"
host_name = "reporting"
security_group_ids = ["sg-xxxxxxxx"]
database_port = 3306
multi_az = "true"
storage_type = "gp2"
storage_encrypted = "true"
instance_class = "db.t2.medium"
publicly_accessible = "false"
subnet_ids = ["subnet-xxxxxxxxx", "subnet-xxxxxxxxx"]
vpc_id = "vpc-xxxxxxxx"
auto_minor_version_upgrade = "true"
allow_major_version_upgrade = "false"
apply_immediately = "false"
maintenance_window = "Mon:03:00-Mon:04:00"
skip_final_snapshot = "false"
copy_tags_to_snapshot = "true"
backup_retention_period = 7
backup_window = "22:00-03:00"
}
```

include:
- "docs/targets.md"
- "docs/terraform.md"

# Contributors to this project
contributors:
- name: "Erik Osterman"
github: "osterman"
- name: "Andriy Knysh"
github: "aknysh"
10 changes: 10 additions & 0 deletions docs/targets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## Makefile Targets
```
Available targets:

help Help screen
help/all Display help for all targets
help/short This help short screen
lint Lint terraform code

```
50 changes: 50 additions & 0 deletions docs/terraform.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|:----:|:-----:|:-----:|
| allow_major_version_upgrade | Allow major version upgrade | string | `false` | no |
| apply_immediately | Specifies whether any database modifications are applied immediately, or during the next maintenance window | string | `false` | no |
| attributes | Additional attributes (e.g. `1`) | list | `<list>` | no |
| auto_minor_version_upgrade | Allow automated minor version upgrade (e.g. from Postgres 9.5.3 to Postgres 9.5.4) | string | `true` | no |
| backup_retention_period | Backup retention period in days. Must be > 0 to enable backups | string | `0` | no |
| backup_window | When AWS can perform DB snapshots, can't overlap with maintenance window | string | `22:00-03:00` | no |
| copy_tags_to_snapshot | Copy tags from DB to a snapshot | string | `true` | no |
| database_port | Database port (_e.g._ `3306` for `MySQL`). Used in the DB Security Group to allow access to the DB instance from the provided `security_group_ids` | string | - | yes |
| db_parameter | A list of DB parameters to apply. Note that parameters may differ from a DB family to another | list | `<list>` | no |
| delimiter | Delimiter to be used between `name`, `namespace`, `stage` and `attributes` | string | `-` | no |
| dns_zone_id | The ID of the DNS Zone in Route53 where a new DNS record will be created for the DB host name | string | `` | no |
| enabled | Set to false to prevent the module from creating any resources | string | `true` | no |
| final_snapshot_identifier | Final snapshot identifier e.g.: some-db-final-snapshot-2015-06-26-06-05 | string | `` | no |
| host_name | The DB host name created in Route53 | string | `db` | no |
| instance_class | Class of RDS instance | string | - | yes |
| iops | The amount of provisioned IOPS. Setting this implies a storage_type of 'io1'. Default is 0 if rds storage type is not 'io1' | string | `0` | no |
| kms_key_id | The ARN for the KMS encryption key. If creating an encrypted replica, set this to the destination KMS ARN | string | `` | no |
| maintenance_window | The window to perform maintenance in. Syntax: 'ddd:hh24:mi-ddd:hh24:mi' UTC | string | `Mon:03:00-Mon:04:00` | no |
| monitoring_interval | The interval, in seconds, between points when Enhanced Monitoring metrics are collected for the DB instance. To disable collecting Enhanced Monitoring metrics, specify 0. Valid Values are 0, 1, 5, 10, 15, 30, 60. | string | `0` | no |
| multi_az | Set to true if multi AZ deployment must be supported | string | `false` | no |
| name | The Name of the application or solution (e.g. `bastion` or `portal`) | string | - | yes |
| namespace | Namespace (e.g. `eg` or `cp`) | string | - | yes |
| parameter_group_name | Name of the DB parameter group to associate | string | `` | no |
| publicly_accessible | Determines if database can be publicly available (NOT recommended) | string | `false` | no |
| replicate_source_db | Specifies that this resource is a Replicate database, and to use this value as the source database. This correlates to the identifier of another Amazon RDS Database to replicate. Note that if you are creating a cross-region replica of an encrypted database you will also need to specify a kms_key_id. See [DB Instance Replication](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.Replication.html) and [Working with PostgreSQL and MySQL Read Replicas](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_ReadRepl.html) for more information on using Replication. | string | - | yes |
| security_group_ids | The IDs of the security groups from which to allow `ingress` traffic to the DB instance | list | `<list>` | no |
| skip_final_snapshot | If true (default), no snapshot will be made before deleting DB | string | `true` | no |
| snapshot_identifier | Snapshot identifier e.g: rds:production-2015-06-26-06-05. If specified, the module create cluster from the snapshot | string | `` | no |
| stage | Stage (e.g. `prod`, `dev`, `staging`) | string | - | yes |
| storage_encrypted | Specifies whether the DB instance is encrypted. The default is false if not specified. | string | `false` | no |
| storage_type | One of 'standard' (magnetic), 'gp2' (general purpose SSD), or 'io1' (provisioned IOPS SSD). | string | `standard` | no |
| subnet_ids | List of subnets for the DB | list | - | yes |
| tags | Additional tags (e.g. map(`BusinessUnit`,`XYZ`) | map | `<map>` | no |
| vpc_id | VPC ID the DB instance will be created in | string | - | yes |

## Outputs

| Name | Description |
|------|-------------|
| hostname | DNS host name of the instance |
| instance_address | Address of the instance |
| instance_endpoint | DNS Endpoint of the instance |
| instance_id | ID of the instance |
| security_group_id | ID of the Security Group |
| subnet_group_id | ID of the Subnet Group |

113 changes: 113 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
module "label" {
source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.3.3"
enabled = "${var.enabled}"
namespace = "${var.namespace}"
name = "${var.name}"
stage = "${var.stage}"
delimiter = "${var.delimiter}"
attributes = "${var.attributes}"
tags = "${var.tags}"
}

module "final_snapshot_label" {
source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.3.3"
enabled = "${var.enabled}"
namespace = "${var.namespace}"
name = "${var.name}"
stage = "${var.stage}"
delimiter = "${var.delimiter}"
attributes = ["${compact(concat(var.attributes, list("final", "snapshot")))}"]
tags = "${var.tags}"
}

resource "aws_kms_key" "default" {
count = "${local.enabled && length(var.kms_key_id) == 0 ? 1 : 0}"
description = "${module.label.id}"
deletion_window_in_days = 10
enable_key_rotation = true
tags = "${module.label.tags}"
}

locals {
enabled = "${var.enabled == "true"}"
final_snapshot_identifier = "${length(var.final_snapshot_identifier) > 0 ? var.final_snapshot_identifier : module.final_snapshot_label.id}"
kms_key_id = "${length(var.kms_key_id) > 0 ? var.kms_key_id : join("", aws_kms_key.default.*.arn)}"
}

resource "aws_db_instance" "default" {
count = "${local.enabled ? 1 : 0}"
identifier = "${module.label.id}"
port = "${var.database_port}"
instance_class = "${var.instance_class}"
storage_encrypted = "${var.storage_encrypted}"
vpc_security_group_ids = ["${aws_security_group.default.*.id}"]
db_subnet_group_name = "${join("", aws_db_subnet_group.default.*.name)}"
multi_az = "${var.multi_az}"
storage_type = "${var.storage_type}"
iops = "${var.iops}"
publicly_accessible = "${var.publicly_accessible}"
snapshot_identifier = "${var.snapshot_identifier}"
allow_major_version_upgrade = "${var.allow_major_version_upgrade}"
auto_minor_version_upgrade = "${var.auto_minor_version_upgrade}"
apply_immediately = "${var.apply_immediately}"
maintenance_window = "${var.maintenance_window}"
skip_final_snapshot = "${var.skip_final_snapshot}"
copy_tags_to_snapshot = "${var.copy_tags_to_snapshot}"
backup_retention_period = "${var.backup_retention_period}"
backup_window = "${var.backup_window}"
tags = "${module.label.tags}"
final_snapshot_identifier = "${local.final_snapshot_identifier}"
kms_key_id = "${local.kms_key_id}"
monitoring_interval = "${var.monitoring_interval}"
replicate_source_db = "${var.replicate_source_db}"
}

resource "aws_db_subnet_group" "default" {
count = "${local.enabled ? 1 : 0}"
name = "${module.label.id}"
subnet_ids = ["${var.subnet_ids}"]
tags = "${module.label.tags}"
}

resource "aws_security_group" "default" {
count = "${local.enabled ? 1 : 0}"
name = "${module.label.id}"
description = "Allow inbound traffic from the security groups"
vpc_id = "${var.vpc_id}"

tags = "${module.label.tags}"
}

locals {
security_group_id = "${join("", aws_security_group.default.*.id)}"
}

resource "aws_security_group_rule" "allow_ingress" {
count = "${local.enabled ? length(var.security_group_ids) : 0}"
security_group_id = "${local.security_group_id}"
type = "ingress"
from_port = "${var.database_port}"
to_port = "${var.database_port}"
protocol = "tcp"
source_security_group_id = "${var.security_group_ids[count.index]}"
}

resource "aws_security_group_rule" "allow_egress" {
count = "${local.enabled ? 1 : 0}"
security_group_id = "${local.security_group_id}"
type = "egress"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}

module "dns_host_name" {
source = "git::https://github.com/cloudposse/terraform-aws-route53-cluster-hostname.git?ref=tags/0.2.5"
enabled = "${local.enabled && length(var.dns_zone_id) > 0 ? "true" : "false"}"
namespace = "${var.namespace}"
name = "${var.host_name}"
stage = "${var.stage}"
zone_id = "${var.dns_zone_id}"
records = "${aws_db_instance.default.*.address}"
}
29 changes: 29 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
output "instance_id" {
value = "${join("", aws_db_instance.default.*.id)}"
description = "ID of the instance"
}

output "instance_address" {
value = "${join("", aws_db_instance.default.*.address)}"
description = "Address of the instance"
}

output "instance_endpoint" {
value = "${join("", aws_db_instance.default.*.endpoint)}"
description = "DNS Endpoint of the instance"
}

output "subnet_group_id" {
value = "${join("", aws_db_subnet_group.default.*.id)}"
description = "ID of the Subnet Group"
}

output "security_group_id" {
value = "${join("", aws_security_group.default.*.id)}"
description = "ID of the Security Group"
}

output "hostname" {
value = "${module.dns_host_name.hostname}"
description = "DNS host name of the instance"
}
Loading