Skip to content

Commit

Permalink
Deal with references to Secrets Manager secrets (#2)
Browse files Browse the repository at this point in the history
Correctly deal with referencing SecretsManager secrets
  • Loading branch information
razorsedge committed Sep 19, 2020
1 parent bbf908a commit f3ab47c
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 6 deletions.
44 changes: 44 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@ locals {
// Master user password
master_password_in_ssm_param = var.db_master_password_ssm_param != null ? true : false
master_password_ssm_param_ecnrypted = var.db_master_password_ssm_param_kms_key != null ? true : false
# Replace null with empty string so that the following regexall will work.
db_master_password_ssm_param = var.db_master_password_ssm_param == null ? "" : var.db_master_password_ssm_param
master_password_in_secretsmanager = length(regexall("/aws/reference/secretsmanager/", local.db_master_password_ssm_param)) > 0

// Provisioned user password
user_password_in_ssm_param = var.db_user_password_ssm_param != null ? true : false
user_password_ssm_param_ecnrypted = var.db_user_password_ssm_param_kms_key != null ? true : false
# Replace null with empty string so that the following regexall will work.
db_user_password_ssm_param = var.db_user_password_ssm_param == null ? "" : var.db_user_password_ssm_param
user_password_in_secretsmanager = length(regexall("/aws/reference/secretsmanager/", local.db_user_password_ssm_param)) > 0
}

#############################################################
Expand All @@ -30,6 +36,12 @@ data "aws_ssm_parameter" "master_password" {
name = var.db_master_password_ssm_param
}

data "aws_secretsmanager_secret" "master_password" {
count = var.enabled && local.master_password_in_secretsmanager ? 1 : 0

name = trimprefix(var.db_master_password_ssm_param, "/aws/reference/secretsmanager/")
}

data "aws_kms_key" "master_password" {
count = var.enabled && local.master_password_in_ssm_param && local.master_password_ssm_param_ecnrypted ? 1 : 0

Expand All @@ -42,6 +54,12 @@ data "aws_ssm_parameter" "user_password" {
name = var.db_user_password_ssm_param
}

data "aws_secretsmanager_secret" "user_password" {
count = var.enabled && local.user_password_in_secretsmanager ? 1 : 0

name = trimprefix(var.db_user_password_ssm_param, "/aws/reference/secretsmanager/")
}

data "aws_kms_key" "user_password" {
count = var.enabled && local.user_password_in_ssm_param && local.user_password_ssm_param_ecnrypted ? 1 : 0

Expand Down Expand Up @@ -253,6 +271,18 @@ data "aws_iam_policy_document" "master_password_ssm_permissions" {
}
}

data "aws_iam_policy_document" "master_password_secretsmanager_permissions" {
count = var.enabled && local.master_password_in_secretsmanager ? 1 : 0

statement {
effect = "Allow"
actions = [
"secretsmanager:GetSecretValue",
]
resources = [join("", data.aws_secretsmanager_secret.master_password.*.arn)]
}
}

data "aws_iam_policy_document" "master_password_kms_permissions" {
count = var.enabled && local.master_password_in_ssm_param && local.master_password_ssm_param_ecnrypted ? 1 : 0

Expand All @@ -277,6 +307,18 @@ data "aws_iam_policy_document" "user_password_ssm_permissions" {
}
}

data "aws_iam_policy_document" "user_password_secretsmanager_permissions" {
count = var.enabled && local.user_password_in_secretsmanager ? 1 : 0

statement {
effect = "Allow"
actions = [
"secretsmanager:GetSecretValue",
]
resources = [join("", data.aws_secretsmanager_secret.user_password.*.arn)]
}
}

data "aws_iam_policy_document" "user_password_kms_permissions" {
count = var.enabled && local.user_password_in_ssm_param && local.user_password_ssm_param_ecnrypted ? 1 : 0

Expand All @@ -297,8 +339,10 @@ module "aggregated_policy" {
join("", data.aws_iam_policy_document.lambda_kms_permissions.*.json),
join("", data.aws_iam_policy_document.master_password_ssm_permissions.*.json),
join("", data.aws_iam_policy_document.master_password_kms_permissions.*.json),
join("", data.aws_iam_policy_document.master_password_secretsmanager_permissions.*.json),
join("", data.aws_iam_policy_document.user_password_ssm_permissions.*.json),
join("", data.aws_iam_policy_document.user_password_kms_permissions.*.json),
join("", data.aws_iam_policy_document.user_password_secretsmanager_permissions.*.json),
])
}

Expand Down
20 changes: 14 additions & 6 deletions source-code/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
just need to pass db instance identifier.
Master user will be granted all permissions to the created database.
If user or database already exist - they won't be created.
If user or database already exists - they won't be created.
Author: aleksandr.fofanov@quantumsoft.ru
Expand All @@ -20,6 +20,7 @@
import os
from dataclasses import dataclass
from typing import List
import json

import psycopg2
import pymysql
Expand Down Expand Up @@ -55,7 +56,14 @@ def get_ssm_parameter_value(self, name: str) -> str:
Name=name,
WithDecryption=True
)
return response.get('Parameter').get('Value')
returnval = response.get('Parameter').get('Value')
if (name.startswith('/aws/reference/secretsmanager')):
try:
val = json.loads(returnval)
returnval = val['password']
except ValueError as e:
pass
return returnval

@staticmethod
def _get_pg_usernames(cursor) -> List[str]:
Expand Down Expand Up @@ -95,7 +103,7 @@ def provision_postgres_db(self, info: DBInfo):
if info.provision_user:
usernames = self._get_pg_usernames(cursor)
if info.provision_user in usernames:
self.logger.warning("User '{}' won't be created because it's already exist".format(info.provision_user))
self.logger.warning("User '{}' won't be created because it already exists".format(info.provision_user))
else:
self.logger.info("Creating user '{}'".format(info.provision_user))

Expand All @@ -110,7 +118,7 @@ def provision_postgres_db(self, info: DBInfo):

if info.provision_db_name in databases_names:
self.logger.warning(
"Database '{}' won't be created because it's already exist".format(info.provision_db_name))
"Database '{}' won't be created because it already exists".format(info.provision_db_name))
else:
self.logger.info("Creating database '{}'".format(info.provision_db_name))

Expand Down Expand Up @@ -172,7 +180,7 @@ def provision_mysql_db(self, info: DBInfo):
if info.provision_user:
usernames = self._get_mysql_usernames(cursor)
if info.provision_user in usernames:
self.logger.warning("User '{}' won't be created because it's already exist".format(info.provision_user))
self.logger.warning("User '{}' won't be created because it already exists".format(info.provision_user))
else:
self.logger.info("Creating user '{}'".format(info.provision_user))

Expand All @@ -192,7 +200,7 @@ def provision_mysql_db(self, info: DBInfo):
databases_names = self._get_mysql_databases_names(cursor)

if info.provision_db_name in databases_names:
self.logger.warning("Database '{}' won't be created because it's already exist".format(
self.logger.warning("Database '{}' won't be created because it already exists".format(
info.provision_db_name
))
else:
Expand Down

0 comments on commit f3ab47c

Please sign in to comment.