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

Allow Globals to be ignored by Functions and not applied. #1874

Closed
brysontyrrell opened this issue Dec 13, 2020 · 12 comments
Closed

Allow Globals to be ignored by Functions and not applied. #1874

brysontyrrell opened this issue Dec 13, 2020 · 12 comments

Comments

@brysontyrrell
Copy link
Contributor

Describe your idea/feature/enhancement

I'm experimenting with using the PackageType: Image option for Functions and came across this error when I attempted to deploy my test app:

Error: Failed to create changeset for the stack: *****, ex: Waiter ChangeSetCreateComplete failed: Waiter encountered a terminal failure state Status: FAILED. Reason: Transform AWS::Serverless-2016-10-31 failed with: Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [*****] is invalid. Runtime, Handler, Layers cannot be present when PackageType is of type `Image`

Example template:

AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31

Globals:

  Function:
    Runtime: python3.8
    Handler: index.lambda_handler
    MemorySize: 128

Resources:

  ZipFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: ./src/zip

  ImageFunction:
    Type: AWS::Serverless::Function
    Properties:
      PackageType: Image
    Metadata:
      Dockerfile: Dockerfile
      DockerContext: ./src/image

If I have a template of Zip and Image type Functions I can no longer use Globals because this error is thrown. I will have to define these properties on each Zip type individually.

Proposal

Either an addition to Globals or AWS::Serverless::Function that prevents globals from being applied to the resource(s).

Additional Details

SAM CLI, version 1.13.2

@brysontyrrell
Copy link
Contributor Author

Another thought on the proposal: is there a way to make it so function resources will ignore attributes in Globals that don't apply to their PackageType?

@jfuss
Copy link
Contributor

jfuss commented Dec 23, 2020

@brysontyrrell Globals is to define the same property across multiple Resources. All resources do not need or cannot have the same properties then you cannot use Globals. You will need to move the conflicting properties into the Resources.

I am not sure if this will work but values defined in the Resource will override the ones defined in the Globals section (at least for strings they will). So you might be able to set them to AWS::NoValue. I am not sure if Cloudformation will remove these properties before it gets sent to SAM, but might be worth a try if you really want to keep what you are doing.

Doing conditional things based upon properties can get very confusing for customers and be something very difficult to manage. Globals then become this conditionally applied block to sets of Resources and changes what Globals is.

I can understand the frustration but this is acting as designed.

@jfuss jfuss transferred this issue from aws/aws-sam-cli Dec 23, 2020
@jfuss jfuss added area/globals stage/needs-feedback Needs feedback from the community (are you also interested in/experiencing this?) labels Dec 23, 2020
@si3mshady
Copy link

SAM sucks

@sapessi
Copy link

sapessi commented Jun 15, 2021

SAM sucks

We'd love to try and change your mind. What can we change/fix to make SAM work for your use-case?

@BlissfulDarkness
Copy link

It feels like the core issue is actually how Globals is specified and applied to resources. Specifically, it's not possible to 'subtype' deep enough. Conceptually, the better solution is something like one of these for Globals:

Globals:
  Function:
    ZipPackageType:
      Runtime:
      Layers:
    ImagePackageType:
      ImageUri:

Globals:
  Function:
    Runtime:
    Layers:
  ImageFunction:
    ImageUri:

This is complicated mostly that there is no concept of Subtype with the Resources, but I think this is actually what the best solution would look like, especially the 2nd form. I think the SAM transform could correctly translate this SAM specific resource type (ImageFunction) into a valid CloudFormation resource, while also applying the 'Function' globals to standard CloudFormation Function resources at the same time.

@MarinaRappoport
Copy link

I faced the same issue. it would be great to have a possibility to ignore/except some Functions from using globals

@damogallagher
Copy link

Just faced this issue - it would be great to have a solution where the 1 template file could hold normal functions and the package type of image

@barkermn01
Copy link

barkermn01 commented Sep 10, 2022

No matter which way you look at this the globals is set up daft, here, either there should be a way to say override globals at a function, or globals as a whole need a better system off perhaps having support for baseSettings: BaseSettingsName

So Currently i use

Globals:
  Function:
    Timeout: 5
    MemorySize: 128
    Runtime: nodejs16.x
    Architectures:
      - "x86_64"
    Layers:
      - "{layer_arn}"
    Handler: index.handler
    VpcConfig:
      SecurityGroupIds: !Ref DefaultSecurityGroupParameter
      SubnetIds: !Ref DefaultSubnetsParameter

However, I now need to add an Image type function because it's been built by an AWS Partner, so the image package type complains because the globals are there (Layers, handler, and PackageType), so to fix this I then have to replicate all those lines for every function, (worst-case scenario) adding 11 lines times the number of functions using Zip package type in my case that is 44 functions, so an extra 484 lines.

Why not change this so that Globals can be there, or support for custom base settings, E.G

FunctionBaseSettings:
  SettingsTypeZipBaseSettings:
    Timeout: 5
    MemorySize: 128
    Runtime: nodejs16.x
    Architectures:
      - "x86_64"
    Layers:
      - "{layer_arn}"
    Handler: index.handler
    VpcConfig:
      SecurityGroupIds: !Ref DefaultSecurityGroupParameter
      SubnetIds: !Ref DefaultSubnetsParameter

then functions use them something like

GETrequestsMonitoredVisitor:
    Type: AWS::Serverless::Function
    BaseSettings: SettingsTypeZipBaseSettings
    Properties:
      Handler: {handler_name}
      CodeUri: {code_path}/
      Events:
        EndpointGetMonitor:
          Type: Api
          Properties:
            Path: {api_gateway_path}
            Method: {api_gaterway_method}
            RestApiId: !Ref API
    Metadata:
      DockerTag: nodejs16.x-v1
      DockerContext: ./{code_path}/

This would allow the developer to create multiple base settings as needed and select the correct one for each function.

I'm using {} to denote what should be present where I have removed specific to our codebase stuff,

@EnkhAmar
Copy link

Hi there,

I understand that you're experiencing an issue with AWS SAM where you would like to be able to ignore Globals for specific functions. From my understanding, Globals are currently applied to all functions defined in the AWS SAM template, which may not always be desired.

I think this is a valid use case and it would be great to have an option to selectively ignore Globals for certain functions. This could potentially be implemented by adding a new property to the function definition, such as "IgnoreGlobals" or something similar.

I'm not sure if there are any technical challenges that would make this difficult to implement, but I'm curious to hear the thoughts of the AWS SAM team on this.

Thanks for bringing this up and please let me know if there's anything else I can do to help.

@justinmclark
Copy link

justinmclark commented May 6, 2023

For what it's worth, I sort of got around this as long as Layers is not one of the Globals.

E.g., this stack deploys just fine:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Parameters:
  UrlParserImage:
    Type: String
    Description: The image to use for the url parser function

Globals:
  Function:
    Timeout: 30
    Runtime: python3.9
    Handler: index.handler


Resources:
  UrlParser:
    Type: AWS::Serverless::Function
    Properties:
      ImageUri: !Ref UrlParserImage

  TestImageFunction:
    Type: AWS::Serverless::Function
    Properties:
      PackageType: Image
      Runtime: null
      Handler: null
      ImageConfig:
        Command: ["test.lambda_handler"]
    Metadata:
      Dockerfile: Dockerfile
      DockerContext: ./test
      DockerTag: v1

However, I have a real production stack with Layers as one of the globals and I'm unable to deploy that stack.

@ssenchenko ssenchenko added type/feature and removed stage/needs-feedback Needs feedback from the community (are you also interested in/experiencing this?) maintainer/need-followup labels Aug 11, 2023
@GavinZZ GavinZZ self-assigned this Oct 18, 2023
@GavinZZ
Copy link
Contributor

GavinZZ commented Oct 25, 2023

Hi after team discussion, we will support introducing a new resource attribute called IgnoreGlobals.

IgnoreGlobals will accept a string input value of "*" or a list of string input values.

  1. When IgnoreGlobals: "*" is used as resource attribute of a specific resource, it means to ignore all Globals for this specific resource
  2. When a list of valid string input is used, it will ignore the matching properties in Globals.

Consider the example where I have a mix of PackageType: Image function and a PackageType: Zip function.

Globals:
  Function:
    Runtime: python3.8
    Handler: index.lambda_handler
    MemorySize: 128

Resources:
  ZipFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: s3://bucket/key

  ImageFunction:
    Type: AWS::Serverless::Function
    IgnoreGlobals: '*'
    Properties:
      PackageType: Image
      ImageUri: s3://bucket/key
    Metadata:
      Dockerfile: Dockerfile
      DockerContext: ./src/image

  ImageFunction2:
    Type: AWS::Serverless::Function
    IgnoreGlobals:
    - Runtime
    - Handler
    Properties:
      PackageType: Image
      ImageUri: s3://bucket/key
    Metadata:
      Dockerfile: Dockerfile
      DockerContext: ./src/image

Note that this feature is already merged, see #3386. It will take about 2~3 weeks to gradually roll out to all regions.

@GavinZZ
Copy link
Contributor

GavinZZ commented Oct 25, 2023

Marking this issue as completed.

@GavinZZ GavinZZ closed this as completed Oct 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests