├── tests ├── spec │ ├── .gitignore │ ├── vpc_spec.rb │ ├── rds_spec.rb │ └── subnet_spec.rb ├── .rspec ├── Gemfile ├── Rakefile └── Gemfile.lock ├── .gitignore ├── terraform-repltask ├── table_mappings.tpl ├── dms-repl-task.tf └── _variables.tf ├── remote-state ├── _data.tf ├── _variables.tf └── main.tf ├── terraform-main ├── db-subnets.tf ├── rds-sg.tf ├── vpc.tf ├── iam-roles.tf ├── dms-repl-instance.tf ├── dms-endpoints.tf ├── rds.tf └── _variables.tf └── README.md /tests/spec/.gitignore: -------------------------------------------------------------------------------- 1 | secrets.yml 2 | -------------------------------------------------------------------------------- /tests/.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --format documentation 3 | -------------------------------------------------------------------------------- /tests/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | gem 'rake' 3 | gem 'awspec' 4 | gem 'aws-sdk' -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/*.terraform 2 | **/*.tfstate 3 | **/*.tfstate.backup 4 | **/.DS_Store 5 | **/envvars 6 | -------------------------------------------------------------------------------- /tests/Rakefile: -------------------------------------------------------------------------------- 1 | require 'rspec/core/rake_task' 2 | RSpec::Core::RakeTask.new('spec') 3 | task :default => :spec 4 | -------------------------------------------------------------------------------- /terraform-repltask/table_mappings.tpl: -------------------------------------------------------------------------------- 1 | {"rules":[{"rule-type":"selection","rule-id":"1","rule-name":"1","object-locator":{"schema-name":"ROCKPROPS%","table-name":"WEB%"},"rule-action":"include"}]} -------------------------------------------------------------------------------- /remote-state/_data.tf: -------------------------------------------------------------------------------- 1 | # Data source used to retrieve the AWS account ID 2 | 3 | data "aws_caller_identity" "current" {} 4 | 5 | output "account_id" { 6 | value = "${data.aws_caller_identity.current.account_id}" 7 | } 8 | -------------------------------------------------------------------------------- /tests/spec/vpc_spec.rb: -------------------------------------------------------------------------------- 1 | describe vpc(ENV['TF_VAR_stack_name'] + '-' + ENV['TF_VAR_environment'] + '-vpc') do 2 | it { should exist } 3 | it { should be_available } 4 | its(:cidr_block) { should eq '10.0.0.0/16' } 5 | it { should have_route_table(ENV['TF_VAR_stack_name'] + '-database-subnet-' + ENV['TF_VAR_environment'] + '-ap-southeast-2a') } 6 | it { should have_route_table(ENV['TF_VAR_stack_name'] + '-database-subnet-' + ENV['TF_VAR_environment'] + '-ap-southeast-2b') } 7 | it { should have_route_table(ENV['TF_VAR_stack_name'] + '-database-subnet-' + ENV['TF_VAR_environment'] + '-ap-southeast-2c') } 8 | end 9 | -------------------------------------------------------------------------------- /tests/spec/rds_spec.rb: -------------------------------------------------------------------------------- 1 | describe rds(ENV['TF_VAR_stack_name'] + '-' + ENV['TF_VAR_environment'] +'-mydb-rds') do 2 | it { should exist } 3 | it { should be_available } 4 | its(:db_instance_identifier) { should eq ENV['TF_VAR_stack_name'] + '-' + ENV['TF_VAR_environment'] + '-mydb-rds' } 5 | its(:db_instance_class) { should eq 'db.t2.micro' } 6 | its(:multi_az) { should eq false } 7 | it { should belong_to_vpc(ENV['TF_VAR_stack_name'] + '-' + ENV['TF_VAR_environment'] +'-vpc') } 8 | it { should belong_to_db_subnet_group(ENV['TF_VAR_stack_name'] + '_' + ENV['TF_VAR_environment'] +'_rds_subnet_group') } 9 | end 10 | -------------------------------------------------------------------------------- /terraform-main/db-subnets.tf: -------------------------------------------------------------------------------- 1 | #============================================================== 2 | # Database / outputs.tf 3 | #============================================================== 4 | 5 | # Create a subnet in each availability zone. 6 | 7 | resource "aws_subnet" "database" { 8 | count = "${length(var.availability_zones)}" 9 | vpc_id = "${aws_vpc.vpc.id}" 10 | 11 | cidr_block = "${element(var.database_subnet_cidr, count.index)}" 12 | availability_zone = "${lookup(var.availability_zones, count.index)}" 13 | 14 | tags { 15 | Name = "${var.stack_name}-database-subnet-${var.environment}-${lookup(var.availability_zones, count.index)}" 16 | owner = "${var.owner}" 17 | stack_name = "${var.stack_name}" 18 | environment = "${var.environment}" 19 | created_by = "terraform" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /remote-state/_variables.tf: -------------------------------------------------------------------------------- 1 | #============================================================== 2 | # variables.tf 3 | #============================================================== 4 | 5 | # This file is used to set variables that are passed to sub 6 | # modules to build our stack 7 | 8 | #-------------------------------------------------------------- 9 | # Global Config 10 | #-------------------------------------------------------------- 11 | 12 | # Variables used in the global config 13 | 14 | variable "region" { 15 | description = "The AWS region we want to build this stack in" 16 | default = "ap-southeast-2" 17 | } 18 | 19 | variable "stack_name" { 20 | description = "The name of our application" 21 | default = "dblink" 22 | } 23 | 24 | variable "owner" { 25 | description = "A group email address to be used in tags" 26 | default = "autobots@ga.gov.au" 27 | } 28 | -------------------------------------------------------------------------------- /tests/spec/subnet_spec.rb: -------------------------------------------------------------------------------- 1 | describe subnet(ENV['TF_VAR_stack_name'] + '-database-subnet-' + ENV['TF_VAR_environment'] + '-ap-southeast-2b') do 2 | it { should exist } 3 | it { should be_available } 4 | it { should belong_to_vpc(ENV['TF_VAR_stack_name'] + '-' + ENV['TF_VAR_environment'] + '-vpc') } 5 | end 6 | 7 | describe subnet(ENV['TF_VAR_stack_name'] + '-database-subnet-' + ENV['TF_VAR_environment'] + '-ap-southeast-2a') do 8 | it { should exist } 9 | it { should be_available } 10 | it { should belong_to_vpc(ENV['TF_VAR_stack_name'] + '-' + ENV['TF_VAR_environment'] + '-vpc') } 11 | end 12 | 13 | describe subnet(ENV['TF_VAR_stack_name'] + '-database-subnet-' + ENV['TF_VAR_environment'] + '-ap-southeast-2c') do 14 | it { should exist } 15 | it { should be_available } 16 | it { should belong_to_vpc(ENV['TF_VAR_stack_name'] + '-' + ENV['TF_VAR_environment'] + '-vpc') } 17 | end 18 | -------------------------------------------------------------------------------- /terraform-main/rds-sg.tf: -------------------------------------------------------------------------------- 1 | #============================================================== 2 | # Database / rds-sg.tf 3 | #============================================================== 4 | 5 | # Security groups for the RDS. 6 | 7 | resource "aws_security_group" "rds" { 8 | name = "${var.stack_name}_${var.environment}_rds_sg" 9 | description = "Allow no inbound traffic" 10 | vpc_id = "${aws_vpc.vpc.id}" 11 | 12 | # ingress { 13 | # from_port = "${var.db_port_num}" 14 | # to_port = "${var.db_port_num}" 15 | # protocol = "TCP" 16 | # security_groups = ["${var.app_sg_id}"] 17 | # } 18 | 19 | egress { 20 | from_port = 0 21 | to_port = 0 22 | protocol = "-1" 23 | cidr_blocks = ["0.0.0.0/0"] 24 | } 25 | tags { 26 | Name = "${var.stack_name}-${var.environment}-rds-sg" 27 | owner = "${var.owner}" 28 | stack_name = "${var.stack_name}" 29 | environment = "${var.environment}" 30 | created_by = "terraform" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /terraform-repltask/dms-repl-task.tf: -------------------------------------------------------------------------------- 1 | #============================================================== 2 | # Database / dms-repl-task.tf 3 | #============================================================== 4 | 5 | # Create a new DMS replication task 6 | resource "aws_dms_replication_task" "dblink" { 7 | migration_type = "full-load" 8 | 9 | #replication_instance_arn = "${aws_dms_replication_instance.link.replication_instance_arn}" 10 | replication_instance_arn = "${var.replication_instance_arn}" 11 | replication_task_id = "${var.replication_task_id}" 12 | source_endpoint_arn = "${var.dms_source_arn}" 13 | table_mappings = "${data.template_file.table_mappings.rendered}" 14 | target_endpoint_arn = "${var.dms_target_arn}" 15 | 16 | tags { 17 | Name = "${var.stack_name}-dms-${var.environment}-replication-task" 18 | owner = "${var.owner}" 19 | stack_name = "${var.stack_name}" 20 | environment = "${var.environment}" 21 | created_by = "terraform" 22 | } 23 | } 24 | 25 | # Reference the DMS table mappings 26 | data "template_file" "table_mappings" { 27 | template = "${file("table_mappings.tpl")}" 28 | } 29 | -------------------------------------------------------------------------------- /remote-state/main.tf: -------------------------------------------------------------------------------- 1 | #============================================================== 2 | # main.tf 3 | #============================================================== 4 | 5 | provider "aws" { 6 | region = "${var.region}" 7 | } 8 | 9 | #-------------------------------------------------------------- 10 | # Remote State Infrastructure 11 | #-------------------------------------------------------------- 12 | 13 | # Create the remote objects that terraform will use to store 14 | # state - an S3 bucket and a DynamoDB table. 15 | 16 | resource "aws_s3_bucket" "terraform_state" { 17 | bucket = "tfstate-${data.aws_caller_identity.current.account_id}-db" 18 | acl = "private" 19 | 20 | tags { 21 | Name = "terraform-state" 22 | owner = "${var.owner}" 23 | stack_name = "${var.stack_name}" 24 | created_by = "space-provisioner" 25 | } 26 | } 27 | 28 | resource "aws_dynamodb_table" "terraform_statelock" { 29 | name = "terraform-lock-db" 30 | read_capacity = 20 31 | write_capacity = 20 32 | hash_key = "LockID" 33 | 34 | attribute { 35 | name = "LockID" 36 | type = "S" 37 | } 38 | 39 | tags { 40 | Name = "terraform-state-locking" 41 | owner = "${var.owner}" 42 | stack_name = "${var.stack_name}" 43 | created_by = "space-provisioner" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /terraform-main/vpc.tf: -------------------------------------------------------------------------------- 1 | #============================================================== 2 | # Shared / vpc.tf 3 | #============================================================== 4 | 5 | # Create the Virtual Private Cloud that the rest of our 6 | # infratructure will be built in. 7 | 8 | resource "aws_vpc" "vpc" { 9 | cidr_block = "${var.vpc_cidr}" 10 | enable_dns_support = true 11 | enable_dns_hostnames = true 12 | 13 | tags { 14 | Name = "${var.stack_name}-${var.environment}-vpc" 15 | owner = "${var.owner}" 16 | stack_name = "${var.stack_name}" 17 | environment = "${var.environment}" 18 | created_by = "terraform" 19 | } 20 | } 21 | 22 | resource "aws_vpn_gateway" "vpn_gw" { 23 | vpc_id = "${aws_vpc.vpc.id}" 24 | 25 | tags { 26 | Name = "${var.stack_name}-${var.environment}-vpn" 27 | owner = "${var.owner}" 28 | stack_name = "${var.stack_name}" 29 | environment = "${var.environment}" 30 | created_by = "terraform" 31 | } 32 | } 33 | 34 | # Internet gateway - remove for network isolation 35 | resource "aws_internet_gateway" "default" { 36 | vpc_id = "${aws_vpc.vpc.id}" 37 | 38 | tags { 39 | Name = "${var.stack_name}-${var.environment}-vpc" 40 | owner = "${var.owner}" 41 | stack_name = "${var.stack_name}" 42 | environment = "${var.environment}" 43 | created_by = "terraform" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /terraform-main/iam-roles.tf: -------------------------------------------------------------------------------- 1 | #============================================================== 2 | # Database / iam-roles.tf 3 | #============================================================== 4 | 5 | # Create a role that can be assummed by the root account 6 | resource "aws_iam_role" "dmsvpcrole" { 7 | name = "dms-vpc-role" 8 | path = "/" 9 | 10 | assume_role_policy = < 0.7) 6 | json (~> 1.7, >= 1.7.7) 7 | minitest (~> 5.1) 8 | thread_safe (~> 0.3, >= 0.3.4) 9 | tzinfo (~> 1.1) 10 | aws-sdk (2.6.44) 11 | aws-sdk-resources (= 2.6.44) 12 | aws-sdk-core (2.6.44) 13 | aws-sigv4 (~> 1.0) 14 | jmespath (~> 1.0) 15 | aws-sdk-resources (2.6.44) 16 | aws-sdk-core (= 2.6.44) 17 | aws-sigv4 (1.0.0) 18 | aws_config (0.0.4) 19 | awsecrets (1.5.0) 20 | aws-sdk (>= 2.2, < 2.7) 21 | aws_config (= 0.0.4) 22 | awspec (0.61.1) 23 | activesupport (~> 4.0) 24 | aws-sdk (>= 2.2, < 2.7) 25 | awsecrets (~> 1.5.0) 26 | rspec (~> 3.0) 27 | rspec-its 28 | term-ansicolor 29 | thor 30 | diff-lcs (1.2.5) 31 | i18n (0.7.0) 32 | jmespath (1.3.1) 33 | json (1.8.3) 34 | minitest (5.9.1) 35 | rake (11.3.0) 36 | rspec (3.5.0) 37 | rspec-core (~> 3.5.0) 38 | rspec-expectations (~> 3.5.0) 39 | rspec-mocks (~> 3.5.0) 40 | rspec-core (3.5.4) 41 | rspec-support (~> 3.5.0) 42 | rspec-expectations (3.5.0) 43 | diff-lcs (>= 1.2.0, < 2.0) 44 | rspec-support (~> 3.5.0) 45 | rspec-its (1.2.0) 46 | rspec-core (>= 3.0.0) 47 | rspec-expectations (>= 3.0.0) 48 | rspec-mocks (3.5.0) 49 | diff-lcs (>= 1.2.0, < 2.0) 50 | rspec-support (~> 3.5.0) 51 | rspec-support (3.5.0) 52 | term-ansicolor (1.4.0) 53 | tins (~> 1.0) 54 | thor (0.19.1) 55 | thread_safe (0.3.5) 56 | tins (1.13.0) 57 | tzinfo (1.2.2) 58 | thread_safe (~> 0.1) 59 | 60 | PLATFORMS 61 | ruby 62 | 63 | DEPENDENCIES 64 | aws-sdk 65 | awspec 66 | rake 67 | 68 | BUNDLED WITH 69 | 1.13.7 70 | -------------------------------------------------------------------------------- /terraform-repltask/_variables.tf: -------------------------------------------------------------------------------- 1 | #============================================================== 2 | # Database / outputs.tf 3 | #============================================================== 4 | #============================================================== 5 | # variables.tf 6 | #============================================================== 7 | 8 | # This file is used to set variables that are passed to sub 9 | # modules to build our stack 10 | 11 | #-------------------------------------------------------------- 12 | # Terraform Remote State 13 | #-------------------------------------------------------------- 14 | 15 | # Define the remote objects that terraform will use to store 16 | # state. We use a remote store, so that you can run destroy 17 | # from a seperate machine to the one it was built on. 18 | 19 | terraform { 20 | required_version = ">= 0.9.1" 21 | 22 | backend "s3" { 23 | # This is an s3bucket you will need to create in your aws 24 | # space 25 | bucket = "tfstate-701941925126-db" 26 | 27 | # The key should be unique to each stack, because we want to 28 | # have multiple enviornments alongside each other we set 29 | # this dynamically in the bitbucket-pipelines.yml with the 30 | # --backend 31 | key = "dblink-repl" 32 | 33 | region = "ap-southeast-2" 34 | 35 | # This is a DynamoDB table with the Primary Key set to LockID 36 | lock_table = "terraform-lock-db" 37 | 38 | #Enable server side encryption on your terraform state 39 | encrypt = true 40 | } 41 | } 42 | 43 | #-------------------------------------------------------------- 44 | # Global Config 45 | #-------------------------------------------------------------- 46 | 47 | # Variables used in the global config 48 | 49 | provider "aws" { 50 | region = "ap-southeast-2" 51 | } 52 | 53 | variable "availability_zones" { 54 | description = "Geographically distanced areas inside the region" 55 | 56 | default = { 57 | "0" = "ap-southeast-2a" 58 | "1" = "ap-southeast-2b" 59 | "2" = "ap-southeast-2c" 60 | } 61 | } 62 | 63 | #-------------------------------------------------------------- 64 | # Meta Data 65 | #-------------------------------------------------------------- 66 | 67 | # Used in tagginga and naming the resources 68 | 69 | variable "stack_name" { 70 | description = "The name of our application" 71 | default = "integration-dblink" 72 | } 73 | 74 | variable "owner" { 75 | description = "A group email address to be used in tags" 76 | default = "autobots@ga.gov.au" 77 | } 78 | 79 | variable "environment" { 80 | description = "Used for seperating terraform backends and naming items" 81 | default = "dev" 82 | } 83 | 84 | #-------------------------------------------------------------- 85 | # DMS Config 86 | #-------------------------------------------------------------- 87 | 88 | #Variables used in the database config 89 | 90 | variable "dms_source_arn" { 91 | description = "The ARN of the source database" 92 | } 93 | 94 | variable "dms_target_arn" { 95 | description = "The ARN of the target database" 96 | } 97 | 98 | variable "replication_instance_arn" { 99 | description = "The ARN of the replication instance" 100 | } 101 | 102 | variable "replication_task_id" { 103 | description = "Unique identifier for the task" 104 | } 105 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DMS Example 2 | 3 | ## Creates an example AWS DMS for replicating an (on-prem) Oracle database to a cloud-based Postgres database. 4 | 5 | ### terraform-main 6 | This will create: 7 | 8 | * VPC with a VPN gateway 9 | * Source and target RDS instances 10 | * DMS Endpoints for each RDS instance 11 | * DMS Replication instance 12 | 13 | This is designed to be deployed once. 14 | 15 | ### terraform-repltask 16 | This will create: 17 | 18 | * DMS Replication Task 19 | 20 | This is designed to be deployed multiple times. 21 | 22 | ## Set Variables 23 | 24 | Set the following variables in variables.tf: 25 | 26 | *Terraform Remote State* 27 | * bucket - an s3 bucket that exists in your aws space (see Preperation) 28 | * lock_table - a dynamodb table in your aws space with the primary key LockID (see Preperation) 29 | 30 | *Replication main* 31 | 32 | Set the following environment variables (substituting the details of your application) 33 | 34 | * `export TF_VAR_source_snapshot=` 35 | * `export TF_VAR_source_db_name=` 36 | * `export TF_VAR_source_password=` 37 | * `export TF_VAR_source_username=` 38 | * `export TF_VAR_source_app_username=` 39 | * `export TF_VAR_source_app_password=` 40 | * `export TF_VAR_target_db_name=` 41 | * `export TF_VAR_target_password=` 42 | * `export TF_VAR_target_username=` 43 | 44 | *Replication task* 45 | 46 | Edit `_variables.tf`. Update `key = "dblink-repl"` within the s3 backend definition to another value, for example `key = "dblink-appname"`. 47 | 48 | Set the following environment variables (substituting the details of your application) 49 | 50 | * `export TF_VAR_stack_name=` 51 | * `export TF_VAR_dms_source_arn=` 52 | * `export TF_VAR_dms_target_arn=` 53 | * `export TF_VAR_replication_instance_arn=` 54 | * `export TF_VAR_replication_task_id=` 55 | 56 | ## Creating your infrastructure 57 | 58 | 1. `terraform init` 59 | 2. `terraform plan` 60 | 3. `terraform apply` 61 | 62 | This command will output your database endpoint, which you will need below. 63 | 64 | ## Destroying your infrastructure 65 | 66 | 1. If you have run the infrastructure overnight you will have backups in your backup bucket. You will need to remove these so the terraform can destroy the bucket. 67 | 1. `terraform destroy` 68 | 69 | This is assuming that you ran `terraform init` previously on the same machine 70 | This command will tear down everything that terraform created. 71 | 72 | ## VPC Peering 73 | 74 | Follow the [VPC Peering guide](https://docs.aws.amazon.com/AmazonVPC/latest/PeeringGuide/vpc-peering-basics.html): 75 | 76 | 1. Ensure your requester and accepter VPCs do not have overlapping IP address spaces. 77 | 1. The owner of the requester VPC sends a request to the owner of the accepter VPC to create the VPC peering connection. 78 | 1. The owner of the accepter VPC accepts the VPC peering connection request to activate the VPC peering connection. 79 | 1. Add a route to each VPC's route tables that points to the IP address range of the other VPC. 80 | 1. Update security groups to allow traffic from either VPC. 81 | 1. Modify your VPC connection to enable DNS hostname resolution. 82 | -------------------------------------------------------------------------------- /terraform-main/rds.tf: -------------------------------------------------------------------------------- 1 | #============================================================== 2 | # Database / rds.tf 3 | #============================================================== 4 | 5 | # Create a target RDS instance 6 | 7 | resource "aws_db_instance" "target" { 8 | identifier = "${var.stack_name}-${var.environment}-${var.identifier}-target" 9 | allocated_storage = "${var.target_storage}" 10 | engine = "${var.target_engine}" 11 | engine_version = "${var.target_engine_version}" 12 | instance_class = "${var.target_instance_class}" 13 | name = "${var.target_db_name}" 14 | username = "${var.target_username}" 15 | password = "${var.target_password}" 16 | vpc_security_group_ids = ["${aws_security_group.rds.id}"] 17 | multi_az = "${var.target_rds_is_multi_az}" 18 | db_subnet_group_name = "${aws_db_subnet_group.rds-subnet.id}" 19 | backup_retention_period = "${var.target_backup_retention_period}" 20 | backup_window = "${var.target_backup_window}" 21 | maintenance_window = "${var.target_maintenance_window}" 22 | storage_encrypted = "${var.target_storage_encrypted}" 23 | 24 | # Skip final snapshot for environments that don't start with 'p' 25 | # e.g. for environments that aren't 'prod' 26 | skip_final_snapshot = "${replace(replace(var.environment, "/^[^p].*/", "1"),"/^p.*$/", "0")}" 27 | 28 | tags { 29 | Name = "${var.stack_name}_rds_target" 30 | owner = "${var.owner}" 31 | stack_name = "${var.stack_name}" 32 | environment = "${var.environment}" 33 | created_by = "terraform" 34 | } 35 | } 36 | 37 | # Create a source RDS instance (will be removed when on-premise database is being used) 38 | 39 | resource "aws_db_instance" "source" { 40 | identifier = "${var.stack_name}-${var.environment}-${var.identifier}-source" 41 | allocated_storage = "${var.source_storage}" 42 | engine = "${var.source_engine}" 43 | engine_version = "${var.source_engine_version}" 44 | instance_class = "${var.source_instance_class}" 45 | name = "${var.source_db_name}" 46 | username = "${var.source_username}" 47 | password = "${var.source_password}" 48 | vpc_security_group_ids = ["${aws_security_group.rds.id}"] 49 | multi_az = "${var.source_rds_is_multi_az}" 50 | db_subnet_group_name = "${aws_db_subnet_group.rds-subnet.id}" 51 | backup_retention_period = "${var.source_backup_retention_period}" 52 | backup_window = "${var.source_backup_window}" 53 | maintenance_window = "${var.source_maintenance_window}" 54 | storage_encrypted = "${var.source_storage_encrypted}" 55 | snapshot_identifier = "${var.source_snapshot}" 56 | 57 | # only for dev/test builds 58 | skip_final_snapshot = true 59 | 60 | tags { 61 | Name = "${var.stack_name}_rds_source" 62 | owner = "${var.owner}" 63 | stack_name = "${var.stack_name}" 64 | environment = "${var.environment}" 65 | created_by = "terraform" 66 | } 67 | } 68 | 69 | # Create a subnet group to house the RDS 70 | 71 | resource "aws_db_subnet_group" "rds-subnet" { 72 | name = "${var.stack_name}_${var.environment}_rds_subnet_group" 73 | description = "${var.stack_name} RDS Subnet Group" 74 | subnet_ids = ["${aws_subnet.database.*.id}"] 75 | 76 | tags { 77 | Name = "${var.stack_name}_${var.environment}_rds_subnet_group" 78 | owner = "${var.owner}" 79 | stack_name = "${var.stack_name}" 80 | environment = "${var.environment}" 81 | created_by = "terraform" 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /terraform-main/_variables.tf: -------------------------------------------------------------------------------- 1 | #============================================================== 2 | # Database / outputs.tf 3 | #============================================================== 4 | #============================================================== 5 | # variables.tf 6 | #============================================================== 7 | 8 | # This file is used to set variables that are passed to sub 9 | # modules to build our stack 10 | 11 | #-------------------------------------------------------------- 12 | # Terraform Remote State 13 | #-------------------------------------------------------------- 14 | 15 | # Define the remote objects that terraform will use to store 16 | # state. We use a remote store, so that you can run destroy 17 | # from a seperate machine to the one it was built on. 18 | 19 | terraform { 20 | required_version = ">= 0.9.1" 21 | 22 | backend "s3" { 23 | # This is an s3bucket you will need to create in your aws 24 | # space 25 | bucket = "tfstate-db" 26 | 27 | # The key should be unique to each stack, because we want to 28 | # have multiple enviornments alongside each other we set 29 | # this dynamically in the bitbucket-pipelines.yml with the 30 | # --backend 31 | key = "dblink" 32 | 33 | region = "ap-southeast-2" 34 | 35 | # This is a DynamoDB table with the Primary Key set to LockID 36 | lock_table = "terraform-lock-db" 37 | 38 | #Enable server side encryption on your terraform state 39 | encrypt = true 40 | } 41 | } 42 | 43 | #-------------------------------------------------------------- 44 | # Global Config 45 | #-------------------------------------------------------------- 46 | 47 | # Variables used in the global config 48 | 49 | provider "aws" { 50 | region = "ap-southeast-2" 51 | } 52 | 53 | variable "availability_zones" { 54 | description = "Geographically distanced areas inside the region" 55 | 56 | default = { 57 | "0" = "ap-southeast-2a" 58 | "1" = "ap-southeast-2b" 59 | "2" = "ap-southeast-2c" 60 | } 61 | } 62 | 63 | #-------------------------------------------------------------- 64 | # Meta Data 65 | #-------------------------------------------------------------- 66 | 67 | # Used in tagginga and naming the resources 68 | 69 | variable "stack_name" { 70 | description = "The name of our application" 71 | default = "dblink" 72 | } 73 | 74 | variable "owner" { 75 | description = "A group email address to be used in tags" 76 | default = "autobots@ga.gov.au" 77 | } 78 | 79 | variable "environment" { 80 | description = "Used for seperating terraform backends and naming items" 81 | default = "prod" 82 | } 83 | 84 | #-------------------------------------------------------------- 85 | # DMS general config 86 | #-------------------------------------------------------------- 87 | 88 | variable "identifier" { 89 | default = "rds" 90 | description = "Name of the database in the RDS" 91 | } 92 | 93 | #-------------------------------------------------------------- 94 | # DMS target config 95 | #-------------------------------------------------------------- 96 | 97 | variable "target_backup_retention_period" { 98 | # Days 99 | default = "30" 100 | description = "Retention of RDS backups" 101 | } 102 | 103 | variable "target_backup_window" { 104 | # 12:00AM-03:00AM AEST 105 | default = "14:00-17:00" 106 | description = "RDS backup window" 107 | } 108 | 109 | variable "target_db_name" { 110 | description = "Name of the target database" 111 | } 112 | 113 | variable "target_db_port" { 114 | description = "The port the Application Server will access the database on" 115 | default = 5432 116 | } 117 | 118 | variable "target_engine" { 119 | default = "postgres" 120 | description = "Engine type, example values mysql, postgres" 121 | } 122 | 123 | variable "target_engine_version" { 124 | description = "Engine version" 125 | default = "9.3.14" 126 | } 127 | 128 | variable "target_instance_class" { 129 | default = "db.t2.micro" 130 | description = "Instance class" 131 | } 132 | 133 | variable "target_maintenance_window" { 134 | default = "Mon:00:00-Mon:03:00" 135 | description = "RDS maintenance window" 136 | } 137 | 138 | variable "target_password" { 139 | description = "Password of the target database" 140 | } 141 | 142 | variable "target_rds_is_multi_az" { 143 | description = "Create backup database in separate availability zone" 144 | default = "false" 145 | } 146 | 147 | variable "target_storage" { 148 | default = "10" 149 | description = "Storage size in GB" 150 | } 151 | 152 | variable "target_storage_encrypted" { 153 | description = "Encrypt storage or leave unencrypted" 154 | default = false 155 | } 156 | 157 | variable "target_username" { 158 | description = "Username to access the target database" 159 | } 160 | 161 | #-------------------------------------------------------------- 162 | # DMS source config 163 | #-------------------------------------------------------------- 164 | 165 | variable "source_app_password" { 166 | description = "Password for the endpoint to access the source database" 167 | } 168 | 169 | variable "source_app_username" { 170 | description = "Username for the endpoint to access the source database" 171 | } 172 | 173 | variable "source_backup_retention_period" { 174 | # Days 175 | default = "1" 176 | description = "Retention of RDS backups" 177 | } 178 | 179 | variable "source_backup_window" { 180 | # 12:00AM-03:00AM AEST 181 | default = "14:00-17:00" 182 | description = "RDS backup window" 183 | } 184 | 185 | variable "source_db_name" { 186 | description = "Password of the target database" 187 | default = "ORACLE" 188 | } 189 | 190 | variable "source_db_port" { 191 | description = "The port the Application Server will access the database on" 192 | default = 1521 193 | } 194 | 195 | variable "source_engine" { 196 | default = "oracle-se2" 197 | description = "Engine type, example values mysql, postgres" 198 | } 199 | 200 | variable "source_engine_name" { 201 | default = "oracle" 202 | description = "Engine name for DMS" 203 | } 204 | 205 | variable "source_engine_version" { 206 | description = "Engine version" 207 | default = "12.1.0.2.v8" 208 | } 209 | 210 | variable "source_instance_class" { 211 | default = "db.t2.micro" 212 | description = "Instance class" 213 | } 214 | 215 | variable "source_maintenance_window" { 216 | default = "Mon:00:00-Mon:03:00" 217 | description = "RDS maintenance window" 218 | } 219 | 220 | variable "source_password" { 221 | description = "Password of the source database" 222 | } 223 | 224 | variable "source_rds_is_multi_az" { 225 | description = "Create backup database in separate availability zone" 226 | default = "false" 227 | } 228 | 229 | variable "source_snapshot" { 230 | description = "Snapshot ID" 231 | } 232 | 233 | variable "source_storage" { 234 | default = "10" 235 | description = "Storage size in GB" 236 | } 237 | 238 | variable "source_storage_encrypted" { 239 | description = "Encrypt storage or leave unencrypted" 240 | default = false 241 | } 242 | 243 | variable "source_username" { 244 | description = "Username to access the source database" 245 | } 246 | 247 | #-------------------------------------------------------------- 248 | # DMS Replication Instance 249 | #-------------------------------------------------------------- 250 | 251 | variable "replication_instance_maintenance_window" { 252 | description = "Maintenance window for the replication instance" 253 | default = "sun:10:30-sun:14:30" 254 | } 255 | 256 | variable "replication_instance_storage" { 257 | description = "Size of the replication instance in GB" 258 | default = "10" 259 | } 260 | 261 | variable "replication_instance_version" { 262 | description = "Engine version of the replication instance" 263 | default = "1.9.0" 264 | } 265 | 266 | variable "replication_instance_class" { 267 | description = "Instance class of replication instance" 268 | default = "dms.t2.micro" 269 | } 270 | 271 | #-------------------------------------------------------------- 272 | # Network 273 | #-------------------------------------------------------------- 274 | 275 | variable "database_subnet_cidr" { 276 | default = ["10.0.0.0/26", "10.0.0.64/26", "10.0.0.128/26"] 277 | description = "List of subnets to be used for databases" 278 | } 279 | 280 | variable "vpc_cidr" { 281 | description = "CIDR for the whole VPC" 282 | default = "10.0.0.0/24" 283 | } 284 | --------------------------------------------------------------------------------