aws / aws-sam-cli

CLI tool to build, test, debug, and deploy Serverless applications using AWS SAM
https://aws.amazon.com/serverless/sam/
Apache License 2.0
6.51k stars 1.17k forks source link

Nested Stacks #2197

Open AgentGoldPaw opened 4 years ago

AgentGoldPaw commented 4 years ago

Describe your idea/feature/enhancement

I wish SAM CLI would allow !Sub on a Serverless::Function.Layers.

I use nested stacks pretty heavily and I am trying to use a global layer described in the master template and pass the ARN to a nested stack and then attach to a function.

Proposal

https://github.com/aws/aws-sam-cli/blob/develop/samcli/lib/providers/sam_function_provider.py#L271

Can add code right here, at least I think. I attempted to figure out as much as I could. As far as a full proposal, I will look at how !Sub is handled in other places.

AgentGoldPaw commented 4 years ago

I looked into it, I would love to learn more about the inner workings and contribute. However I am having trouble figuring out some basics.

mndeveci commented 4 years ago

Hi @th3g3ntl3men , can you explain your feature request in a little bit detail, giving some examples with it?

AgentGoldPaw commented 4 years ago

template A:

AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Resources:
  layercto:
    Type: AWS::Serverless::LayerVersion
    Properties:
      Description: !Sub
        - Stack ${StackTagName} Environment ${EnvironmentTagName} Layer ${ResourceName}
        - ResourceName: layer
      ContentUri: src/layer
      RetentionPolicy: Delete
      CompatibleRuntimes:
        - nodejs12.x
    Metadata:
      BuildMethod: nodejs12.x
  Stack:
    Type: AWS::Serverless::Application
    Properties:
      Location: ./templateB.yaml
      Parameters:
           Layer: !Ref Layer

template b:

AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Resources:
  createCustomer:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub ${AWS::StackName}-createCustomer
      Description: !Sub
        - Stack ${StackTagName} Environment ${EnvironmentTagName} Function ${ResourceName}
        - ResourceName: Function
      CodeUri: src/Function
      Handler: index.handler
      Runtime: nodejs12.x
      MemorySize: 3008
      Timeout: 30
      Tracing: Active
      Policies:
        - AWSXrayWriteOnlyAccess
      Layers:
        - !Sub ${Layer}
Parameters: 
Layer:
    Type: String
    Description: Log destination for apis.

Template B breaks because the code assumes that if the layer is a string that is a ARN. The value that gets passed is Layer.

Basically I would like my layer managed by my root stack, but be able to share the ARN dynamically using !Ref and passing as a parameter to nested stacks and using !Sub to reference the value.

Does that make sense @mndeveci ?

AgentGoldPaw commented 4 years ago

@mndeveci just pinging you so this doesn't go stale. Does the above provide more clarity on what I am hoping to do?

awsjeffg commented 4 years ago

@mndeveci is this a duplicate of #1213 ?

AgentGoldPaw commented 4 years ago

@awsjeffg it doesn't look like it at initial glance, he is talking about the URL of nested template, and how the templates are handled separately. This is focused on the parsing and handling of a AWS::Serverless::Function Layer property and how the cli only allows a ARN string and a !Ref to a layer definition.

mndeveci commented 4 years ago

@awsjeffg looks like it is.

@th3g3ntl3men AWS SAM CLI doesn't build nested stacks recursively. Instead you need to provide template location from the build directory for child stacks. I think what happens with your example is that, your parameter is not passed into the second template, therefore it is generating this error message.

In order to use nested stacks, you need to have a child stack, which is buildable by itself. After building all the child stacks, you need to refer them like this folder/to/child/stack/.aws-sam/template.yaml from the root stack. And then you can build and/or deploy root stack.

AgentGoldPaw commented 4 years ago

@mndeveci I use a tool called Stackery that manages the packaging and building of the templates correctly using AWS-SAM-CLI.

The issue isn't with building of template.

  Layers:
        - !Sub ${Layer}

it's specifically the line above. This does not build because aws-sam-cli doesn't allow a !Sub in layers. I am wanting to expand the functionality to allow it.

tivaliy commented 3 years ago

Any workarounds besides using --parameter-overrides during building...

aahung commented 3 years ago

Building resources in nested stack is enabled by default in #2662 so parameter overrides of child stacks will passed from parent stacks automatically. To be released

aahung commented 3 years ago

released in v1.20.0

aahung commented 3 years ago

2724

KoriSeng commented 3 years ago

@aahung not sure if this is related.

SAM CLI, version 1.22.0

Building a nested stack that defines a Docker image works as expected. But i have issue when trying to deploy. I think i am supposed to declare image_repositories. I tried adding ImageUri to the nested template.yaml and adding image_repositories in samconfig.toml, not sure how to reference a nested function.

In none nested, image_repositories=["Function1:URI","Function2:URI"]

what about nested applications? I tested below, but didnt work. sam deploy -g also does not list out the image repository. image_repositories =["Nested.Function1:URI"]

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\samcli\lib\package\packageable_resources.py", line 223, in export
    self.do_export(resource_id, resource_dict, parent_dir)
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\samcli\lib\package\packageable_resources.py", line 236, in do_export
    uploaded_url = upload_local_image_artifacts(
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\samcli\lib\package\utils.py", line 84, in upload_local_image_artifacts
    return uploader.upload(image_path, resource_id)
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\samcli\lib\package\ecr_uploader.py", line 82, in upload
    raise DockerPushFailedError(msg=str(ex)) from ex
samcli.commands.package.exceptions.DockerPushFailedError: 500 Server Error: Internal Server Error ("invalid reference format")
2021-04-09 11:56:17,877 | Unable to export
Traceback (most recent call last):
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\docker\api\client.py", line 261, in _raise_for_status
    response.raise_for_status()
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\requests\models.py", line 941, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 500 Server Error: Internal Server Error for url: http+docker://localnpipe/v1.35/images/....
Error: Unable to upload artifact Nested\template.yaml referenced by Location parameter of Nested resource.
Unable to upload artifact function:latest referenced by ImageUri parameter of Function resource.
500 Server Error: Internal Server Error ("invalid reference format")