Skip to content

Commit

Permalink
Add a property to enable the disk encryption for postgres databases o…
Browse files Browse the repository at this point in the history
…n AWS

We added the possibility to use encrypted disks for AWS Postgres Databases. The new property can be used during the inital deployment.
Changes for already existing databases are not supported. Terraform would replace them with complete data lose.

Implementation steps:

    - Add a KMS Key + Alias and connect them to the database
    - Add a cli property to use the encrypted disk for AWS
    - Deploy KMS Key + Alias only if the disk encryption is enabled
    - Update the documentation
  • Loading branch information
max-soe committed Feb 10, 2023
1 parent 6eba99e commit 6cc56db
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 1 deletion.
7 changes: 7 additions & 0 deletions commands/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,13 @@ var deployFlags = []cli.Flag{
Value: "small",
Destination: &initialDeployArgs.DBSize,
},
cli.BoolFlag{
Name: "rds-disk-encryption",
Usage: "(optional) Use a aws rds database with an encrypted disk. The KMS key is created automatically.",
EnvVar: "RDSDiskEncryption",
Hidden: true,
Destination: &initialDeployArgs.RDSDiskEncryption,
},
cli.BoolTFlag{
Name: "spot",
Usage: "(optional) Use spot instances for workers. Can be true/false (default: true)",
Expand Down
4 changes: 4 additions & 0 deletions commands/deploy/deploy_args.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ type Args struct {
DBSize string
// DBSizeIsSet is true if the user has manually specified the db-size (ie, it's not the default)
DBSizeIsSet bool
RDSDiskEncryption bool
RDSDiskEncryptionIsSet bool
EnableGlobalResources bool
EnableGlobalResourcesIsSet bool
EnablePipelineInstances bool
Expand Down Expand Up @@ -136,6 +138,8 @@ func (a *Args) MarkSetFlags(c FlagSetChecker) error {
a.SelfUpdateIsSet = true
case "db-size":
a.DBSizeIsSet = true
case "rds-disk-encryption":
a.RDSDiskEncryptionIsSet = true
case "spot", "preemptible":
a.SpotIsSet = true
case "allow-ips":
Expand Down
8 changes: 8 additions & 0 deletions concourse/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ func assertImmutableFieldsNotChanging(deployArgs *deploy.Args, conf config.Confi
return fmt.Errorf("Existing deployment uses zone %s and cannot change to zone %s", conf.GetAvailabilityZone(), deployArgs.Zone)
}

if deployArgs.RDSDiskEncryption != conf.GetRDSDiskEncryption() {
return fmt.Errorf("The disk encryption cannot be changed after inital deploy!")
}

return nil
}

Expand Down Expand Up @@ -109,6 +113,7 @@ func populateConfigWithDefaults(conf config.Config, provider iaas.Provider, pass
conf.RDSInstanceClass = provider.DBType("small")
conf.RDSPassword = passwordGenerator(defaultPasswordLength)
conf.RDSUsername = "admin" + passwordGenerator(7)
conf.RDSDiskEncryption = false
conf.VMProvisioningType = config.SPOT
conf.WorkerType = "m4"
conf = populateConfigWithDefaultCIDRs(conf, provider)
Expand Down Expand Up @@ -162,6 +167,9 @@ func applyArgumentsToConfig(conf config.Config, deployArgs *deploy.Args, provide
if deployArgs.DBSizeIsSet {
conf.RDSInstanceClass = provider.DBType(deployArgs.DBSize)
}
if deployArgs.RDSDiskEncryptionIsSet {
conf.RDSDiskEncryption = deployArgs.RDSDiskEncryption
}
if deployArgs.BitbucketAuthIsSet {
conf.BitbucketClientID = deployArgs.BitbucketAuthClientID
conf.BitbucketClientSecret = deployArgs.BitbucketAuthClientSecret
Expand Down
1 change: 1 addition & 0 deletions concourse/tf_input_vars_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ func (f *AWSInputVarsFactory) NewInputVars(c config.ConfigView) terraform.InputV
RDSInstanceClass: c.GetRDSInstanceClass(),
RDSPassword: c.GetRDSPassword(),
RDSUsername: c.GetRDSUsername(),
RDSDiskEncryption: c.GetRDSDiskEncryption(),
RDS1CIDR: c.GetRDS1CIDR(),
RDS2CIDR: c.GetRDS2CIDR(),
Region: c.GetRegion(),
Expand Down
6 changes: 6 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ type Config struct {
RDSInstanceClass string `json:"rds_instance_class"`
RDSPassword string `json:"rds_password"`
RDSUsername string `json:"rds_username"`
RDSDiskEncryption bool `json:"rds_disk_encryption"`
Region string `json:"region"`
SourceAccessIP string `json:"source_access_ip"`
//Spot is deprecated, exists only as we need to migrate old configs to VMProvisioningType
Expand Down Expand Up @@ -152,6 +153,7 @@ type ConfigView interface {
GetRDSInstanceClass() string
GetRDSPassword() string
GetRDSUsername() string
GetRDSDiskEncryption() bool
GetRegion() string
GetSourceAccessIP() string
GetTags() []string
Expand Down Expand Up @@ -419,6 +421,10 @@ func (c Config) GetRDSUsername() string {
return c.RDSUsername
}

func (c Config) GetRDSDiskEncryption() bool {
return c.RDSDiskEncryption
}

func (c Config) GetRegion() string {
return c.Region
}
Expand Down
9 changes: 9 additions & 0 deletions docs/deploy.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,15 @@ control-tower deploy \
> This flag overwrites the allowed IPs on every deploy. This means deploying with `allow-ips` then deploying again without it will reset the allow list to `0.0.0.0/0`. The self-update pipeline will maintain the `allow-ips` of the most recent deploy.
## RDS Disk encryption

On GCP the database disk encryption is enabled by default. On AWS we added the option to enable the disk encryption too. By default it's disabled.
> Note that you can only change this value during the inital deploy. It's not possible to change this for a running instance.
| **Flag** | **Description** | **Environment Variable** |
| :-----------------------| :----------------------------------------------------------------------------------- | :----------------------- |
| `--rds-disk-encryption` | Optional configuration to use an encrypted rds disk for AWS. Not enabled by default! | `RDSDiskEncryption` |

## BitBucket Auth

| **Flag** | **Description** | **Environment Variable** |
Expand Down
23 changes: 22 additions & 1 deletion resource/assets/aws/infrastructure.tf
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ variable "rds1_cidr" {
default = "{{ .RDS1CIDR }}"
}

variable "rds_disk_encryption" {
type = string
default = "{{ .RDSDiskEncryption }}"
}

variable "rds2_cidr" {
type = string
default = "{{ .RDS2CIDR }}"
Expand Down Expand Up @@ -221,7 +226,8 @@ resource "aws_iam_user_policy" "self_update" {
"iam:PutUserPolicy",
"rds:*",
"route53:*",
"s3:*"
"s3:*",
"kms:*"
],
"Resource": "*",
"Condition": {
Expand Down Expand Up @@ -653,6 +659,19 @@ resource "aws_db_subnet_group" "default" {
}
}

resource "aws_kms_key" "default_key" {
count = var.rds_disk_encryption == "true" ? 1 : 0
description = "${var.rds_default_database_name}-key"
deletion_window_in_days = 10
enable_key_rotation = true
}

resource "aws_kms_alias" "default_key_alias" {
count = var.rds_disk_encryption == "true" ? 1 : 0
name = "alias/${var.rds_default_database_name}-key"
target_key_id = aws_kms_key.default_key[0].key_id
}

resource "aws_db_instance" "default" {
allocated_storage = 10
apply_immediately = true
Expand All @@ -671,6 +690,8 @@ resource "aws_db_instance" "default" {
db_subnet_group_name = aws_db_subnet_group.default.name
skip_final_snapshot = true
storage_type = "gp2"
storage_encrypted = var.rds_disk_encryption
kms_key_id = var.rds_disk_encryption == "true" ? aws_kms_key.default_key[0].arn : ""
lifecycle {
ignore_changes = [allocated_storage]
}
Expand Down
1 change: 1 addition & 0 deletions terraform/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type AWSInputVars struct {
RDSInstanceClass string
RDSPassword string
RDSUsername string
RDSDiskEncryption bool
RDS1CIDR string
RDS2CIDR string
Region string
Expand Down

0 comments on commit 6cc56db

Please sign in to comment.