Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow-for-empty-targets-in-deployment-maps #634

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/admin-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,14 @@ Config has five components in `main-notification-endpoint`, `scp`, `scm`,
`master` instead. We recommend configuring the main scm branch name to
`main`. As new repositories will most likely use this branch name as their
default branch.
- `deployment-maps` tracks all source code management configuration.
- **allow-empty-target** allows you to configure deployment maps with empty targets.
If all targets get evaluated to empty, the ADF CodePipeline is still created
based on the remaining providers (e.g. source and build). It just doesn't have
a deploy stage.
Use cases might include the following:
- target an OU that doesn't have any AWS Accounts (initially or temporarily).
- target AWS Accounts by tag with no AWS Accounts having that tag assigned (yet).

## Accounts

Expand Down
3 changes: 3 additions & 0 deletions src/lambda_codebase/initial_commit/adfconfig.yml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@ config:
scm:
auto-create-repositories: enabled
default-scm-branch: main
# deployment-maps:
# Optional:
# allow-empty-target: "TRUE" # Needs to be "TRUE" or "FALSE". # Defaults to "FALSE", if not set.
AndyEfaa marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,14 @@ def generate_pipeline_inputs(
list(target_structure.generate_waves()),
)

# Print out if final target list is empty...
number_targets_total = 0
AndyEfaa marked this conversation as resolved.
Show resolved Hide resolved
for target in pipeline_object.template_dictionary["targets"]:
number_targets_total = number_targets_total + len(target)
AndyEfaa marked this conversation as resolved.
Show resolved Hide resolved
LOGGER.info("We found %s targets total", number_targets_total)
if number_targets_total == 0:
LOGGER.info("We'll create an empty pipeline with no targets!")
AndyEfaa marked this conversation as resolved.
Show resolved Hide resolved

if DEPLOYMENT_ACCOUNT_REGION not in regions:
pipeline_object.stage_regions.append(DEPLOYMENT_ACCOUNT_REGION)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"ACCOUNT_BOOTSTRAPPING_STATE_MACHINE_ARN"
)
ADF_DEFAULT_SCM_FALLBACK_BRANCH = 'master'
ADF_DEFAULT_ALLOW_EMPTY_DEPLOYMENT_MAPS = "FALSE"
LOGGER = configure_logger(__name__)


Expand Down Expand Up @@ -151,6 +152,13 @@ def prepare_deployment_account(sts, deployment_account_id, config):
ADF_DEFAULT_SCM_FALLBACK_BRANCH,
)
)
deployment_account_parameter_store.put_parameter(
'/adf/deployment-maps/allow-empty-target',
config.config.get('deployment-maps', {}).get(
'allow-empty-target',
ADF_DEFAULT_ALLOW_EMPTY_DEPLOYMENT_MAPS,
)
)
auto_create_repositories = config.config.get(
'scm', {}).get('auto-create-repositories')
if auto_create_repositories is not None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,14 @@
from logger import configure_logger
from schema_validation import AWS_ACCOUNT_ID_REGEX_STR

from errors import ParameterNotFoundError
from parameter_store import ParameterStore
import boto3

LOGGER = configure_logger(__name__)
ADF_DEPLOYMENT_ACCOUNT_ID = os.environ["ACCOUNT_ID"]
DEPLOYMENT_ACCOUNT_REGION = os.environ["AWS_REGION"]

AWS_ACCOUNT_ID_REGEX = re.compile(AWS_ACCOUNT_ID_REGEX_STR)


Expand Down Expand Up @@ -94,6 +99,11 @@ def __init__(
)
self.target_structure = target_structure
self.organizations = organizations
parameter_store = ParameterStore(DEPLOYMENT_ACCOUNT_REGION, boto3)
self.allow_empty_deployment_maps = parameter_store.fetch_parameter(
AndyEfaa marked this conversation as resolved.
Show resolved Hide resolved
"/adf/deployment-maps/allow-empty-target"
)


@staticmethod
def _account_is_active(account):
Expand Down Expand Up @@ -133,8 +143,16 @@ def _create_response_object(self, responses):
str(response.get('Id'))
)
)
if accounts_found == 0:
raise NoAccountsFoundError(f"No accounts found in {self.path}")

if self.allow_empty_deployment_maps == "TRUE":
# We now allow empty deployment maps
if accounts_found == 0:
LOGGER.info(
'Create_response_object: AWS accounts found is 0',
)
else:
if accounts_found == 0:
AndyEfaa marked this conversation as resolved.
Show resolved Hide resolved
raise NoAccountsFoundError(f"No accounts found in {self.path}")
AndyEfaa marked this conversation as resolved.
Show resolved Hide resolved

def _target_is_account_id(self):
responses = self.organizations.client.describe_account(
Expand Down Expand Up @@ -203,9 +221,14 @@ def fetch_accounts_for_target(self):
)
if str(self.path).startswith('/'):
return self._target_is_ou_path()
if self.path is None:
# No path/target has been passed, path will default to /deployment
return self._target_is_null_path()
raise InvalidDeploymentMapError(
f"Unknown definition for target: {self.path}"
)

if self.allow_empty_deployment_maps == "TRUE":
AndyEfaa marked this conversation as resolved.
Show resolved Hide resolved
return
else:
if self.path is None:
# No path/target has been passed, path will default to /deployment
return self._target_is_null_path()

raise InvalidDeploymentMapError(
f"Unknown definition for target: {self.path}"
)
AndyEfaa marked this conversation as resolved.
Show resolved Hide resolved
Loading