Quentin Del
Quentin Del

Reputation: 1685

Template error: every Fn::GetAtt object requires two non-empty parameters, the resource name and the resource attribute

I am trying to deploy a CloudFormation template for two lambdas and an elastic IP.

I am not sure how to fix this error in my template: Fn::GetAtt object requires two non-empty parameters

Would you be able to give me some insights please ? What are some best practices to debug a CloudFormation template ?

AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: 
Parameters:
  PrivateSubnets:
    Type: AWS::SSM::Parameter::Value<List<AWS::EC2::Subnet::Id>>
    Default: /vpc/subnets/private-ids
  VpcId:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::VPC::Id>
    Default: /vpc/id
  LogLevel:
    Type: String
    AllowedValues:
    - debug
    - warn
    - info
    - error
    - critical
    Default: debug
  Xray:
    Type: String
    AllowedValues:
    - Active
    - PassThrough
    Default: Active
Globals:
  Function:
    AutoPublishAlias: live
    Runtime: nodejs10.x
    Tracing:
      Ref: Xray
    Environment:
      Variables:
        NODE_ENV: production
        LOG_LEVEL:
          Ref: LogLevel
        ALB_ENDPOINT:
          Fn::GetAtt:
          - LoadBalancer
          - DNSName
        SECRETS_ID:
          Ref: ServiceSecrets
Resources:
  ServiceSecrets:
    Type: AWS::SecretsManager::Secret
    Properties:
      KmsKeyId:
        Fn::ImportValue: kms-default-key-id
      Description:
        Ref: AWS::StackName
      SecretString: '{ "refresh_token": "abc", "id_token": "abc" }'
  LambdaPolicyCommon:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      Path: /
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Action:
          - secretsmanager:GetSecretValue
          Resource:
            Ref: ServiceSecrets
        - Effect: Allow
          Action:
          - kms:GenerateDataKey
          - kms:Decrypt
          Resource:
            Fn::ImportValue: kms-default-key-arn
  LambdaFunctionCronJob:
    Type: AWS::Serverless::Function
    Properties:
      ReservedConcurrentExecutions: 1
      CodeUri: s3://s3bucket-881
      Handler: index.handler
      Timeout: 60
      Policies:
      - Ref: LambdaPolicyCommon
      - Fn::ImportValue: iam-policy-lambda-common-arn
      VpcConfig:
        SubnetIds:
          Ref: PrivateSubnets
        SecurityGroupIds:
        - Ref: LoadBalancerSecurityGroup
      Events:
        Cron:
          Type: Schedule
          Properties:
            Schedule: rate(1 minute)
  LambdaFunctionProxy:
    Type: AWS::Serverless::Function
    Properties:
      ReservedConcurrentExecutions: 1
      CodeUri: s3://cicd-buildartifactsbucket-3d345d2c
      Handler: index.handler
      Timeout: 60
      Policies:
      - Ref: LambdaPolicyCommon
      - Fn::ImportValue: iam-policy-lambda-common-arn
  LoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Scheme: internal
      Subnets:
        Ref: PrivateSubnets
      SecurityGroups:
      - Ref: LoadBalancerSecurityGroup
  TargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    DependsOn: AlbLambdaFunctionInvokePermission
    Properties:
      TargetType: lambda
      Targets:
      - Id:
          Fn::GetAtt:
          - LambdaFunctionCronJob
          - Alias
  HttpListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
      - TargetGroupArn:
          Ref: TargetGroup
        Type: forward
      LoadBalancerArn:
        Ref: LoadBalancer
      Port: 80
      Protocol: HTTP
  LoadBalancerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: group description
      VpcId:
        Ref: VpcId
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 80
        ToPort: 80
        CidrIp: 0.0.0.0/0
  AlbLambdaFunctionInvokePermission:
    Type: AWS::Lambda::Permission
    Properties:
      FunctionName:
        Fn::GetAtt:
        - LambdaFunctionProxy
        - Alias
      Action: lambda:InvokeFunction
      Principal: elasticloadbalancing.amazonaws.com

Upvotes: 1

Views: 2089

Answers (3)

Quentin Del
Quentin Del

Reputation: 1685

From AWS Support

For serverless function alias can be referenced as "Ref": "MyLambdaFunction.Alias"

Since for serverless function cloudformation does not accept the format logical name, attribute name it is finding ''alias" attribute as empty and it does not resolve it It will need to be mentionned like this:

Properties:
FunctionName: !Ref LambdaFunctionProxyToHc.Alias

Upvotes: 1

Assael Azran
Assael Azran

Reputation: 2993

Try to change:

Fn::GetAtt:
- LambdaFunctionProxy
- Alias

To:

Fn::GetAtt:
    - "LambdaFunctionProxy"
    - "Alias"

Upvotes: 4

rtruszk
rtruszk

Reputation: 3922

You should either use full function name:

Fn::GetAtt: [ LoadBalancer, DNSName ]

or short form:

!GetAtt LoadBalancer.DNSName

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html

Upvotes: 1

Related Questions