Skip to content

Commit

Permalink
adding tags to stacks and launches on create and update (issue #551)
Browse files Browse the repository at this point in the history
  • Loading branch information
eamonnfaherty committed Sep 2, 2022
1 parent b80986f commit 221fa3b
Show file tree
Hide file tree
Showing 11 changed files with 79 additions and 29 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

[tool.poetry]
name = "aws-service-catalog-puppet"
version = "0.188.0"
version = "0.189.0"
description = "Making it easier to deploy ServiceCatalog products"
classifiers = ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Programming Language :: Python :: 3", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Natural Language :: English"]
homepage = "https://service-catalog-tools-workshop.com/"
Expand Down
74 changes: 49 additions & 25 deletions servicecatalog_puppet/aws.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ def provision_product_with_plan(
params,
version,
should_use_sns,
tags,
):
uid = f"[{launch_name}] {account_id}:{region}]"
stack_name = "-".join([constants.PREFIX, account_id, region, launch_name])
Expand Down Expand Up @@ -200,7 +201,7 @@ def provision_product_with_plan(
provisioning_parameters.append(
{"Key": p, "Value": params.get(p),}
)
response = service_catalog.create_provisioned_product_plan(
args = dict(
PlanName=stack_name,
PlanType="CLOUDFORMATION",
PathId=path_id,
Expand All @@ -215,6 +216,11 @@ def provision_product_with_plan(
],
NotificationArns=[regional_sns_topic,] if should_use_sns else [],
)
if tags:
args["Tags"].extend(
[dict(Key=t.get("key"), Value=t.get("value")) for t in tags]
)
response = service_catalog.create_provisioned_product_plan(**args)
logger.info(f"{uid} :: Plan created, waiting for completion")

plan_id = response.get("PlanId")
Expand Down Expand Up @@ -334,6 +340,7 @@ def provision_product(
version,
should_use_sns,
execution,
tags,
):
partition = config.get_partition()
uid = f"[{launch_name}] {account_id}:{region}]"
Expand All @@ -346,24 +353,29 @@ def provision_product(
provisioning_parameters.append(
{"Key": p, "Value": params.get(p),}
)
provisioned_product_id = (
service_catalog.provision_product(
ProductId=product_id,
ProvisioningArtifactId=provisioning_artifact_id,
PathName=path_name,
ProvisionedProductName=launch_name,
ProvisioningParameters=provisioning_parameters,
Tags=[
{"Key": "ServiceCatalogPuppet:Actor", "Value": "Generated",},
{"Key": "launch_name", "Value": launch_name,},
{"Key": "version", "Value": version,},
],
NotificationArns=[
f"arn:{partition}:sns:{region}:{puppet_account_id}:servicecatalog-puppet-cloudformation-regional-events",
]
if should_use_sns
else [],
args = dict(
ProductId=product_id,
ProvisioningArtifactId=provisioning_artifact_id,
PathName=path_name,
ProvisionedProductName=launch_name,
ProvisioningParameters=provisioning_parameters,
Tags=[
{"Key": "ServiceCatalogPuppet:Actor", "Value": "Generated",},
{"Key": "launch_name", "Value": launch_name,},
{"Key": "version", "Value": version,},
],
NotificationArns=[
f"arn:{partition}:sns:{region}:{puppet_account_id}:servicecatalog-puppet-cloudformation-regional-events",
]
if should_use_sns
else [],
)
if tags:
args["Tags"].extend(
[dict(Key=t.get("key"), Value=t.get("value")) for t in tags]
)
provisioned_product_id = (
service_catalog.provision_product(**args)
.get("RecordDetail")
.get("ProvisionedProductId")
)
Expand Down Expand Up @@ -405,6 +417,7 @@ def update_provisioned_product(
params,
version,
execution,
tags,
):
uid = f"[{launch_name}] {account_id}:{region}]"
provisioning_parameters = []
Expand All @@ -413,14 +426,25 @@ def update_provisioned_product(
{"Key": p, "Value": params.get(p),}
)

provisioned_product_id = (
service_catalog.update_provisioned_product(
ProductId=product_id,
ProvisioningArtifactId=provisioning_artifact_id,
PathName=path_name,
ProvisionedProductName=launch_name,
ProvisioningParameters=provisioning_parameters,
args = dict(
ProductId=product_id,
ProvisioningArtifactId=provisioning_artifact_id,
PathName=path_name,
ProvisionedProductName=launch_name,
ProvisioningParameters=provisioning_parameters,
Tags=[
{"Key": "ServiceCatalogPuppet:Actor", "Value": "Generated",},
{"Key": "launch_name", "Value": launch_name,},
{"Key": "version", "Value": version,},
],
)
if tags:
args["Tags"].extend(
[dict(Key=t.get("key"), Value=t.get("value")) for t in tags]
)

provisioned_product_id = (
service_catalog.update_provisioned_product(**args)
.get("RecordDetail")
.get("ProvisionedProductId")
)
Expand Down
2 changes: 2 additions & 0 deletions servicecatalog_puppet/manifest_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,7 @@ def get_tasks_for(
product=item.get("product"),
version=item.get("version"),
execution=item.get("execution", constants.EXECUTION_MODE_DEFAULT),
tags=item.get("tags", []),
),
"stacks": dict(
stack_name=item_name,
Expand All @@ -790,6 +791,7 @@ def get_tasks_for(
constants.MANIFEST_SHOULD_USE_STACKS_SERVICE_ROLE,
constants.CONFIG_SHOULD_USE_STACKS_SERVICE_ROLE_DEFAULT,
),
tags=item.get("tags", []),
),
"apps": dict(
app_name=item_name,
Expand Down
6 changes: 6 additions & 0 deletions servicecatalog_puppet/schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ stack:
launch_name: str(required=False)
parameters: include('parameters', required=False)
depends_on: list(include('depends_on'), required=False)
tags: list(include('tags_for_resources'), required=False)
execution: include('execution', required=False)
deploy_to: any(include('tags'), include('accounts'))
outputs: include('outputs', required=False)
Expand All @@ -150,6 +151,10 @@ app:
outputs: include('outputs', required=False)
capabilities: list(enum("CAPABILITY_IAM", "CAPABILITY_NAMED_IAM", "CAPABILITY_AUTO_EXPAND"), required=False)

tags_for_resources:
key: str()
value: str()

outputs:
ssm: list(include('ssm_output'))

Expand Down Expand Up @@ -179,6 +184,7 @@ launch:
version: str()
parameters: include('parameters', required=False)
depends_on: list(include('depends_on'), required=False)
tags: list(include('tags_for_resources'), required=False)
execution: include('execution', required=False)
deploy_to: any(include('tags'), include('accounts'))
outputs: include('outputs', required=False)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ def create(
use_service_role=parameters_to_use.get("use_service_role"),
execution=parameters_to_use.get("execution"),
manifest_file_path=manifest_file_path,
tags=parameters_to_use.get("tags"),
)

elif section_name == constants.LAUNCHES:
Expand Down Expand Up @@ -137,6 +138,7 @@ def create(
worker_timeout=parameters_to_use.get("worker_timeout"),
requested_priority=parameters_to_use.get("requested_priority"),
execution=parameters_to_use.get("execution"),
tags=parameters_to_use.get("tags"),
manifest_file_path=manifest_file_path,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class ProvisionProductTask(tasks.TaskWithParameters):
requested_priority = luigi.IntParameter(significant=False, default=0)

execution = luigi.Parameter()
tags = luigi.ListParameter()

section_name = constants.LAUNCHES

Expand Down Expand Up @@ -212,6 +213,7 @@ def run(self):
params_to_use,
self.version,
self.should_use_sns,
self.tags,
)
else:
provisioned_product_id = aws.update_provisioned_product(
Expand All @@ -226,6 +228,7 @@ def run(self):
params_to_use,
self.version,
self.execution,
self.tags,
)

else:
Expand All @@ -242,6 +245,7 @@ def run(self):
self.version,
self.should_use_sns,
self.execution,
self.tags,
)

self.write_output(task_output)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class ProvisionProductTaskTest(tasks_unit_tests_helper.PuppetTaskUnitTest):
manifest_parameters = {}
account_parameters = {}
ssm_param_outputs = []
tags = []
execution = "execution"

def setUp(self) -> None:
Expand All @@ -42,7 +43,8 @@ def setUp(self) -> None:
manifest_parameters=self.manifest_parameters,
account_parameters=self.account_parameters,
ssm_param_outputs=self.ssm_param_outputs,
execution=self.execution
execution=self.execution,
tags=self.tags,
)

self.wire_up_mocks()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class ProvisionStackDryRunTaskTest(tasks_unit_tests_helper.PuppetTaskUnitTest):
ssm_param_outputs = []
execution = "execution"
manifest_file_path = "manifest_file_path"
tags = []

def setUp(self) -> None:
from servicecatalog_puppet.workflow.stack import provision_stack_dry_run_task
Expand All @@ -45,6 +46,7 @@ def setUp(self) -> None:
ssm_param_outputs=self.ssm_param_outputs,
execution=self.execution,
manifest_file_path=self.manifest_file_path,
tags=self.tags,
)

self.wire_up_mocks()
Expand Down
6 changes: 6 additions & 0 deletions servicecatalog_puppet/workflow/stack/provision_stack_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ class ProvisionStackTask(tasks.TaskWithParameters):
execution = luigi.Parameter()
manifest_file_path = luigi.Parameter()

tags = luigi.ListParameter()

section_name = constants.STACKS

@property
Expand Down Expand Up @@ -297,6 +299,10 @@ def run(self):
)
if self.use_service_role:
a["RoleARN"] = config.get_puppet_stack_role_arn(self.account_id)
if self.tags:
a["Tags"] = [
dict(Key=t.get("key"), Value=t.get("value")) for t in self.tags
]
cloudformation.create_or_update(**a)

task_output["provisioned"] = need_to_provision
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class ProvisionStackTaskTest(tasks_unit_tests_helper.PuppetTaskUnitTest):
ssm_param_outputs = []
execution = "execution"
manifest_file_path = "manifest_file_path"
tags = []

def setUp(self) -> None:
from servicecatalog_puppet.workflow.stack import provision_stack_task
Expand All @@ -44,7 +45,8 @@ def setUp(self) -> None:
account_parameters=self.account_parameters,
ssm_param_outputs=self.ssm_param_outputs,
execution=self.execution,
manifest_file_path=self.manifest_file_path
manifest_file_path=self.manifest_file_path,
tags=self.tags,
)

self.wire_up_mocks()
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@

setup_kwargs = {
'name': 'aws-service-catalog-puppet',
'version': '0.188.0',
'version': '0.189.0',
'description': 'Making it easier to deploy ServiceCatalog products',
'long_description': '# aws-service-catalog-puppet\n\n![logo](./docs/logo.png) \n\n## Badges\n\n[![codecov](https://codecov.io/gh/awslabs/aws-service-catalog-puppet/branch/master/graph/badge.svg?token=e8M7mdsmy0)](https://codecov.io/gh/awslabs/aws-service-catalog-puppet)\n\n\n## What is it?\nThis is a python3 framework that makes it easier to share multi region AWS Service Catalog portfolios and makes it \npossible to provision products into accounts declaratively using a metadata based rules engine.\n\nWith this framework you define your accounts in a YAML file. You give each account a set of tags, a default region and \na set of enabled regions.\n\nOnce you have done this you can define portfolios should be shared with each set of accounts using the tags and you \ncan specify which regions the shares occur in.\n\nIn addition to this, you can also define products that should be provisioned into accounts using the same tag based \napproach. The framework will assume role into the target account and provision the product on your behalf.\n\n\n## Getting started\n\nYou can read the [installation how to](https://service-catalog-tools-workshop.com/30-how-tos/10-installation/30-service-catalog-puppet.html)\nor you can read through the [every day use](https://service-catalog-tools-workshop.com/30-how-tos/50-every-day-use.html)\nguides.\n\nYou can read the [documentation](https://aws-service-catalog-puppet.readthedocs.io/en/latest/) to understand the inner \nworkings. \n\n\n## Going further\n\nThe framework is one of a pair. The other is [aws-service-catalog-factory](https://github.com/awslabs/aws-service-catalog-factory).\nWith Service Catalog Factory you can create pipelines that deploy multi region portfolios very easily. \n\n## License\n\nThis library is licensed under the Apache 2.0 License. \n \n',
'author': 'Eamonn Faherty',
Expand Down

0 comments on commit 221fa3b

Please sign in to comment.