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

sam local doesn't support AWS::Region and AWS::AccountId in the template #4208

Open HAK-CODE opened 2 years ago

HAK-CODE commented 2 years ago

Environment

Detail Description I have a python SAM application which template is defined here

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  api-data-services

  Sample SAM Template for api-data-services

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 10
    VpcConfig:
      SecurityGroupIds:
        - sg-af1ac2dc
      SubnetIds:
        - subnet-04612348
        - subnet-4e329f25
    Layers:
      - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPython:29
      - !Sub arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:layer:common-layer:90
    Environment:
      Variables:
        EC_ENDPOINT: '{{resolve:ssm:/prod/cache/writerendpoint:1}}'
        EC_PORT: '{{resolve:ssm:/prod/cache/writerport:1}}'
        EC_READER_ENDPOINT: '{{resolve:ssm:/prod/cache/readerendpoint:1}}'
        EC_READER_PORT: '{{resolve:ssm:/prod/cache/readerport:1}}'
        AWS_ACCOUNT: !Sub '${AWS::AccountId}'
    Tags:
      author: HAK
      env: prod
      type: api
      purpose: data services

Resources:
  TimeseriesServiceData:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      Description: Get timeseries data from different sources
      FunctionName: api-data-services-timeseries
      CodeUri: src
      Handler: data.main.lambda_handler
      Runtime: python3.9
      Architectures:
        - arm64
      MemorySize: 128
      ReservedConcurrentExecutions: 5
      Environment:
        Variables:
          LOG_LEVEL: DEBUG
          POWERTOOLS_SERVICE_NAME: timeseries-data
          POWERTOOLS_LOGGER_LOG_EVENT: false
      Policies:
        - AWSSecretsManagerGetSecretValuePolicy:
            SecretArn: !Sub arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:prod/es/credentials-nPmxsV

  TimeseriesServiceDataLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub '/aws/lambda/${TimeseriesServiceData}'
      RetentionInDays: 7

Outputs:
  TimeseriesServiceData:
    Description: Timeseries Data function name
    Value: !Ref TimeseriesServiceData

It is deployed and running on cloud but I wanted to test it locally for which i use this command

sam local invoke TimeseriesServiceData --profile default --debug

Default profile is set with AWS Admin access but when I run this I get this

2022-09-08 16:22:29,364 | Telemetry endpoint configured to be https://aws-serverless-tools-telemetry.us-west-2.amazonaws.com/metrics
2022-09-08 16:22:29,364 | Using config file: samconfig.toml, config environment: default
2022-09-08 16:22:29,364 | Expand command line arguments to:
2022-09-08 16:22:29,364 | --template_file=/Users/hak/Desktop/iot-core-services/api-data-services/.aws-sam/build/template.yaml --function_logical_id=TimeseriesServiceData --no_event --layer_cache_basedir=/Users/hak/.aws-sam/layers-pkg --container_host=localhost --container_host_interface=127.0.0.1 
2022-09-08 16:22:29,364 | local invoke command is called
2022-09-08 16:22:29,368 | No Parameters detected in the template
2022-09-08 16:22:29,375 | Sam customer defined id is more priority than other IDs. Customer defined id for resource TimeseriesServiceData is TimeseriesServiceData
2022-09-08 16:22:29,375 | There is no customer defined id or cdk path defined for resource TimeseriesServiceDataLogGroup, so we will use the resource logical id as the resource id
2022-09-08 16:22:29,376 | 0 stacks found in the template
2022-09-08 16:22:29,376 | No Parameters detected in the template
2022-09-08 16:22:29,381 | Sam customer defined id is more priority than other IDs. Customer defined id for resource TimeseriesServiceData is TimeseriesServiceData
2022-09-08 16:22:29,381 | There is no customer defined id or cdk path defined for resource TimeseriesServiceDataLogGroup, so we will use the resource logical id as the resource id
2022-09-08 16:22:29,382 | 2 resources found in the stack 
2022-09-08 16:22:29,382 | Found Serverless function with name='TimeseriesServiceData' and CodeUri='TimeseriesServiceData'
2022-09-08 16:22:29,382 | --base-dir is not presented, adjusting uri TimeseriesServiceData relative to /Users/hak/Desktop/iot-core-services/api-data-services/.aws-sam/build/template.yaml
2022-09-08 16:22:29,393 | Found one Lambda function with name 'TimeseriesServiceData'
2022-09-08 16:22:29,393 | Invoking data.main.lambda_handler (python3.9)
2022-09-08 16:22:29,393 | Environment variables overrides data is standard format
2022-09-08 16:22:29,393 | Loading AWS credentials from session with profile 'default'
2022-09-08 16:22:29,399 | Resolving code path. Cwd=/Users/hak/Desktop/iot-core-services/api-data-services/.aws-sam/build, CodeUri=/Users/hak/Desktop/iot-core-services/api-data-services/.aws-sam/build/TimeseriesServiceData
2022-09-08 16:22:29,399 | Resolved absolute path to code is /Users/hak/Desktop/iot-core-services/api-data-services/.aws-sam/build/TimeseriesServiceData
2022-09-08 16:22:29,399 | Code /Users/hak/Desktop/iot-core-services/api-data-services/.aws-sam/build/TimeseriesServiceData is not a zip/jar file
2022-09-08 16:22:29,399 | arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPython:29 is already cached. Skipping download
2022-09-08 16:22:30,738 | Cleaning all decompressed code dirs
2022-09-08 16:22:30,739 | Sending Telemetry: {'metrics': [{'commandRun': {'requestId': '65564733-8a86-47dd-ae09-1f3c1d26e7ce', 'installationId': '8fb6ad5c-cfab-4e06-9306-366069d6f5a9', 'sessionId': '794baa4d-2fd4-4fab-a0b9-67fe1c5c14eb', 'executionEnvironment': 'CLI', 'ci': False, 'pyversion': '3.8.13', 'samcliVersion': '1.54.0', 'awsProfileProvided': True, 'debugFlagProvided': True, 'region': '', 'commandName': 'sam local invoke', 'metricSpecificAttributes': {'projectType': 'CFN'}, 'duration': 1374, 'exitReason': 'InvalidParameterValueException', 'exitCode': 255}}]}
2022-09-08 16:22:31,974 | HTTPSConnectionPool(host='aws-serverless-tools-telemetry.us-west-2.amazonaws.com', port=443): Read timed out. (read timeout=0.1)
Traceback (most recent call last):
  File "/opt/homebrew/bin/sam", line 8, in <module>
    sys.exit(cli())
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/click/decorators.py", line 73, in new_func
    return ctx.invoke(f, obj, *args, **kwargs)
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/samcli/lib/telemetry/metric.py", line 166, in wrapped
    raise exception  # pylint: disable=raising-bad-type
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/samcli/lib/telemetry/metric.py", line 124, in wrapped
    return_value = func(*args, **kwargs)
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/samcli/lib/utils/version_checker.py", line 41, in wrapped
    actual_result = func(*args, **kwargs)
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/samcli/cli/main.py", line 87, in wrapper
    return func(*args, **kwargs)
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/samcli/commands/local/invoke/cli.py", line 85, in cli
    do_cli(
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/samcli/commands/local/invoke/cli.py", line 182, in do_cli
    context.local_lambda_runner.invoke(
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/samcli/commands/local/lib/local_lambda.py", line 137, in invoke
    self.local_runtime.invoke(
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/samcli/lib/telemetry/metric.py", line 230, in wrapped_func
    return_value = func(*args, **kwargs)
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/samcli/local/lambdafn/runtime.py", line 177, in invoke
    container = self.create(function_config, debug_context, container_host, container_host_interface)
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/samcli/local/lambdafn/runtime.py", line 73, in create
    container = LambdaContainer(
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/samcli/local/docker/lambda_container.py", line 93, in __init__
    image = LambdaContainer._get_image(
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/samcli/local/docker/lambda_container.py", line 236, in _get_image
    return lambda_image.build(runtime, packagetype, image, layers, architecture, function_name=function_name)
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/samcli/local/docker/lambda_image.py", line 136, in build
    downloaded_layers = self.layer_downloader.download_all(layers, self.force_image_build)
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/samcli/local/layers/layer_downloader.py", line 77, in download_all
    layer_dirs.append(self.download(layer, force))
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/samcli/local/layers/layer_downloader.py", line 111, in download
    layer_zip_uri = self._fetch_layer_uri(layer)
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/samcli/local/layers/layer_downloader.py", line 160, in _fetch_layer_uri
    raise e
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/samcli/local/layers/layer_downloader.py", line 141, in _fetch_layer_uri
    layer_version_response = self.lambda_client.get_layer_version(
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/botocore/client.py", line 508, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/opt/homebrew/Cellar/aws-sam-cli/1.54.0/libexec/lib/python3.8/site-packages/botocore/client.py", line 915, in _make_api_call
    raise error_class(parsed_response, operation_name)
botocore.errorfactory.InvalidParameterValueException: An error occurred (InvalidParameterValueException) when calling the GetLayerVersion operation: Invalid Layer name: arn:aws:lambda:us-east-1:123456789012:layer:common-layer

One this to notice is arn:aws:lambda:us-east-1:123456789012:layer:common-layer though my aws profile and config point to us-east-2 and account also dummy then I tried to hard code this (btw this layer is already deployed on cloud) but still no success, am I making any mistake can we overwrite psedu-parameters like ${AWS::AccountId}.

mndeveci commented 2 years ago

Thanks for raising this issue @HAK-CODE

I do confirm this behavior locally that SAM CLI don't resolve AWS::Region and AWS::AccountId correctly. It is using some pre-defined fields in here.

You can set the correct region by setting AWS_REGION environment variable, but there is no way to do same thing with AccountId.

I will tag this as feature request and will be prioritized later. In the mean time, I can recommend using sam sync to test your lambda functions in the cloud. Since it will be deployed, these parameters should be resolved and you shouldn't face this issue. Any feedback about sam sync is greatly appreciated.

Thanks!

HAK-CODE commented 2 years ago

Hi @mndeveci , Thanks for you response, could you please check and confirm as i set AWS_REGION in my environment variable as us-east-2 but still it set as us-east-1

botocore.errorfactory.InvalidParameterValueException: An error occurred (InvalidParameterValueException) when calling the GetLayerVersion operation: Invalid Layer name: arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPython

Command stopped: "sam local invoke"
2022-09-10 11:34:26 [ERROR]: Failed to run SAM application locally: "sam local invoke" command stopped (error code: 1)
adam-brewer-meshii commented 1 year ago

For what it's worth, I'm also getting this issue. Specifically I'm trying to invoke one lambda from another using sam local invoke but getting the same error:

User: arn:aws:iam::[ACCOUNT_ID]:user/[USERNAME] is not authorized to perform: lambda:InvokeFunction on resource: arn:aws:lambda:eu-west-2:123456789012:function:meshii-mine-token because no resource-based policy allows the lambda:InvokeFunction action.

Defining a policy in template.yml with wildcards for actions and resources has no affect. Even grating a policy/role to my default user with the correct permissions has no affect.

I'm assuming it's an issue with the assigned default account ID when using local invoke – it doesn't seem like changing 123456789012 to anything else is possible..

vaunus commented 8 months ago

Have seen a similar issue in sam build when building a lambda container. The SAM template has AWS::AccountId inside it which I am passing to docker as an argument as need it in the Dockerfile. Always get 123456789012 even when --profile is set.

cscetbon commented 8 months ago

What I've noticed is that you need to use !Sub when you use such variables, so instead of using

AcmCertificateArn: arn:aws:acm:${AWS::Region}:${AWS::AccountId}:certificate/11cc0ad5-02f2-33da-9e73-a4a64dd350c9

You need to use

AcmCertificateArn: !Sub arn:aws:acm:${AWS::Region}:${AWS::AccountId}:certificate/11cc0ad5-02f2-33da-9e73-a4a64dd350c9
vaunus commented 8 months ago

Thanks, Sub works on a deploy but not on a build

enyawtsivad commented 8 months ago

I am trying sam local invoke with terraform. Neither adding "--region=us-west-2", nor "export AWS_REGION=us-west-2" made any difference in the outcome.
I still get: Error: An error occurred (InvalidParameterValueException) when calling the GetLayerVersion operation: Invalid Layer name: arn:aws:lambda: The configuration contains version numbers. The error output does not.

davetbo-amzn commented 6 months ago

I'm getting a similar error, but it's due to having Lambda Insights turned on, apparently. Error: An error occurred (InvalidParameterValueException) when calling the GetLayerVersion operation: Invalid Layer name: arn:aws:lambda:us-east-1:580247275435:layer:LambdaInsightsExtension

I'm actually running this stack in us-west-2, but this region and account number seem to be coming from enabling Lambda Insights, so I'm guessing that's an AWS internal account/region deployment thing.

I confirmed the insights setting is the culprit. If I comment out this line in my Lambda CDK construct, the sam local invoke works.

insightsversion=lambda.LambdaInsightsVersion.VERSION_1_0_229_0,

Is there any advice for using SAM local invoke with Lambda insights enabled? I suppose turning it off for dev is not the end of the world, but it would be nice to not have this setting be compatible with local testing.