From db972dea333ba4f1051daedd940906c2f1a52084 Mon Sep 17 00:00:00 2001 From: mattsb42-aws Date: Fri, 7 Dec 2018 18:47:33 -0800 Subject: [PATCH 01/11] update known_third_party for isort --- decrypt_oracle/setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/decrypt_oracle/setup.cfg b/decrypt_oracle/setup.cfg index fa524ca8b..f697eddc4 100644 --- a/decrypt_oracle/setup.cfg +++ b/decrypt_oracle/setup.cfg @@ -39,4 +39,4 @@ force_grid_wrap = 0 combine_as_imports = True not_skip = __init__.py known_first_party = aws_encryption_sdk_decryption_oracle -known_third_party =aws_encryption_sdk,aws_encryption_sdk_decrypt_oracle,aws_encryption_sdk_decryption_oracle,chalice,pytest,requests,setuptools +known_third_party =awacs,aws_encryption_sdk,aws_encryption_sdk_decrypt_oracle,boto3,botocore,chalice,pytest,requests,setuptools,troposphere From 21bed1c7b56206855ce50c9604403a5c98452426 Mon Sep 17 00:00:00 2001 From: mattsb42-aws Date: Fri, 7 Dec 2018 18:51:42 -0800 Subject: [PATCH 02/11] add chalice deployment components --- decrypt_oracle/.chalice/buildspec.yaml | 13 +++++++++++++ decrypt_oracle/tox.ini | 21 ++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 decrypt_oracle/.chalice/buildspec.yaml diff --git a/decrypt_oracle/.chalice/buildspec.yaml b/decrypt_oracle/.chalice/buildspec.yaml new file mode 100644 index 000000000..ee66a1d49 --- /dev/null +++ b/decrypt_oracle/.chalice/buildspec.yaml @@ -0,0 +1,13 @@ +version: 0.2 +phases: + install: + commands: + - pip install --user tox + build: + commands: + - cd decrypt_oracle + - tox -e chalice-deploy +artifacts: + type: zip + files: + - decrypt_oracle/transformed.yaml diff --git a/decrypt_oracle/tox.ini b/decrypt_oracle/tox.ini index 796c5a1c9..ebdc0a746 100644 --- a/decrypt_oracle/tox.ini +++ b/decrypt_oracle/tox.ini @@ -33,6 +33,7 @@ envlist = # test-release :: Builds dist files and uploads to testpypi pypirc profile. # release :: Builds dist files and uploads to pypi pypirc profile. + [testenv:chalice-prep] basepython = python3.6 skip_install = true @@ -58,6 +59,21 @@ commands = {[testenv:chalice-prep]commands} chalice {posargs} +[testenv:chalice-deploy] +basepython = python3.6 +recreate = true +deps = + {[testenv:chalice]deps} + aws +commands = + {[testenv:chalice-prep]commands} + chalice package {envtmpdir}/packaged + aws cloudformation package \ + --template-file {envtmpdir}/packaged/sam.json \ + --s3-bucket $APP_S3_BUCKET \ + --output-template-file transformed.yaml + + [testenv:base-command] commands = pytest --basetemp={envtmpdir} -l --cov aws_encryption_sdk_decrypt_oracle test/ {posargs} @@ -67,10 +83,13 @@ passenv = AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN \ # Pass through AWS profile name (useful for local testing) AWS_PROFILE \ + AWS_DEFAULT_REGION \ # Used to manage test generators AWS_ENCRYPTION_SDK_PYTHON_DECRYPT_ORACLE_GENERATE_TEST_VECTORS \ AWS_ENCRYPTION_SDK_PYTHON_DECRYPT_ORACLE_REGION \ - AWS_ENCRYPTION_SDK_PYTHON_DECRYPT_ORACLE_API_DEPLOYMENT_ID + AWS_ENCRYPTION_SDK_PYTHON_DECRYPT_ORACLE_API_DEPLOYMENT_ID \ + # Used by Chalice + APP_S3_BUCKET sitepackages = False deps = -rtest/requirements.txt From 23eddd58174e3f2ac8a2d3e9bbb2fc527540a138 Mon Sep 17 00:00:00 2001 From: mattsb42-aws Date: Fri, 7 Dec 2018 18:52:16 -0800 Subject: [PATCH 03/11] add ci/cd pipeline build/deploy tool --- decrypt_oracle/.chalice/pipeline.py | 351 ++++++++++++++++++++++++++++ decrypt_oracle/tox.ini | 11 + 2 files changed, 362 insertions(+) create mode 100644 decrypt_oracle/.chalice/pipeline.py diff --git a/decrypt_oracle/.chalice/pipeline.py b/decrypt_oracle/.chalice/pipeline.py new file mode 100644 index 000000000..b6f224412 --- /dev/null +++ b/decrypt_oracle/.chalice/pipeline.py @@ -0,0 +1,351 @@ +""" +Generate the CloudFormation template for the deployment pipeline. +""" +import argparse +import getpass +import logging +from typing import Iterable + +import boto3 +import troposphere +from awacs import ( + aws as AWS, + awslambda as LAMBDA, + cloudformation as CLOUDFORMATION, + cloudwatch as CLOUDWATCH, + codebuild as CODEBUILD, + codepipeline as CODEPIPELINE, + iam as IAM, + logs as LOGS, + s3 as S3, + sts as STS, +) +from botocore.exceptions import ClientError +from troposphere import GetAtt, Ref, Sub, Template, codebuild, codepipeline, iam, s3 + +APPLICATION_NAME = "AwsEncryptionSdkDecryptOraclePython" +PIPELINE_STACK_NAME = "{}DeployPipeline".format(APPLICATION_NAME) +CODEBUILD_IMAGE = "aws/codebuild/python:3.6.5" +BUILDSPEC = "decrypt_oracle/.chalice/buildspec.yaml" +GITHUB_REPO = "aws-encryption-sdk-python" +WAITER_CONFIG = dict(Delay=10) +_LOGGER = logging.getLogger("Decrypt Oracle Build Pipeline Deployer") + + +class AllowEverywhere(AWS.Statement): + def __init__(self, *args, **kwargs): + my_kwargs = dict(Effect=AWS.Allow, Resource=["*"]) + my_kwargs.update(kwargs) + super(AllowEverywhere, self).__init__(*args, **my_kwargs) + + +def _service_assume_role(service: str) -> AWS.Policy: + """""" + return AWS.Policy( + Statement=[ + AWS.Statement( + Effect=AWS.Allow, + Action=[STS.AssumeRole], + Principal=AWS.Principal("Service", ["{}.amazonaws.com".format(service)]), + ) + ] + ) + + +def _codebuild_role() -> iam.Role: + """""" + policy = iam.Policy( + "CodeBuildPolicy", + PolicyName="CodeBuildPolicy", + PolicyDocument=AWS.PolicyDocument( + Statement=[ + AllowEverywhere(Action=[LOGS.CreateLogGroup, LOGS.CreateLogStream, LOGS.PutLogEvents]), + AllowEverywhere(Action=[S3.GetObject, S3.GetObjectVersion, S3.PutObject]), + ] + ), + ) + return iam.Role("CodeBuildRole", AssumeRolePolicyDocument=_service_assume_role(CODEBUILD.prefix), Policies=[policy]) + + +def _codebuild_builder(role: iam.Role, application_bucket: s3.Bucket) -> codebuild.Project: + """""" + artifacts = codebuild.Artifacts(Type="CODEPIPELINE") + environment = codebuild.Environment( + ComputeType="BUILD_GENERAL1_SMALL", + Image=CODEBUILD_IMAGE, + Type="LINUX_CONTAINER", + EnvironmentVariables=[codebuild.EnvironmentVariable(Name="APP_S3_BUCKET", Value=Ref(application_bucket))], + ) + source = codebuild.Source(Type="CODEPIPELINE", BuildSpec=BUILDSPEC) + return codebuild.Project( + "AppPackageBuild", + Artifacts=artifacts, + Environment=environment, + Name="{}Build".format(APPLICATION_NAME), + ServiceRole=Ref(role), + Source=source, + ) + + +def _pipeline_role(buckets: Iterable[s3.Bucket]) -> iam.Role: + """""" + bucket_statements = [ + AWS.Statement( + Effect=AWS.Allow, + Action=[S3.GetBucketVersioning, S3.PutBucketVersioning], + Resource=[GetAtt(bucket, "Arn") for bucket in buckets], + ), + AWS.Statement( + Effect=AWS.Allow, + Action=[S3.GetObject, S3.PutObject], + Resource=[Sub("${{{bucket}.Arn}}/*".format(bucket=bucket.title)) for bucket in buckets], + ), + ] + policy = iam.Policy( + "PipelinePolicy", + PolicyName="PipelinePolicy", + PolicyDocument=AWS.PolicyDocument( + Statement=bucket_statements + + [ + AllowEverywhere(Action=[CLOUDWATCH.Action("*"), IAM.PassRole]), + AllowEverywhere(Action=[LAMBDA.InvokeFunction, LAMBDA.ListFunctions]), + AllowEverywhere( + Action=[ + CLOUDFORMATION.CreateStack, + CLOUDFORMATION.DeleteStack, + CLOUDFORMATION.DescribeStacks, + CLOUDFORMATION.UpdateStack, + CLOUDFORMATION.CreateChangeSet, + CLOUDFORMATION.DeleteChangeSet, + CLOUDFORMATION.DescribeChangeSet, + CLOUDFORMATION.ExecuteChangeSet, + CLOUDFORMATION.SetStackPolicy, + CLOUDFORMATION.ValidateTemplate, + ] + ), + AllowEverywhere(Action=[CODEBUILD.BatchGetBuilds, CODEBUILD.StartBuild]), + ] + ), + ) + return iam.Role( + "CodePipelinesRole", AssumeRolePolicyDocument=_service_assume_role(CODEPIPELINE.prefix), Policies=[policy] + ) + + +def _cloudformation_role() -> iam.Role: + """""" + policy = iam.Policy( + "CloudFormationPolicy", + PolicyName="CloudFormationPolicy", + PolicyDocument=AWS.PolicyDocument(Statement=[AllowEverywhere(Action=[AWS.Action("*")])]), + ) + return iam.Role( + "CloudFormationRole", AssumeRolePolicyDocument=_service_assume_role(CLOUDFORMATION.prefix), Policies=[policy] + ) + + +def _pipeline( + pipeline_role: iam.Role, + cfn_role: iam.Role, + codebuild_builder: codebuild.Project, + artifact_bucket: s3.Bucket, + github_owner: str, + github_branch: str, + github_access_token: troposphere.AWSProperty, +) -> codepipeline.Pipeline: + """""" + _source_output = "SourceOutput" + get_source = codepipeline.Stages( + Name="Source", + Actions=[ + codepipeline.Actions( + Name="PullSource", + RunOrder="1", + OutputArtifacts=[codepipeline.OutputArtifacts(Name=_source_output)], + ActionTypeId=codepipeline.ActionTypeId( + Category="Source", Owner="ThirdParty", Version="1", Provider="GitHub" + ), + Configuration=dict( + Owner=github_owner, + Repo=GITHUB_REPO, + OAuthToken=Ref(github_access_token), + Branch=github_branch, + PollForSourceChanges=True, + ), + ) + ], + ) + _compiled_cfn_template = "CompiledCfnTemplate" + _changeset_name = "{}ChangeSet".format(APPLICATION_NAME) + _stack_name = "{}Stack".format(APPLICATION_NAME) + do_build = codepipeline.Stages( + Name="Build", + Actions=[ + codepipeline.Actions( + Name="BuildChanges", + RunOrder="1", + InputArtifacts=[codepipeline.InputArtifacts(Name=_source_output)], + OutputArtifacts=[codepipeline.OutputArtifacts(Name=_compiled_cfn_template)], + ActionTypeId=codepipeline.ActionTypeId( + Category="Build", Owner="AWS", Version="1", Provider="CodeBuild" + ), + Configuration=dict(ProjectName=Ref(codebuild_builder)), + ) + ], + ) + stage_changeset = codepipeline.Actions( + Name="StageChanges", + RunOrder="1", + ActionTypeId=codepipeline.ActionTypeId(Category="Deploy", Owner="AWS", Version="1", Provider="CloudFormation"), + InputArtifacts=[codepipeline.InputArtifacts(Name=_compiled_cfn_template)], + Configuration=dict( + ActionMode="CHANGE_SET_REPLACE", + ChangeSetName=_changeset_name, + RoleArn=GetAtt(cfn_role, "Arn"), + Capabilities="CAPABILITY_IAM", + StackName=_stack_name, + TemplatePath="{}::transformed.yaml".format(_compiled_cfn_template), + ), + ) + deploy_changeset = codepipeline.Actions( + Name="Deploy", + RunOrder="2", + ActionTypeId=codepipeline.ActionTypeId(Category="Deploy", Owner="AWS", Version="1", Provider="CloudFormation"), + Configuration=dict( + ActionMode="CHANGE_SET_EXECUTE", + ChangeSetName=_changeset_name, + StackName=_stack_name, + OutputFileName="StackOutputs.json", + ), + OutputArtifacts=[codepipeline.OutputArtifacts(Name="AppDeploymentValues")], + ) + deploy = codepipeline.Stages(Name="Deploy", Actions=[stage_changeset, deploy_changeset]) + artifact_store = codepipeline.ArtifactStore(Type="S3", Location=Ref(artifact_bucket)) + return codepipeline.Pipeline( + "{}Pipeline".format(APPLICATION_NAME), + RoleArn=GetAtt(pipeline_role, "Arn"), + ArtifactStore=artifact_store, + Stages=[get_source, do_build, deploy], + ) + + +def _build_template(github_owner: str, github_branch: str) -> Template: + """""" + template = Template(Description="CI/CD pipeline for Decrypt Oracle powered by the AWS Encryption SDK for Python") + github_access_token = template.add_parameter( + troposphere.Parameter( + "GithubPersonalToken", Type="String", Description="Personal access token for the github repo.", NoEcho=True + ) + ) + application_bucket = template.add_resource(s3.Bucket("ApplicationBucket")) + artifact_bucket = template.add_resource(s3.Bucket("ArtifactBucketStore")) + builder_role = template.add_resource(_codebuild_role()) + builder = template.add_resource(_codebuild_builder(builder_role, application_bucket)) + # add codepipeline role + pipeline_role = template.add_resource(_pipeline_role(buckets=[application_bucket, artifact_bucket])) + # add cloudformation deploy role + cfn_role = template.add_resource(_cloudformation_role()) + # add codepipeline + template.add_resource( + _pipeline( + pipeline_role=pipeline_role, + cfn_role=cfn_role, + codebuild_builder=builder, + artifact_bucket=artifact_bucket, + github_owner=github_owner, + github_branch=github_branch, + github_access_token=github_access_token, + ) + ) + return template + + +def _stack_exists(cloudformation) -> bool: + """Determine if the stack has already been deployed.""" + try: + cloudformation.describe_stacks(StackName=PIPELINE_STACK_NAME) + + except ClientError as error: + if error.response["Error"]["Message"] == "Stack with id {name} does not exist".format(name=PIPELINE_STACK_NAME): + return False + raise + + else: + return True + + +def _update_existing_stack(cloudformation, template: Template, github_token: str) -> None: + """Update a stack.""" + _LOGGER.info("Updating existing stack") + + # 3. update stack + cloudformation.update_stack( + StackName=PIPELINE_STACK_NAME, + TemplateBody=template.to_json(), + Parameters=[dict(ParameterKey="GithubPersonalToken", ParameterValue=github_token)], + Capabilities=["CAPABILITY_IAM"], + ) + _LOGGER.info("Waiting for stack update to complete...") + waiter = cloudformation.get_waiter("stack_update_complete") + waiter.wait(StackName=PIPELINE_STACK_NAME, WaiterConfig=WAITER_CONFIG) + _LOGGER.info("Stack update complete!") + + +def _deploy_new_stack(cloudformation, template: Template, github_token: str) -> None: + """Deploy a new stack.""" + _LOGGER.info("Bootstrapping new stack") + + # 2. deploy template + cloudformation.create_stack( + StackName=PIPELINE_STACK_NAME, + TemplateBody=template.to_json(), + Parameters=[dict(ParameterKey="GithubPersonalToken", ParameterValue=github_token)], + Capabilities=["CAPABILITY_IAM"], + ) + _LOGGER.info("Waiting for stack to deploy...") + waiter = cloudformation.get_waiter("stack_create_complete") + waiter.wait(StackName=PIPELINE_STACK_NAME, WaiterConfig=WAITER_CONFIG) + _LOGGER.info("Stack deployment complete!") + + +def _deploy_or_update_template(template: Template, github_token: str) -> None: + """Update a stack, deploying a new stack if nothing exists yet.""" + cloudformation = boto3.client("cloudformation") + + if _stack_exists(cloudformation): + return _update_existing_stack( + cloudformation=cloudformation, + template=template, + github_token=github_token, + ) + + return _deploy_new_stack( + cloudformation=cloudformation, + template=template, + github_token=github_token, + ) + + +def _setup_logging() -> None: + """Set up logging.""" + logging.basicConfig(level=logging.INFO) + + +def main(args=None): + """Entry point for CLI.""" + _setup_logging() + + parser = argparse.ArgumentParser(description="Pipeline deployer") + parser.add_argument("--github-user", required=True, help="What Github user should be used?") + parser.add_argument("--github-branch", required=False, default="master", help="What Github branch should be used?") + + parsed = parser.parse_args(args) + + access_token = getpass.getpass("Github personal token:") + + template = _build_template(github_owner=parsed.github_user, github_branch=parsed.github_branch) + _deploy_or_update_template(template=template, github_token=access_token) + + +if __name__ == "__main__": + main() diff --git a/decrypt_oracle/tox.ini b/decrypt_oracle/tox.ini index ebdc0a746..3c19eb34f 100644 --- a/decrypt_oracle/tox.ini +++ b/decrypt_oracle/tox.ini @@ -34,6 +34,15 @@ envlist = # release :: Builds dist files and uploads to pypi pypirc profile. +[testenv:generate-pipeline] +basepython = python3 +skip_install = true +deps = + troposphere[policy] + boto3 +commands = python .chalice/pipeline.py {posargs} + + [testenv:chalice-prep] basepython = python3.6 skip_install = true @@ -201,6 +210,7 @@ commands = setup.py \ #doc/conf.py \ test/ \ + .chalice/pipeline.py \ {posargs} @@ -231,6 +241,7 @@ commands = isort -rc \ test \ #doc \ setup.py \ + .chalice/pipeline.py \ {posargs} [testenv:isort-check] From b573e737ad7b0b21caf150c858d834be7666be5d Mon Sep 17 00:00:00 2001 From: mattsb42-aws Date: Fri, 7 Dec 2018 18:55:49 -0800 Subject: [PATCH 04/11] install tox to system python in buildspec --- decrypt_oracle/.chalice/buildspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/decrypt_oracle/.chalice/buildspec.yaml b/decrypt_oracle/.chalice/buildspec.yaml index ee66a1d49..657c5a4be 100644 --- a/decrypt_oracle/.chalice/buildspec.yaml +++ b/decrypt_oracle/.chalice/buildspec.yaml @@ -2,7 +2,7 @@ version: 0.2 phases: install: commands: - - pip install --user tox + - pip install tox build: commands: - cd decrypt_oracle From 8aa8494852db54791f65683ce622921123b087bd Mon Sep 17 00:00:00 2001 From: mattsb42-aws Date: Fri, 7 Dec 2018 19:05:24 -0800 Subject: [PATCH 05/11] chalice-deploy needs awscli, not aws --- decrypt_oracle/tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/decrypt_oracle/tox.ini b/decrypt_oracle/tox.ini index 3c19eb34f..42f88742a 100644 --- a/decrypt_oracle/tox.ini +++ b/decrypt_oracle/tox.ini @@ -73,7 +73,7 @@ basepython = python3.6 recreate = true deps = {[testenv:chalice]deps} - aws + awscli commands = {[testenv:chalice-prep]commands} chalice package {envtmpdir}/packaged From 2380866a054bf9bf02f25ab97f16b49e51d2b9e8 Mon Sep 17 00:00:00 2001 From: mattsb42-aws Date: Fri, 7 Dec 2018 19:10:02 -0800 Subject: [PATCH 06/11] correct reference to environment variable in testenv:chalice-deploy --- decrypt_oracle/tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/decrypt_oracle/tox.ini b/decrypt_oracle/tox.ini index 42f88742a..8f5524c4f 100644 --- a/decrypt_oracle/tox.ini +++ b/decrypt_oracle/tox.ini @@ -79,7 +79,7 @@ commands = chalice package {envtmpdir}/packaged aws cloudformation package \ --template-file {envtmpdir}/packaged/sam.json \ - --s3-bucket $APP_S3_BUCKET \ + --s3-bucket {env:APP_S3_BUCKET} \ --output-template-file transformed.yaml From c068e61593529b14a938d81ff019acb2f1035d3f Mon Sep 17 00:00:00 2001 From: mattsb42-aws Date: Fri, 7 Dec 2018 19:14:31 -0800 Subject: [PATCH 07/11] pass through AWS_CONTAINER_CREDENTIALS_RELATIVE_URI to enable credential discovery in CodeBuild --- decrypt_oracle/tox.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/decrypt_oracle/tox.ini b/decrypt_oracle/tox.ini index 8f5524c4f..5104aeadd 100644 --- a/decrypt_oracle/tox.ini +++ b/decrypt_oracle/tox.ini @@ -93,6 +93,8 @@ passenv = # Pass through AWS profile name (useful for local testing) AWS_PROFILE \ AWS_DEFAULT_REGION \ + # Pass through AWS credentials pointer in ECS/CodeBuild + AWS_CONTAINER_CREDENTIALS_RELATIVE_URI \ # Used to manage test generators AWS_ENCRYPTION_SDK_PYTHON_DECRYPT_ORACLE_GENERATE_TEST_VECTORS \ AWS_ENCRYPTION_SDK_PYTHON_DECRYPT_ORACLE_REGION \ From ec15bda4402d9a397d526cb855fd49baec099d4e Mon Sep 17 00:00:00 2001 From: mattsb42-aws Date: Fri, 7 Dec 2018 19:20:17 -0800 Subject: [PATCH 08/11] set correct input reference path for built cloudformation template --- decrypt_oracle/.chalice/pipeline.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/decrypt_oracle/.chalice/pipeline.py b/decrypt_oracle/.chalice/pipeline.py index b6f224412..444701163 100644 --- a/decrypt_oracle/.chalice/pipeline.py +++ b/decrypt_oracle/.chalice/pipeline.py @@ -204,7 +204,7 @@ def _pipeline( RoleArn=GetAtt(cfn_role, "Arn"), Capabilities="CAPABILITY_IAM", StackName=_stack_name, - TemplatePath="{}::transformed.yaml".format(_compiled_cfn_template), + TemplatePath="{}::decrypt_oracle/transformed.yaml".format(_compiled_cfn_template), ), ) deploy_changeset = codepipeline.Actions( From 08e0a5859ee35fcc865ebe7abe6ffea3fae74451 Mon Sep 17 00:00:00 2001 From: mattsb42-aws Date: Fri, 7 Dec 2018 19:34:39 -0800 Subject: [PATCH 09/11] add comments to pipeline builder --- decrypt_oracle/.chalice/pipeline.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/decrypt_oracle/.chalice/pipeline.py b/decrypt_oracle/.chalice/pipeline.py index 444701163..81793aa19 100644 --- a/decrypt_oracle/.chalice/pipeline.py +++ b/decrypt_oracle/.chalice/pipeline.py @@ -33,6 +33,7 @@ class AllowEverywhere(AWS.Statement): + """Shortcut for creating IAM Statements that Allow to Resource "*".""" def __init__(self, *args, **kwargs): my_kwargs = dict(Effect=AWS.Allow, Resource=["*"]) my_kwargs.update(kwargs) @@ -40,7 +41,7 @@ def __init__(self, *args, **kwargs): def _service_assume_role(service: str) -> AWS.Policy: - """""" + """Build and return the IAM AssumeRolePolicy for use in service roles.""" return AWS.Policy( Statement=[ AWS.Statement( @@ -53,7 +54,7 @@ def _service_assume_role(service: str) -> AWS.Policy: def _codebuild_role() -> iam.Role: - """""" + """Build and return the IAM Role resource to be used by CodeBuild to run the build project.""" policy = iam.Policy( "CodeBuildPolicy", PolicyName="CodeBuildPolicy", @@ -68,7 +69,7 @@ def _codebuild_role() -> iam.Role: def _codebuild_builder(role: iam.Role, application_bucket: s3.Bucket) -> codebuild.Project: - """""" + """Build and return the CodeBuild Project resource to be used to build the decrypt oracle.""" artifacts = codebuild.Artifacts(Type="CODEPIPELINE") environment = codebuild.Environment( ComputeType="BUILD_GENERAL1_SMALL", @@ -88,7 +89,7 @@ def _codebuild_builder(role: iam.Role, application_bucket: s3.Bucket) -> codebui def _pipeline_role(buckets: Iterable[s3.Bucket]) -> iam.Role: - """""" + """Build and return the IAM Role resource to be used by CodePipeline to run the pipeline.""" bucket_statements = [ AWS.Statement( Effect=AWS.Allow, @@ -133,7 +134,7 @@ def _pipeline_role(buckets: Iterable[s3.Bucket]) -> iam.Role: def _cloudformation_role() -> iam.Role: - """""" + """Build and return the IAM Role resource to be used by the pipeline to interact with CloudFormation.""" policy = iam.Policy( "CloudFormationPolicy", PolicyName="CloudFormationPolicy", @@ -153,7 +154,7 @@ def _pipeline( github_branch: str, github_access_token: troposphere.AWSProperty, ) -> codepipeline.Pipeline: - """""" + """Build and return the CodePipeline pipeline resource.""" _source_output = "SourceOutput" get_source = codepipeline.Stages( Name="Source", @@ -230,7 +231,7 @@ def _pipeline( def _build_template(github_owner: str, github_branch: str) -> Template: - """""" + """Build and return the pipeline template.""" template = Template(Description="CI/CD pipeline for Decrypt Oracle powered by the AWS Encryption SDK for Python") github_access_token = template.add_parameter( troposphere.Parameter( From 199ed70ca17b825dd5f63fb51620879ddd9f7a90 Mon Sep 17 00:00:00 2001 From: mattsb42-aws Date: Fri, 7 Dec 2018 19:47:41 -0800 Subject: [PATCH 10/11] autoformat --- decrypt_oracle/.chalice/pipeline.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/decrypt_oracle/.chalice/pipeline.py b/decrypt_oracle/.chalice/pipeline.py index 81793aa19..acdfcaba5 100644 --- a/decrypt_oracle/.chalice/pipeline.py +++ b/decrypt_oracle/.chalice/pipeline.py @@ -34,6 +34,7 @@ class AllowEverywhere(AWS.Statement): """Shortcut for creating IAM Statements that Allow to Resource "*".""" + def __init__(self, *args, **kwargs): my_kwargs = dict(Effect=AWS.Allow, Resource=["*"]) my_kwargs.update(kwargs) @@ -314,17 +315,9 @@ def _deploy_or_update_template(template: Template, github_token: str) -> None: cloudformation = boto3.client("cloudformation") if _stack_exists(cloudformation): - return _update_existing_stack( - cloudformation=cloudformation, - template=template, - github_token=github_token, - ) + return _update_existing_stack(cloudformation=cloudformation, template=template, github_token=github_token) - return _deploy_new_stack( - cloudformation=cloudformation, - template=template, - github_token=github_token, - ) + return _deploy_new_stack(cloudformation=cloudformation, template=template, github_token=github_token) def _setup_logging() -> None: From d4a34ef8f661b84a23f6b385ced81601ad90a44f Mon Sep 17 00:00:00 2001 From: mattsb42-aws Date: Mon, 10 Dec 2018 13:34:58 -0800 Subject: [PATCH 11/11] rework CodeBuild names to make more sense --- decrypt_oracle/.chalice/pipeline.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/decrypt_oracle/.chalice/pipeline.py b/decrypt_oracle/.chalice/pipeline.py index acdfcaba5..8734613e3 100644 --- a/decrypt_oracle/.chalice/pipeline.py +++ b/decrypt_oracle/.chalice/pipeline.py @@ -80,10 +80,10 @@ def _codebuild_builder(role: iam.Role, application_bucket: s3.Bucket) -> codebui ) source = codebuild.Source(Type="CODEPIPELINE", BuildSpec=BUILDSPEC) return codebuild.Project( - "AppPackageBuild", + "{}Build".format(APPLICATION_NAME), Artifacts=artifacts, Environment=environment, - Name="{}Build".format(APPLICATION_NAME), + Name=APPLICATION_NAME, ServiceRole=Ref(role), Source=source, )