Skip to content

Commit

Permalink
Merge branch 'master' into enable-enterprise-support-on-creation
Browse files Browse the repository at this point in the history
  • Loading branch information
Stewart Wallace authored Mar 13, 2020
2 parents 0030b93 + 3709469 commit 5fff1b0
Show file tree
Hide file tree
Showing 17 changed files with 685 additions and 49 deletions.
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ init:
test:
# Run unit tests
pytest src/lambda_codebase/initial_commit/bootstrap_repository -vvv -s -c src/lambda_codebase/initial_commit/bootstrap_repository/pytest.ini
pytest src/lambda_codebase/initial_commit/bootstrap_repository/adf-bootstrap/deployment/lambda_codebase -vvv -s -c src/lambda_codebase/initial_commit/bootstrap_repository/adf-bootstrap/deployment/lambda_codebase/pytest.ini
pytest src/lambda_codebase/initial_commit/bootstrap_repository/adf-bootstrap/deployment/lambda_codebase -vvv -s -c src/lambda_codebase/initial_commit/bootstrap_repository/adf-bootstrap/deployment/lambda_codebase/pytest.ini
pytest src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/python -vvv -s -c src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/python/pytest.ini
pytest src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/cdk -vvv -s -c src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/cdk/pytest.ini
pytest src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared -vvv -s -c src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/pytest.ini
lint:
# Linter performs static analysis to catch latent bugs
find src/ -iname "*.py" | xargs pylint --rcfile .pylintrc
find src/ -iname "*.py" | xargs pylint --rcfile .pylintrc
14 changes: 8 additions & 6 deletions docs/user-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ pipelines:
### Parameter Injection
Parameter injection solves problems that occur with Cross Account parameter access. This concept allows the resolution of values directly from SSM Parameter Store within the Deployment account into Parameter files *(eg global.json, account-name.json)* and also importing of exported values from CloudFormation stacks across accounts and regions.
Parameter injection solves problems that occur with Cross Account parameter access. This concept allows the resolution of values directly from SSM Parameter Store within the Deployment account into Parameter files *(eg global.json, account-name.json)* and also importing of output values from CloudFormation stacks across accounts and regions.
#### Retrieving parameter values
Expand All @@ -410,16 +410,16 @@ To highlight an example of how Parameter Injection can work well, think of the f
There is also the concept of optionally resolving or importing values. This can be achieved by ending the import or resolve function with a **?**. For example, if you want to resolve a value from Parameter Store that might or might not yet exist you can use an optional resolve *(eg resolve:/my/path/to/myMagicKey?)*. If the key *myMagicKey* does not exist in Parameter Store then an empty string will be returned as the value.
#### Importing exported values
#### Importing output values
Parameter injection is also useful for importing exported values from CloudFormation stacks in other accounts or regions. Using the special **"import"** syntax you can access these values directly into your parameter files.
Parameter injection is also useful for importing output values from CloudFormation stacks in other accounts or regions. Using the special **"import"** syntax you can access these values directly into your parameter files.
```yaml
Parameters:
BucketInLoggingAccount: 'import:123456789101:eu-west-1:stack_name:export_key'
BucketInLoggingAccount: 'import:123456789101:eu-west-1:stack_name:output_key'
```
In the above example *123456789101* is the AWS Account Id in which we want to pull a value from, *eu-west-1* is the region, stack_name is the CloudFormation stack name and *export_key* is the output key name *(not export name)*. Again, this concept works with the optional style syntax *(eg, import:123456789101:eu-west-1:stack_name:export_key?)* if the key *export_key* does not exist at the point in time when this specific import is executed, it will return an empty string as the parameter value rather than an error since it is considered optional.
In the above example *123456789101* is the AWS Account Id in which we want to pull a value from, *eu-west-1* is the region, stack_name is the CloudFormation stack name and *output_key* is the output key name *(not export name)*. Again, this concept works with the optional style syntax *(eg, import:123456789101:eu-west-1:stack_name:output_key?)* if the key *output_key* does not exist at the point in time when this specific import is executed, it will return an empty string as the parameter value rather than an error since it is considered optional.
#### Uploading assets
Expand All @@ -445,7 +445,7 @@ upload:${style}:${local_path}
upload:${style}:${region}:${local_path}
```

There are three different styles that one could choose from.
There are five different styles that one could choose from.

* `path` style, as shown in the example above, will return the S3 path to the object as.
This is referred to as the classic [Path Style method](https://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html).
Expand All @@ -464,6 +464,8 @@ There are three different styles that one could choose from.
* `s3-uri` style, will return the S3 location using S3 URI without specifying a protocol.
As an example, this style is required for [CodeBuild project source locations](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codebuild-project-source.html#cfn-codebuild-project-source-location).
* It returns: `${bucket}/${key}`
* `s3-key-only` style, similar to `s3-uri` but it will only return the `key` value.
* It returns: `${key}`

The `region` is optional.
This allows you to upload files to S3 Buckets within specific regions by
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,6 @@ Resources:
- !Sub arn:aws:iam::${DeploymentAccountId}:role/adf-codebuild-role
Action:
- sts:AssumeRole
Condition:
ArnEquals:
'aws:SourceArn': !Sub 'arn:aws:codebuild:${AWS::Region}:${DeploymentAccountId}:project/*'
Path: /
ReadOnlyAutomationRolePolicy:
Type: AWS::IAM::Policy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@

ADF_DEPLOYMENT_REGION = os.environ["AWS_REGION"]
ADF_DEPLOYMENT_ACCOUNT_ID = os.environ["ACCOUNT_ID"]
DEFAULT_CODEBUILD_IMAGE = "UBUNTU_14_04_PYTHON_3_7_1"

class CodeBuild(core.Construct):
# pylint: disable=no-value-for-parameter

def __init__(self, scope: core.Construct, id: str, shared_modules_bucket: str, deployment_region_kms: str, map_params: dict, target, **kwargs): #pylint: disable=W0622
super().__init__(scope, id, **kwargs)
ADF_DEFAULT_BUILD_ROLE = 'arn:aws:iam::{0}:role/adf-codebuild-role'.format(ADF_DEPLOYMENT_ACCOUNT_ID)
Expand Down Expand Up @@ -121,35 +124,32 @@ def __init__(self, scope: core.Construct, id: str, shared_modules_bucket: str, d

@staticmethod
def determine_build_image(scope, target, map_params):
specific_image = None
if target:
return target.get(
'properties', {}).get(
'image') or getattr(
_codebuild.LinuxBuildImage,
map_params['default_providers']['deploy'].get(
'properties', {}).get(
'image', "UBUNTU_14_04_PYTHON_3_7_1").upper())
if isinstance(map_params['default_providers']['build'].get('properties', {}).get('image', False), dict):
_image_repo_arn = target.get(
'properties', {}).get(
'image', {}).get(
'repository_arn', {}) or map_params['default_providers']['build'].get(
'properties', {}).get(
'image', {}).get(
'repository_arn', {})
_tag = target.get(
'properties', {}).get(
'image', {}).get(
'tag', '') or map_params['default_providers']['build'].get(
'properties', {}).get(
'image', {}).get(
'tag', 'latest')
_repo_arn = _ecr.Repository.from_repository_arn(scope, 'custom_repo', _image_repo_arn)
return _codebuild.LinuxBuildImage.from_ecr_repository(_repo_arn, _tag)
return getattr(_codebuild.LinuxBuildImage,
map_params['default_providers']['build'].get(
'properties', {}).get(
'image', "UBUNTU_14_04_PYTHON_3_7_1").upper())
specific_image = (
target.get('properties', {}).get('image') or
map_params['default_providers']['deploy'].get(
'properties', {}).get('image')
)
else:
specific_image = (
map_params['default_providers']['build'].get(
'properties', {}).get('image')
)
if isinstance(specific_image, dict):
repo_arn = _ecr.Repository.from_repository_arn(
scope,
'custom_repo',
specific_image.get('repository_arn', ''),
)
return _codebuild.LinuxBuildImage.from_ecr_repository(
repo_arn,
specific_image.get('tag', 'latest'),
)
return getattr(
_codebuild.LinuxBuildImage,
(specific_image or DEFAULT_CODEBUILD_IMAGE).upper(),
)

@staticmethod
def generate_build_env_variables(codebuild, shared_modules_bucket, map_params, target=None):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ def _generate_configuration(self): #pylint: disable=R0912, R0911, R0915
"Owner": self.map_params.get('default_providers', {}).get('source').get('properties', {}).get('owner', {}),
"Repo": self.map_params.get('default_providers', {}).get('source', {}).get('properties', {}).get('repository', {}) or self.map_params['name'],
"Branch": self.map_params.get('default_providers', {}).get('source', {}).get('properties', {}).get('branch', {}) or 'master',
# pylint: disable=no-value-for-parameter
"OAuthToken": core.SecretValue.secrets_manager(
self.map_params['default_providers']['source'].get('properties', {}).get('oauth_token_path'),
json_field=self.map_params['default_providers']['source'].get('properties', {}).get('json_field')
Expand Down Expand Up @@ -394,5 +395,6 @@ def generate_artifact_stores(map_params, ssm_params):
def import_required_arns():
_output = []
for arn in Pipeline._import_arns:
# pylint: disable=no-value-for-parameter
_output.append(core.Fn.import_value(arn))
return _output
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
class Events(core.Construct):
def __init__(self, scope: core.Construct, id: str, params: dict, **kwargs): #pylint: disable=W0622
super().__init__(scope, id, **kwargs)
# pylint: disable=no-value-for-parameter
_pipeline = _codepipeline.Pipeline.from_pipeline_arn(self, 'pipeline', params["pipeline"])
_source_account = params.get('source', {}).get('account_id')
_provider = params.get('source', {}).get('provider')
Expand Down Expand Up @@ -58,6 +59,7 @@ def __init__(self, scope: core.Construct, id: str, params: dict, **kwargs): #pyl
)
)
if params.get('topic_arn'):
# pylint: disable=no-value-for-parameter
_topic = _sns.Topic.from_topic_arn(self, 'topic_arn', params["topic_arn"])
_event = _events.Rule(
self,
Expand Down Expand Up @@ -117,6 +119,7 @@ def __init__(self, scope: core.Construct, id: str, params: dict, **kwargs): #pyl
source=["aws.codepipeline"]
)
)
# pylint: disable=no-value-for-parameter
_completion_pipeline = _codepipeline.Pipeline.from_pipeline_arn(
self,
'pipeline-{0}'.format(index),
Expand All @@ -135,6 +138,7 @@ def __init__(self, scope: core.Construct, id: str, params: dict, **kwargs): #pyl
'schedule_{0}'.format(params['name']),
description="Triggers {0} on a schedule of {1}".format(params['name'], params['schedule']),
enabled=True,
# pylint: disable=no-value-for-parameter
schedule=_events.Schedule.expression(params['schedule'])
)
_target_pipeline = _targets.CodePipeline(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ def create_webhook(scope, pipeline, map_params):
],
target_action="source",
name="adf-webhook-{0}".format(map_params['name']),
# pylint: disable=no-value-for-parameter
target_pipeline_version=core.Token.as_number(_version),
register_with_third_party=True
)
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class Notifications(core.Construct):
def __init__(self, scope: core.Construct, id: str, map_params: dict, **kwargs): #pylint: disable=W0622
super().__init__(scope, id, **kwargs)
LOGGER.debug('Notification configuration required for %s', map_params['name'])
# pylint: disable=no-value-for-parameter
_slack_func = _lambda.Function.from_function_arn(
self,
'slack_lambda_function',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT-0

"""
Tests for cdk_constructs
"""

import sys
import os

sys.path.append(
os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')))
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__))))
Loading

0 comments on commit 5fff1b0

Please sign in to comment.