-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FR: secrets import to services from AWS Secrets Manager (#142)
- Loading branch information
1 parent
41aa31c
commit 4db8a88
Showing
11 changed files
with
279 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
|
||
|
||
secrets | ||
======= | ||
|
||
.. seealso:: | ||
|
||
`docker-compose secrets reference`_ | ||
|
||
You might have secrets in AWS Secrets Manager that you created outside of this application stack and your services | ||
need access to it. | ||
|
||
By defining secrets in docker-compose, you can do all of that work rather easily. | ||
To help make it as easy in AWS, simply set `external=True` and a few other settings to indicate how to get the secret. | ||
|
||
|
||
.. code-block:: yaml | ||
version: "3.8" | ||
services: | ||
servicename: | ||
image: abcd | ||
secrets: | ||
- abcd | ||
secrets: | ||
mysecret: | ||
external: true | ||
x-secret: | ||
Name: /name/in/aws | ||
LinkTo: | ||
- EcsExecutionRole | ||
- EcsTaskRole | ||
x-secret | ||
-------- | ||
|
||
Name | ||
^^^^ | ||
|
||
The name (also known as path) to the secret in AWS Secrets Manager. | ||
|
||
|
||
LinksTo | ||
^^^^^^^ | ||
|
||
List to determine whether the TaskRole or ExecutionRole (or both) should have access to the Secret. | ||
If set as TaskRole, then the secret **value will not be exposed in env vars** and only the secret name will be set. | ||
|
||
|
||
.. _docker-compose secrets reference: https://docs.docker.com/compose/compose-file/#secrets |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# -*- coding: utf-8 -*- | ||
# ECS ComposeX <https://github.com/lambda-my-aws/ecs_composex> | ||
# Copyright (C) 2020 John Mille <[email protected]> | ||
# # | ||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation, either version 3 of the License, or | ||
# (at your option) any later version. | ||
# # | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# # | ||
# You should have received a copy of the GNU General Public License | ||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# -*- coding: utf-8 -*- | ||
# ECS ComposeX <https://github.com/lambda-my-aws/ecs_composex> | ||
# Copyright (C) 2020 John Mille <[email protected]> | ||
# # | ||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation, either version 3 of the License, or | ||
# (at your option) any later version. | ||
# # | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# # | ||
# You should have received a copy of the GNU General Public License | ||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
# -*- coding: utf-8 -*- | ||
# ECS ComposeX <https://github.com/lambda-my-aws/ecs_composex> | ||
# Copyright (C) 2020 John Mille <[email protected]> | ||
# # | ||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation, either version 3 of the License, or | ||
# (at your option) any later version. | ||
# # | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# # | ||
# You should have received a copy of the GNU General Public License | ||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
""" | ||
Module to parse secrets from the compose content file. | ||
""" | ||
|
||
from troposphere import Sub, AWS_PARTITION, AWS_REGION, AWS_ACCOUNT_ID | ||
from troposphere.ecs import Secret as EcsSecret | ||
from troposphere.iam import Policy | ||
|
||
from ecs_composex.common import LOG, keyisset | ||
from ecs_composex.ecs.ecs_params import TASK_ROLE_T, EXEC_ROLE_T | ||
from ecs_composex.ecs.ecs_iam import define_service_containers | ||
from ecs_composex.ecs.ecs_container_config import extend_container_secrets | ||
|
||
|
||
RES_KEY = "secrets" | ||
XRES_KEY = "x-secrets" | ||
|
||
|
||
class ComposeSecret(object): | ||
""" | ||
Class to represent a Compose secret. | ||
""" | ||
|
||
def __init__(self, name, definition): | ||
if not keyisset("Name", definition[XRES_KEY]): | ||
raise KeyError(f"Missing Name in the {XRES_KEY} defintion") | ||
self.name = name | ||
aws_name = definition[XRES_KEY]["Name"] | ||
if aws_name.startswith("arn:"): | ||
self.aws_name = definition[XRES_KEY]["Name"] | ||
else: | ||
self.aws_name = Sub( | ||
f"arn:${{{AWS_PARTITION}}}:secretsmanager:${{{AWS_REGION}}}:${{{AWS_ACCOUNT_ID}}}:secret:${aws_name}" | ||
) | ||
self.links = ( | ||
definition[XRES_KEY]["LinksTo"] | ||
if keyisset("LinksTo", definition[XRES_KEY]) | ||
else [EXEC_ROLE_T] | ||
) | ||
self.ecs_secret = EcsSecret(Name=self.name, ValueFrom=self.aws_name) | ||
|
||
self.validate_links() | ||
|
||
def validate_links(self): | ||
for link in self.links: | ||
if not link in [EXEC_ROLE_T, TASK_ROLE_T]: | ||
raise ValueError( | ||
"Links in LinksTo can only be one of", | ||
EXEC_ROLE_T, | ||
TASK_ROLE_T, | ||
"Got", | ||
link, | ||
) | ||
|
||
def assign_to_task_definition(self, template, container): | ||
""" | ||
Method to add the secret to the given task definition | ||
:param troposphere.Template template: | ||
:param troposphere.ecs.ContainerDefinition container: | ||
:return: | ||
""" | ||
task_role = template.resources[TASK_ROLE_T] | ||
exec_role = template.resources[EXEC_ROLE_T] | ||
policy = Policy( | ||
PolicyName=f"AccessSecret{self.name}", | ||
PolicyDocument={ | ||
"Version": "2012-10-17", | ||
"Statement": [ | ||
{ | ||
"Action": ["secretsmanager:GetSecretValue"], | ||
"Effect": "Allow", | ||
"Resource": self.aws_name, | ||
"Sid": f"AccessToSecret{self.name}", | ||
} | ||
], | ||
}, | ||
) | ||
if EXEC_ROLE_T in self.links and hasattr(exec_role, "Policies"): | ||
exec_role.Policies.append(policy) | ||
elif EXEC_ROLE_T in self.links and not hasattr(exec_role, "Policies"): | ||
setattr(exec_role, "Policies", [policy]) | ||
if TASK_ROLE_T in self.links and hasattr(task_role, "Policies"): | ||
task_role.Policies.append(policy) | ||
elif TASK_ROLE_T in self.links and not hasattr(task_role, "Policies"): | ||
setattr(task_role, "Policies", [policy]) | ||
extend_container_secrets(container, self.ecs_secret) | ||
|
||
|
||
def parse_secrets(settings): | ||
""" | ||
Function to parse the settings compose content and define the secrets. | ||
:param ecs_composex.common.settings.ComposeXSettings settings: | ||
:return: | ||
""" | ||
if not keyisset(RES_KEY, settings.compose_content): | ||
return | ||
secrets = settings.compose_content[RES_KEY] | ||
for secret_name in secrets: | ||
secret_def = secrets[secret_name] | ||
if keyisset("external", secret_def): | ||
LOG.info(f"Adding secret {secret_name} to settings") | ||
secret_def["ComposeSecret"] = ComposeSecret(secret_name, secret_def) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,6 +40,8 @@ services: | |
|
||
app02: | ||
image: 373709687836.dkr.ecr.eu-west-1.amazonaws.com/blog-app-02:latest | ||
secrets: | ||
- testsecret | ||
ports: | ||
- 5000 | ||
deploy: | ||
|
@@ -81,3 +83,13 @@ services: | |
x-tags: | ||
owner: johnpreston | ||
contact: [email protected] | ||
|
||
|
||
secrets: | ||
testsecret: | ||
external: true | ||
x-secrets: | ||
Name: /path/to/my/secret | ||
LinksTo: | ||
- EcsTaskRole | ||
- EcsExecutionRole |