Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
4560f77
sam pipeline bootstrap (#2811)
elbayaaa Apr 24, 2021
aaa4c6a
sam pipeline init command (#2831)
elbayaaa Apr 30, 2021
fbbd90b
Merge branch 'develop' into sam-pipeline
elbayaaa May 20, 2021
ae4b8b6
Let 'sam pipeline init' prefills pipeline's infrastructure resources…
elbayaaa May 20, 2021
163fa7e
Rename the pipeline 'Stage' concept to 'Environment' (#2908)
elbayaaa May 27, 2021
7793d2e
Sam pipelines ux rename ecr repo to image repository (#2910)
elbayaaa May 28, 2021
042a0e7
feat: Support creating pipeline files directly into . without hooks (…
aahung May 28, 2021
063e331
Integration test for pipeline init and pipeline bootstrap (#2841)
aahung May 28, 2021
4303760
small UX improvements: (#2914)
elbayaaa May 31, 2021
0a0ab43
Merge branch 'develop' into sam-pipelines
elbayaaa Jun 21, 2021
c2db1fd
Sam pipelines s3 security (#2975)
elbayaaa Jun 23, 2021
39d53fd
Ensure the ArtifactsLoggingBucket denies non ssl requests (#2976)
elbayaaa Jun 23, 2021
94b8faa
Sam pipelines ux round 3 (#2979)
elbayaaa Jun 24, 2021
0f07bfa
let pipeline IAM user assume only IAM roles tagged with Role=pipeline…
elbayaaa Jun 25, 2021
8b5950d
Adding AWS_ prefix to displayed out. (#2993)
c2tarun Jun 29, 2021
57f1b44
Add region to pipeline bootstrap interactive flow (#2997)
aahung Jun 30, 2021
5e91958
Inform write to pipelineconfig.toml at the end of bootstrap (#3002)
aahung Jul 1, 2021
ac972fa
List detected env names in pipeline init when prompt to input the env…
aahung Jul 5, 2021
f442b2d
Adding account id to bootstrap message. (#2998)
c2tarun Jul 6, 2021
81dabd0
Cfn creds fix (#3014)
c2tarun Jul 7, 2021
a23a11a
Ux bootstrap revamp 20210706 (#3021)
aahung Jul 7, 2021
74b49c1
Adding account condition for CFN execution role. (#3027)
c2tarun Jul 8, 2021
4efda8a
pipeline UX revamp 20210707 (#3031)
aahung Jul 13, 2021
a88e9b2
Removing ip range option from bootstrap. (#3036)
c2tarun Jul 13, 2021
b945b2f
Fix toml file incorrect read/write in init --bootstrap (#3037)
aahung Jul 13, 2021
3df5957
Temporarily removing account fix. (#3038)
c2tarun Jul 13, 2021
7c261bc
Rename environment to stage (#3040)
aahung Jul 13, 2021
cc9b7e1
Improve account source selection (#3042)
aahung Jul 13, 2021
174f68c
Fixing various cosmetics UX issues with pipeline workflow. (#3046)
c2tarun Jul 14, 2021
de116e3
Auto skip questions if stage detected (#3045)
aahung Jul 14, 2021
a5364bf
Merge remote-tracking branch 'upstream/develop' into sam-pipelines
aahung Jul 14, 2021
f490395
Merge pull request #3056 from aahung/sam-pipelines
aahung Jul 14, 2021
fd05aa5
Allow to use index to select stage names (#3051)
aahung Jul 14, 2021
618b0b0
Updating message when bootstrap stages are missing. (#3058)
c2tarun Jul 15, 2021
d2247a1
Fixing bootstrap integ tests. (#3061)
c2tarun Jul 16, 2021
89308fb
Fix bootstrap test region (#3064)
aahung Jul 16, 2021
9223aaa
Add more pipeline init integ test (#3065)
aahung Jul 17, 2021
9f55cce
Config file bug (#3066)
c2tarun Jul 17, 2021
cebae87
Fix pipeline init integ test because of pipelineconfig file exists (#…
aahung Jul 17, 2021
07fcdea
Make stage name randomized to avoid race condition among multi canary…
aahung Jul 19, 2021
f836d82
Load number of stages from pipeline template (#3059)
aahung Jul 19, 2021
d762ffe
Allow roles with Tag aws-sam-pipeline-codebuild-service-role to assum…
aahung Jul 20, 2021
5ce9a54
pipeline init UX: Ask to confirm when file exists (#3079)
aahung Jul 20, 2021
5992d76
Add doc links (#3087)
aahung Jul 20, 2021
ace524c
Adding accidentally removed tests back. (#3088)
c2tarun Jul 20, 2021
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
2 changes: 1 addition & 1 deletion mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,6 @@ ignore_missing_imports=True
ignore_missing_imports=True

# progressive add typechecks and these modules already complete the process, let's keep them clean
[mypy-samcli.commands.build,samcli.lib.build.*,samcli.commands.local.cli_common.invoke_context,samcli.commands.local.lib.local_lambda,samcli.lib.providers.*,samcli.lib.utils.git_repo.py]
[mypy-samcli.commands.build,samcli.lib.build.*,samcli.commands.local.cli_common.invoke_context,samcli.commands.local.lib.local_lambda,samcli.lib.providers.*,samcli.lib.utils.git_repo.py,samcli.lib.cookiecutter.*,samcli.lib.pipeline.*,samcli.commands.pipeline.*]
disallow_untyped_defs=True
disallow_incomplete_defs=True
1 change: 1 addition & 0 deletions samcli/cli/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"samcli.commands.deploy",
"samcli.commands.logs",
"samcli.commands.publish",
"samcli.commands.pipeline.pipeline",
# We intentionally do not expose the `bootstrap` command for now. We might open it up later
# "samcli.commands.bootstrap",
]
Expand Down
4 changes: 2 additions & 2 deletions samcli/cli/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import logging
import uuid
from typing import Optional, cast
from typing import Optional, cast, List

import boto3
import botocore
Expand Down Expand Up @@ -186,7 +186,7 @@ def _refresh_session(self):
raise CredentialsError(str(ex)) from ex


def get_cmd_names(cmd_name, ctx):
def get_cmd_names(cmd_name, ctx) -> List[str]:
"""
Given the click core context, return a list representing all the subcommands passed to the CLI

Expand Down
6 changes: 3 additions & 3 deletions samcli/commands/_utils/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@
import yaml
from botocore.utils import set_value_from_jmespath

from samcli.commands.exceptions import UserException
from samcli.lib.utils.packagetype import ZIP
from samcli.yamlhelper import yaml_parse, yaml_dump
from samcli.commands._utils.resources import (
METADATA_WITH_LOCAL_PATHS,
RESOURCES_WITH_LOCAL_PATHS,
AWS_SERVERLESS_FUNCTION,
AWS_LAMBDA_FUNCTION,
get_packageable_resource_paths,
)
from samcli.commands.exceptions import UserException
from samcli.lib.utils.packagetype import ZIP
from samcli.yamlhelper import yaml_parse, yaml_dump


class TemplateNotFoundException(UserException):
Expand Down
4 changes: 2 additions & 2 deletions samcli/commands/deploy/guided_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from typing import Dict, Any, List

import click
from botocore.session import get_session
from click import confirm
from click import prompt
from click.types import FuncParamType
Expand Down Expand Up @@ -36,6 +35,7 @@
from samcli.lib.providers.sam_function_provider import SamFunctionProvider
from samcli.lib.providers.sam_stack_provider import SamLocalStackProvider
from samcli.lib.utils.colors import Colored
from samcli.lib.utils.defaults import get_default_aws_region
from samcli.lib.utils.packagetype import IMAGE

LOG = logging.getLogger(__name__)
Expand Down Expand Up @@ -110,7 +110,7 @@ def guided_prompts(self, parameter_override_keys):
The keys of parameters to override, for each key, customers will be asked to provide a value
"""
default_stack_name = self.stack_name or "sam-app"
default_region = self.region or get_session().get_config_variable("region") or "us-east-1"
default_region = self.region or get_default_aws_region()
default_capabilities = self.capabilities[0] or ("CAPABILITY_IAM",)
default_config_env = self.config_env or DEFAULT_ENV
default_config_file = self.config_file or DEFAULT_CONFIG_FILE_NAME
Expand Down
19 changes: 19 additions & 0 deletions samcli/commands/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,22 @@ class ContainersInitializationException(UserException):
"""
Exception class when SAM is not able to initialize any of the lambda functions containers
"""


class PipelineTemplateCloneException(UserException):
"""
Exception class when unable to download pipeline templates from a Git repository during `sam pipeline init`
"""


class AppPipelineTemplateManifestException(UserException):
"""
Exception class when SAM is not able to parse the "manifest.yaml" file located in the SAM pipeline templates
Git repo: "github.com/aws/aws-sam-cli-pipeline-init-templates.git
"""


class AppPipelineTemplateMetadataException(UserException):
"""
Exception class when SAM is not able to parse the "metadata.json" file located in the SAM pipeline templates
"""
Empty file.
Empty file.
238 changes: 238 additions & 0 deletions samcli/commands/pipeline/bootstrap/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
"""
CLI command for "pipeline bootstrap", which sets up the require pipeline infrastructure resources
"""
import os
from textwrap import dedent
from typing import Any, Dict, List, Optional

import click

from samcli.cli.cli_config_file import configuration_option, TomlProvider
from samcli.cli.main import pass_context, common_options, aws_creds_options, print_cmdline_args
from samcli.lib.config.samconfig import SamConfig
from samcli.lib.pipeline.bootstrap.stage import Stage
from samcli.lib.telemetry.metric import track_command
from samcli.lib.utils.colors import Colored
from samcli.lib.utils.version_checker import check_newer_version
from .guided_context import GuidedContext
from ..external_links import CONFIG_AWS_CRED_ON_CICD_URL

SHORT_HELP = "Generates the necessary AWS resources to connect your CI/CD system."

HELP_TEXT = """
SAM Pipeline Bootstrap generates the necessary AWS resources to connect your
CI/CD system. This step must be completed for each pipeline stage prior to
running sam pipeline init
"""

PIPELINE_CONFIG_DIR = os.path.join(".aws-sam", "pipeline")
PIPELINE_CONFIG_FILENAME = "pipelineconfig.toml"


@click.command("bootstrap", short_help=SHORT_HELP, help=HELP_TEXT, context_settings=dict(max_content_width=120))
@configuration_option(provider=TomlProvider(section="parameters"))
@click.option(
"--interactive/--no-interactive",
is_flag=True,
default=True,
help="Disable interactive prompting for bootstrap parameters, and fail if any required arguments are missing.",
)
@click.option(
"--stage",
help="The name of the corresponding stage. It is used as a suffix for the created resources.",
required=False,
)
@click.option(
"--pipeline-user",
help="An IAM user generated or referenced by sam pipeline bootstrap in order to "
"allow the connected CI/CD system to connect to the SAM CLI.",
required=False,
)
@click.option(
"--pipeline-execution-role",
help="Execution role that the CI/CD system assumes in order to make changes to resources on your behalf.",
required=False,
)
@click.option(
"--cloudformation-execution-role",
help="Execution role that CloudFormation assumes in order to make changes to resources on your behalf",
required=False,
)
@click.option(
"--bucket",
help="The name of the S3 bucket where this command uploads your CloudFormation template. This is required for"
"deployments of templates sized greater than 51,200 bytes.",
required=False,
)
@click.option(
"--create-image-repository/--no-create-image-repository",
is_flag=True,
default=False,
help="If set to true and no ECR image repository is provided, this command will create an ECR image repository "
"to hold the container images of Lambda functions having an Image package type.",
)
@click.option(
"--image-repository",
help="ECR repo uri where this command uploads the image artifacts that are referenced in your template.",
required=False,
)
@click.option(
"--confirm-changeset/--no-confirm-changeset",
default=True,
is_flag=True,
help="Prompt to confirm if the resources is to be deployed by SAM CLI.",
)
@common_options
@aws_creds_options
@pass_context
@track_command
@check_newer_version
@print_cmdline_args
def cli(
ctx: Any,
interactive: bool,
stage: Optional[str],
pipeline_user: Optional[str],
pipeline_execution_role: Optional[str],
cloudformation_execution_role: Optional[str],
bucket: Optional[str],
create_image_repository: bool,
image_repository: Optional[str],
confirm_changeset: bool,
config_file: Optional[str],
config_env: Optional[str],
) -> None:
"""
`sam pipeline bootstrap` command entry point
"""
do_cli(
region=ctx.region,
profile=ctx.profile,
interactive=interactive,
stage_name=stage,
pipeline_user_arn=pipeline_user,
pipeline_execution_role_arn=pipeline_execution_role,
cloudformation_execution_role_arn=cloudformation_execution_role,
artifacts_bucket_arn=bucket,
create_image_repository=create_image_repository,
image_repository_arn=image_repository,
confirm_changeset=confirm_changeset,
config_file=config_env,
config_env=config_file,
) # pragma: no cover


def do_cli(
region: Optional[str],
profile: Optional[str],
interactive: bool,
stage_name: Optional[str],
pipeline_user_arn: Optional[str],
pipeline_execution_role_arn: Optional[str],
cloudformation_execution_role_arn: Optional[str],
artifacts_bucket_arn: Optional[str],
create_image_repository: bool,
image_repository_arn: Optional[str],
confirm_changeset: bool,
config_file: Optional[str],
config_env: Optional[str],
standalone: bool = True,
) -> None:
"""
implementation of `sam pipeline bootstrap` command
"""
if not pipeline_user_arn:
pipeline_user_arn = _load_saved_pipeline_user_arn()

if interactive:
if standalone:
click.echo(
dedent(
"""\

sam pipeline bootstrap generates the necessary AWS resources to connect a stage in
your CI/CD system. We will ask for [1] stage definition, [2] account details, and
[3] references to existing resources in order to bootstrap these pipeline
resources.
"""
),
)

guided_context = GuidedContext(
profile=profile,
stage_name=stage_name,
pipeline_user_arn=pipeline_user_arn,
pipeline_execution_role_arn=pipeline_execution_role_arn,
cloudformation_execution_role_arn=cloudformation_execution_role_arn,
artifacts_bucket_arn=artifacts_bucket_arn,
create_image_repository=create_image_repository,
image_repository_arn=image_repository_arn,
region=region,
)
guided_context.run()
stage_name = guided_context.stage_name
pipeline_user_arn = guided_context.pipeline_user_arn
pipeline_execution_role_arn = guided_context.pipeline_execution_role_arn
cloudformation_execution_role_arn = guided_context.cloudformation_execution_role_arn
artifacts_bucket_arn = guided_context.artifacts_bucket_arn
create_image_repository = guided_context.create_image_repository
image_repository_arn = guided_context.image_repository_arn
region = guided_context.region
profile = guided_context.profile

if not stage_name:
raise click.UsageError("Missing required parameter '--stage'")

environment: Stage = Stage(
name=stage_name,
aws_profile=profile,
aws_region=region,
pipeline_user_arn=pipeline_user_arn,
pipeline_execution_role_arn=pipeline_execution_role_arn,
cloudformation_execution_role_arn=cloudformation_execution_role_arn,
artifacts_bucket_arn=artifacts_bucket_arn,
create_image_repository=create_image_repository,
image_repository_arn=image_repository_arn,
)

bootstrapped: bool = environment.bootstrap(confirm_changeset=confirm_changeset)

if bootstrapped:
environment.print_resources_summary()

environment.save_config_safe(
config_dir=PIPELINE_CONFIG_DIR, filename=PIPELINE_CONFIG_FILENAME, cmd_names=_get_bootstrap_command_names()
)

click.secho(
dedent(
f"""\
View the definition in {os.path.join(PIPELINE_CONFIG_DIR, PIPELINE_CONFIG_FILENAME)},
run sam pipeline bootstrap to generate another set of resources, or proceed to
sam pipeline init to create your pipeline configuration file.
"""
)
)

if not environment.pipeline_user.is_user_provided:
click.secho(
dedent(
f"""\
Before running {Colored().bold("sam pipeline init")}, we recommend first setting up AWS credentials
in your CI/CD account. Read more about how to do so with your provider in
{CONFIG_AWS_CRED_ON_CICD_URL}.
"""
)
)


def _load_saved_pipeline_user_arn() -> Optional[str]:
samconfig: SamConfig = SamConfig(config_dir=PIPELINE_CONFIG_DIR, filename=PIPELINE_CONFIG_FILENAME)
if not samconfig.exists():
return None
config: Dict[str, str] = samconfig.get_all(cmd_names=_get_bootstrap_command_names(), section="parameters")
return config.get("pipeline_user")


def _get_bootstrap_command_names() -> List[str]:
return ["pipeline", "bootstrap"]
Loading