Skip to content

Commit 6d27de3

Browse files
authored
Multiple AWS SM Secrets as inputs and RDS Fixes (#52)
* Initial commit * Adding option for DB Identifier * Typo * Making proxy policy more flexible * Typo 2 * Ignoring policy changes * Trying a more direct approach for db_proxy_target * lowering-var * Testing with lifecycle block * Debugging proxy recreation * Debugging proxy recreation 2 * v3
1 parent 5a38f8a commit 6d27de3

File tree

11 files changed

+80
-20
lines changed

11 files changed

+80
-20
lines changed

README.md

+21-1
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ The following inputs can be used as `step.with` keys
128128
#### **Secrets and Environment Variables Inputs**
129129
| Name | Type | Description - Check note about [**environment variables**](#environment-variables). |
130130
|------------------|---------|------------------------------------|
131-
| `env_aws_secret` | String | Secret name to pull environment variables from AWS Secret Manager. |
131+
| `env_aws_secret` | String | Secret name to pull environment variables from AWS Secret Manager. Accepts comma separated list of secrets. |
132132
| `env_repo` | String | `.env` file containing environment variables to be used with the app. Name defaults to `repo_env`. |
133133
| `env_ghs` | String | `.env` file to be used with the app. This is the name of the [Github secret](https://docs.github.com/es/actions/security-guides/encrypted-secrets). |
134134
| `env_ghv` | String | `.env` file to be used with the app. This is the name of the [Github variables](https://docs.github.com/en/actions/learn-github-actions/variables). |
@@ -225,6 +225,7 @@ The following inputs can be used as `step.with` keys
225225
|------------------|---------|------------------------------------|
226226
| `aws_rds_db_enable`| Boolean | Set to `true` to enable an RDS DB. |
227227
| `aws_rds_db_proxy`| Boolean | Set to `true` to add a RDS DB Proxy. |
228+
| `aws_rds_db_identifier`| String | Database identifier that will appear in the AWS Console. Defaults to `aws_resource_identifier` if none set. |
228229
| `aws_rds_db_name`| String | The name of the database to create when the DB instance is created. If this parameter is not specified, no database is created in the DB instance. |
229230
| `aws_rds_db_user`| String | Username for the db. Defaults to `dbuser`. |
230231
| `aws_rds_db_engine`| String | Which Database engine to use. Defaults to `postgres`. |
@@ -509,6 +510,25 @@ The Aurora available environment variables are:
509510
| `AURORA_CLUSTER_ENGINE_VERSION_ACTUAL` | The running version of the cluster database |
510511
| `AURORA_CLUSTER_HOSTED_ZONE_ID`| The Route53 Hosted Zone ID of the endpoint |
511512

513+
### Stored secret in AWS Secrets Manager
514+
In order to be flexible, the following variables will be used to store DB related info in AWS Secretes Manager
515+
516+
`username`
517+
`password`
518+
`host`
519+
`port`
520+
`database`
521+
`engine`
522+
`engine_version`
523+
`DB_USER`
524+
`DB_USERNAME`
525+
`DB_PASSWORD`
526+
`DB_HOST`
527+
`DB_PORT`
528+
`DB_NAME`
529+
`DB_ENGINE`
530+
`DB_ENGINE_VERSION`
531+
512532
### AWS Root Certs
513533
The AWS root certificate is downloaded and accessible via the `rds-combined-ca-bundle.pem` file in root of your app repo/directory.
514534

action.yaml

+5-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ inputs:
119119

120120
# ENV files
121121
env_aws_secret:
122-
description: 'Secret name to pull env variables from AWS Secret Manager'
122+
description: 'Secret name to pull env variables from AWS Secret Manager, could be a comma separated list, read in order. Expected JSON content.'
123123
required: false
124124
env_repo:
125125
description: 'File containing environment variables to be used with the app'
@@ -311,6 +311,9 @@ inputs:
311311
aws_rds_db_proxy:
312312
description: 'Set to true to add a RDS DB Proxy'
313313
required: false
314+
aws_rds_db_identifier:
315+
description: 'Database identifier that will appear in the AWS Console. Defaults to aws_resource_identifier if none set.'
316+
required: false
314317
aws_rds_db_name:
315318
description: 'The name of the database to create when the DB instance is created.'
316319
required: false
@@ -902,6 +905,7 @@ runs:
902905
# AWS RDS
903906
AWS_RDS_DB_ENABLE: ${{ inputs.aws_rds_db_enable }}
904907
AWS_RDS_DB_PROXY: ${{ inputs.aws_rds_db_proxy }}
908+
AWS_RDS_DB_IDENTIFIER: ${{ inputs.aws_rds_db_identifier }}
905909
AWS_RDS_DB_NAME: ${{ inputs.aws_rds_db_name }}
906910
AWS_RDS_DB_USER: ${{ inputs.aws_rds_db_user }}
907911
AWS_RDS_DB_ENGINE: ${{ inputs.aws_rds_db_engine }}

operations/_scripts/generate/generate_vars_terraform.sh

+2
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ fi
162162
if [[ $(alpha_only "$AWS_RDS_DB_ENABLE") == true ]]; then
163163
aws_rds_db_enable=$(generate_var aws_rds_db_enable $AWS_RDS_DB_ENABLE)
164164
aws_rds_db_proxy=$(generate_var aws_rds_db_proxy $AWS_RDS_DB_PROXY)
165+
aws_rds_db_identifier=$(generate_var aws_rds_db_identifier $AWS_RDS_DB_IDENTIFIER)
165166
aws_rds_db_name=$(generate_var aws_rds_db_name $AWS_RDS_DB_NAME)
166167
aws_rds_db_user=$(generate_var aws_rds_db_user $AWS_RDS_DB_USER)
167168
aws_rds_db_engine=$(generate_var aws_rds_db_engine $AWS_RDS_DB_ENGINE)
@@ -420,6 +421,7 @@ $aws_efs_additional_tags
420421
#-- RDS --#
421422
$aws_rds_db_enable
422423
$aws_rds_db_proxy
424+
$aws_rds_db_identifier
423425
$aws_rds_db_name
424426
$aws_rds_db_user
425427
$aws_rds_db_engine

operations/deployment/terraform/aws/aws_variables.tf

+6
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,12 @@ variable "aws_rds_db_proxy" {
396396
default = false
397397
}
398398

399+
variable "aws_rds_db_identifier" {
400+
type = string
401+
description = "Database identifier that will appear in the AWS Console. Defaults to aws_resource_identifier if none set."
402+
default = ""
403+
}
404+
399405
variable "aws_rds_db_name" {
400406
type = string
401407
description = "The name of the database to create when the DB instance is created. If this parameter is not specified, no database is created in the DB instance."

operations/deployment/terraform/aws/bitovi_main.tf

+1
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ module "rds" {
134134
# RDS
135135
aws_rds_db_name = var.aws_rds_db_name
136136
aws_rds_db_user = var.aws_rds_db_user
137+
aws_rds_db_identifier = var.aws_rds_db_identifier != "" ? var.aws_rds_db_identifier : lower(var.aws_resource_identifier)
137138
aws_rds_db_engine = var.aws_rds_db_engine
138139
aws_rds_db_engine_version = var.aws_rds_db_engine_version
139140
aws_rds_db_security_group_name = var.aws_rds_db_security_group_name

operations/deployment/terraform/ecr/bitovi_main.tf

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ locals {
4242
}
4343
default_tags = merge(local.aws_tags, jsondecode(var.aws_additional_tags))
4444
# Module tagging
45-
ecr_tags = merge(local.default_tags,jsondecode(var.aws_ecr_additional_tags))
45+
ecr_tags = merge(local.default_tags,jsondecode(var.aws_ecr_additional_tags))
4646
}
4747

4848
output "ecr_repository_arn" {

operations/deployment/terraform/modules/aws/aurora/aws_aurora.tf

+10-4
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,19 @@ resource "aws_secretsmanager_secret_version" "database_credentials_sm_secret_ver
136136
secret_string = jsonencode({
137137
username = sensitive(module.aurora_cluster.cluster_master_username)
138138
password = sensitive(module.aurora_cluster.cluster_master_password)
139-
DB_ENGINE = sensitive(local.dba_engine)
140-
DB_ENGINE_VERSION = sensitive(module.aurora_cluster.cluster_engine_version_actual)
139+
host = sensitive(module.aurora_cluster.cluster_endpoint)
140+
port = sensitive(module.aurora_cluster.cluster_port)
141+
database = sensitive(module.aurora_cluster.cluster_database_name == null ? "" : module.aurora_cluster.cluster_database_name)
142+
engine = sensitive(local.dba_engine)
143+
engine_version = sensitive(module.aurora_cluster.cluster_engine_version_actual)
141144
DB_USER = sensitive(module.aurora_cluster.cluster_master_username)
145+
DB_USERNAME = sensitive(module.aurora_cluster.cluster_master_username)
142146
DB_PASSWORD = sensitive(module.aurora_cluster.cluster_master_password)
143-
DB_NAME = sensitive(module.aurora_cluster.cluster_database_name == null ? "" : module.aurora_cluster.cluster_database_name)
144-
DB_PORT = sensitive(module.aurora_cluster.cluster_port)
145147
DB_HOST = sensitive(module.aurora_cluster.cluster_endpoint)
148+
DB_PORT = sensitive(module.aurora_cluster.cluster_port)
149+
DB_NAME = sensitive(module.aurora_cluster.cluster_database_name == null ? "" : module.aurora_cluster.cluster_database_name)
150+
DB_ENGINE = sensitive(local.dba_engine)
151+
DB_ENGINE_VERSION = sensitive(module.aurora_cluster.cluster_engine_version_actual)
146152
})
147153
}
148154

operations/deployment/terraform/modules/aws/db_proxy/aws_db_proxy.tf

+12-3
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,10 @@ resource "aws_db_proxy_target" "db_instance" {
8181
db_instance_identifier = data.aws_db_instance.db[0].id
8282
db_proxy_name = aws_db_proxy.rds_proxy[0].name
8383
target_group_name = aws_db_proxy_default_target_group.default.name
84-
84+
lifecycle {
85+
ignore_changes = [ db_instance_identifier ]
86+
replace_triggered_by = [ data.aws_db_instance.db ]
87+
}
8588
depends_on = [ aws_db_proxy.rds_proxy ]
8689
}
8790

@@ -90,7 +93,10 @@ resource "aws_db_proxy_target" "db_cluster" {
9093
db_cluster_identifier = data.aws_rds_cluster.db[0].id
9194
db_proxy_name = aws_db_proxy.rds_proxy[0].name
9295
target_group_name = aws_db_proxy_default_target_group.default.name
93-
96+
lifecycle {
97+
ignore_changes = [ db_instance_identifier ]
98+
replace_triggered_by = [ data.aws_rds_cluster.db ]
99+
}
94100
depends_on = [ aws_db_proxy.rds_proxy ]
95101
}
96102

@@ -199,7 +205,7 @@ resource "aws_iam_policy" "rds_proxy_iam" {
199205
"secretsmanager:ListSecretVersionIds"
200206
],
201207
"Resource": [
202-
"${data.aws_secretsmanager_secret_version.database_credentials.arn}"
208+
"arn:aws:secretsmanager:${data.aws_region.current.name}.${data.aws_caller_identity.current.account_id}:secret:${var.aws_db_proxy_secret_name}*"
203209
]
204210
},
205211
{
@@ -215,6 +221,9 @@ resource "aws_iam_policy" "rds_proxy_iam" {
215221
]
216222
}
217223
POLICY
224+
lifecycle {
225+
ignore_changes = [ policy ]
226+
}
218227
}
219228

220229
resource "aws_iam_role_policy_attachment" "rds_policy" {

operations/deployment/terraform/modules/aws/rds/aws_rds.tf

+11-5
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ resource "aws_db_subnet_group" "selected" {
5353
}
5454

5555
resource "aws_db_instance" "default" {
56-
identifier = var.aws_rds_db_name != null ? var.aws_rds_db_name : var.aws_resource_identifier
56+
identifier = var.aws_rds_db_identifier
5757
engine = var.aws_rds_db_engine
5858
engine_version = var.aws_rds_db_engine_version
5959
db_subnet_group_name = aws_db_subnet_group.selected.name
@@ -98,13 +98,19 @@ resource "aws_secretsmanager_secret_version" "database_credentials_sm_secret_ver
9898
secret_string = jsonencode({
9999
username = sensitive(aws_db_instance.default.username)
100100
password = sensitive(aws_db_instance.default.password)
101-
DB_ENGINE = sensitive(aws_db_instance.default.engine)
102-
DB_ENGINE_VERSION = sensitive(aws_db_instance.default.engine_version)
101+
host = sensitive(aws_db_instance.default.address)
102+
port = sensitive(aws_db_instance.default.port)
103+
database = sensitive(aws_db_instance.default.db_name)
104+
engine = sensitive(aws_db_instance.default.engine)
105+
engine_version = sensitive(aws_db_instance.default.engine_version)
103106
DB_USER = sensitive(aws_db_instance.default.username)
107+
DB_USERNAME = sensitive(aws_db_instance.default.username)
104108
DB_PASSWORD = sensitive(aws_db_instance.default.password)
105-
DB_NAME = sensitive(aws_db_instance.default.db_name)
106-
DB_PORT = sensitive(aws_db_instance.default.port)
107109
DB_HOST = sensitive(aws_db_instance.default.address)
110+
DB_PORT = sensitive(aws_db_instance.default.port)
111+
DB_NAME = sensitive(aws_db_instance.default.db_name)
112+
DB_ENGINE = sensitive(aws_db_instance.default.engine)
113+
DB_ENGINE_VERSION = sensitive(aws_db_instance.default.engine_version)
108114
})
109115
}
110116

operations/deployment/terraform/modules/aws/rds/aws_rds_vars.tf

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
variable "aws_rds_db_identifier" {}
12
variable "aws_rds_db_name" {}
23
variable "aws_rds_db_user" {}
34
variable "aws_rds_db_engine" {}
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
# This file will create a key=value file with an AWS Secret stored in AWS Secret Manager
22
# With a JSON style of "{"key1":"value1","key2":"value2"}"
3-
data "aws_secretsmanager_secret_version" "env_secret" {
4-
secret_id = var.env_aws_secret
3+
data "aws_secretsmanager_secret_version" "secret_list" {
4+
count = length(local.env_aws_secret)
5+
secret_id = local.env_aws_secret[count.index]
56
}
67

78
resource "local_file" "tf-secretdotenv" {
89
filename = format("%s/%s", abspath(path.root), "aws.env")
9-
content = "${local.s3_secret_string}\n"
10+
content = join("\n",local.s3_secret_string)
1011
}
1112

1213
locals {
13-
s3_secret_raw = nonsensitive(jsondecode(data.aws_secretsmanager_secret_version.env_secret.secret_string))
14-
s3_secret_string = join("\n", [for k, v in local.s3_secret_raw : "${k}=\"${v}\""])
14+
env_aws_secret = [for n in split(",", var.env_aws_secret) : (n)]
15+
all_secret_contents = {
16+
for secret_name, secret_data in data.aws_secretsmanager_secret_version.secret_list : secret_name => jsondecode(secret_data.secret_string)
17+
}
18+
merged_secrets = merge(values(local.all_secret_contents)...)
19+
s3_secret_string = [for key, value in local.merged_secrets : "${key}=${value}"]
1520
}

0 commit comments

Comments
 (0)