Skip to content

Syntax Errors in Policy - ManagedPolicy

0

Hello, I am trying to deploy a Yaml script which has got a Policy deployment but it is failing with below error:

UsagePlanReminderLambdaPolicy [UPDATE_FAILED]: Resource handler returned message: "Syntax errors in policy. (Service: Iam, Status Code: 400, Request ID: ac93419a-875e-4fd9-bb6c-0f8ef937e09d)" (RequestToken: 963ca8c9-659f-406c-d707-7daa402e38b1, HandlerErrorCode: InvalidRequest) Below is the script which I am deploying-

UsagePlanReminderLambdaPolicy:
  Type: 'AWS::IAM::ManagedPolicy'
  Properties:
    PolicyDocument:
      Version: 2012-10-17
      Statement:
        - Action: 'apigateway:GET'
          Resource: '*'
          Effect: Allow
          Sid: VisualEditor0
        - Action: 'sns:Publish'
          Resource: 
            - Ref: UsagePlanReminderTopic
          Effect: Allow
          Sid: VisualEditor1
        - Action:
            - 'dynamodb:PutItem'
            - 'dynamodb:GetItem'
          Resource: '*'
          Effect: Allow
          Sid: VisualEditor2
    Description: Policy for Lambda
    Path: /

I tried to surround "Version" with single/double quotes but then it gives invalid version. So Version is not an issue. Tried several syntax for Resource: -Ref UsagePlanReminderTopic but no luck.

Not sure where the syntax error is.

Full Master Template--

AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Parameters:
  Environment:
    Type: String
    Description: The environment type value

  S3DeploymentBucket:
    Type: String
    Description: Bucket code is deployed to
  TargetNetworkStack:
    Type: String
    Description: Stack name of the standard network version.
  SupportEmailAddress:
    Type: String
    Description: Email address to send usage plan alert to
  OrganisationId:
    Type: String
  ReminderCodeBase:
    Type: String
    Description: Location of the code zip file
  ApiUsageQuotaLimit:
    Description: Usage quota limit of CUL APis per month
    Type: Number
    Default: 100000
  CheckFrequencyInMinutes:
    Type: Number
    Description: The frequency to check if the usage plan quota has been exceeded a defined Threshold.
    Default: 5
  ThresholdLowPercent:
    Type: Number
    Description: The first Threshold which should be checked if exceeded or not.
    Default: 50
  ThresholdMediumPercent:
    Type: Number
    Description: The second Threshold which should be checked if exceeded or not.
    Default: 80
  ThresholdHighPercent:
    Type: Number
    Description: The third Threshold which should be checked if exceeded or not.
    Default: 100
  RunbookLink:
    Type: String
    Description: The link address of the runbook.
  UsgPlanReminderResS3Location:
    Type: String

Description: >-
  An AWS Serverless Application for deploying a loan account API to Amazon Lambda.

Resources:

  DaDomainBasePathMapping:
    Type: AWS::ApiGateway::BasePathMapping
    Condition: EnableDa
    Properties: 
      BasePath: "account"
      DomainName: !Ref DAapiDomainName
      RestApiId: !Ref LoanAccountApi
      Stage: !Ref LoanAccountApiStage

  'Fn::Transform':
    Name: 'AWS::Include'
    Parameters:
      Location: 
        Ref: UsgPlanReminderResS3Location
      SupportEmailAddress: 
        Ref: SupportEmailAddress
      S3DeploymentBucket: 
        Ref: S3DeploymentBucket
      Environment: 
        Ref: Environment
      OrganisationId: 
        Ref: OrganisationId
      ReminderCodeBase: 
        Ref: ReminderCodeBase
      ApiUsageQuotaLimit: 
        Ref: ApiUsageQuotaLimit
      CheckFrequencyInMinutes: 
        Ref: CheckFrequencyInMinutes
      ThresholdLowPercent: 
        Ref: ThresholdLowPercent
      ThresholdMediumPercent: 
        Ref: ThresholdMediumPercent
      ThresholdHighPercent: 
        Ref: ThresholdHighPercent
      RunbookLink: 
        Ref: RunbookLink
      TargetNetworkStack: 
        Ref: TargetNetworkStack
          
Outputs:
  ApiId:
   Value: !Ref LoanAccountApi
  
  Stage:
   Value: !Ref LoanAccountApiStage
   
  ApiUsagePlan:
    Value: !Ref LoanAccountApiUsagePlan
    Description: Loan Account Api Usage Plan

Include Template-

Thanks

UsagePlanReminderTopic:
  Type: 'AWS::SNS::Topic'

UsagePlanReminderSubscription:
  Type: 'AWS::SNS::Subscription'
  Properties:
    Protocol: email
    Endpoint:
      Ref: SupportEmailAddress
    TopicArn:
      Ref: UsagePlanReminderTopic

UsagePlanReminderLambdaSecurityGroup:
  Type: 'AWS::EC2::SecurityGroup'
  Properties:
    GroupName:
      Fn::Sub: '${AWS::StackName}-UsagePlanReminderSecurityGroup'
    GroupDescription: Allow all outbound traffic for a lambda function
    VpcId:
      Fn::ImportValue:
        Fn::Sub: '${TargetNetworkStack}-AppsVpcId'
    SecurityGroupEgress:
      - IpProtocol: -1
        FromPort: 0
        ToPort: 65535
        CidrIp: 0.0.0.0/0
        Description: Allow all outbound ipv4 access
      - IpProtocol: -1
        FromPort: 0
        ToPort: 65535
        CidrIpv6: '::/0'
        Description: Allow all outbound ipv6 access

UsagePlanReminderFunction:
  Type: 'AWS::Lambda::Function'
  Properties:
    VpcConfig:
      SecurityGroupIds:
        Ref: UsagePlanReminderLambdaSecurityGroup
      SubnetIds:
        Fn::Split:
          - ','
          - Fn::ImportValue:
              Fn::Sub: '${TargetNetworkStack}-AppsPrivateSubnetIds'
    MemorySize: 1024
    Environment:
      Variables:
        VersionStage: AWSCURRENT
        Region:
          Ref: 'AWS::Region'
        Environment:
          Ref: Stage
        OrganisationId:
          Ref: OrganisationId
        RunbookLink:
          Ref: RunbookLink
        ApiUsageQuotaLimit:
          Ref: ApiUsageQuotaLimit
        UsagePlanReminderTopic:
          Ref: UsagePlanReminderTopic
        ThresholdLowPercent:
          Ref: ThresholdLowPercent
        ThresholdMediumPercent:
          Ref: ThresholdMediumPercent
        ThresholdHighPercent:
          Ref: ThresholdHighPercent
        UsageReminderHistoryTable:
          Ref: UsageReminderHistoryTable
        AWS_LAMBDA_HANDLER_LOG_FORMAT: Unformatted
    Handler: >-
      UsagePlanNotification::UsagePlanNotification.LambdaEntryPoint::FunctionHandler
    Role:
      Fn::GetAtt:
        - UsagePlanReminderLambdaRole
        - Arn
    Timeout: 29
    Runtime: dotnet8
    Code:
      S3Bucket:
        Ref: S3DeploymentBucket
      S3Key:
        Ref: ReminderCodeBase

UsagePlanReminderLambdaRole:
  Type: 'AWS::IAM::Role'
  Properties:
    AssumeRolePolicyDocument:
      Version: 2012-10-17T00:00:00.000Z
      Statement:
        - Action:
            - 'sts:AssumeRole'
          Effect: Allow
          Principal:
            Service:
              - lambda.amazonaws.com
    ManagedPolicyArns:
      - 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
      - 'arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole'
      - Ref: UsagePlanReminderLambdaPolicy
  
UsagePlanReminderLambdaPolicy:
  Type: 'AWS::IAM::ManagedPolicy'
  Properties:
    PolicyDocument:
      Version: 2012-10-17
      Statement:
        - Action: 'apigateway:GET'
          Resource: '*'
          Effect: Allow
          Sid: VisualEditor0
        - Action: 'sns:Publish'
          Resource:
           Fn::GetAtt:
            - UsagePlanReminderTopic
            - Arn
          Effect: Allow
          Sid: VisualEditor1
        - Action:
            - 'dynamodb:PutItem'
            - 'dynamodb:GetItem'
          Resource: '*'
          Effect: Allow
          Sid: VisualEditor2
    Description: Policy for Lambda
    Path: /

UsagePlanReminderScheduledRule:
  Type: 'AWS::Events::Rule'
  Properties:
    State: ENABLED
    ScheduleExpression:
      Fn::Sub: 'rate(${CheckFrequencyInMinutes} minutes)'
    Description: Scheduled rule to run on the start of each day.
    EventBusName: default
    Targets:
      - Id: TargetReminderFunctionV1
        Arn:
          Fn::GetAtt:
            - UsagePlanReminderFunction
            - Arn

PermissionForUsageReminderEventToInvokeLambda:
  Type: 'AWS::Lambda::Permission'
  Properties:
    Action: 'lambda:InvokeFunction'
    FunctionName:
      Ref: UsagePlanReminderFunction
    SourceArn:
      Fn::GetAtt:
        - UsagePlanReminderScheduledRule
        - Arn
    Principal: events.amazonaws.com

UsageReminderHistoryTable:
  Type: 'AWS::DynamoDB::Table'
  Properties:
    AttributeDefinitions:
      - AttributeName: Quota
        AttributeType: S
      - AttributeName: YearMonthPercent
        AttributeType: S
    BillingMode: PAY_PER_REQUEST
    KeySchema:
      - AttributeName: Quota
        KeyType: HASH
      - AttributeName: YearMonthPercent
        KeyType: RANGE

2 Answers
0

Hello.

Can't you get the ARN even if you do the following?

          Resource: 
            - !Ref UsagePlanReminderTopic
EXPERT

answered 2 years ago

  • I tried deploying the CloudFormation template below in my AWS account and it was successfully deployed.

    AWSTemplateFormatVersion: "2010-09-09"
    Description: test
    
    Resources:
      UsagePlanReminderTopic:
        Type: AWS::SNS::Topic
        Properties:
          FifoTopic: false
          TopicName: !Sub usageplanremindertopic
    
      UsagePlanReminderLambdaPolicy:
        Type: 'AWS::IAM::ManagedPolicy'
        Properties:
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Action: 'apigateway:GET'
                Resource: '*'
                Effect: Allow
                Sid: VisualEditor0
              - Action: 'sns:Publish'
                Resource: 
                  - !Ref UsagePlanReminderTopic
                Effect: Allow
                Sid: VisualEditor1
              - Action:
                  - 'dynamodb:PutItem'
                  - 'dynamodb:GetItem'
                Resource: '*'
                Effect: Allow
                Sid: VisualEditor2
          Description: Policy for Lambda
          Path: /
    
  • I am using this template as part of AWS:Include and accordingly I need to use full function name and short hands like !Ref. I have updated my question with full master as well as Include template

  • In the case of "Fn::GetAtt", "TopicArn" is for getting the ARN. In other words, I think you need to do something like this: https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-sns-topic.html#aws-resource-sns-topic-return-values

            - Action: 'sns:Publish'
              Resource:
               - Fn::GetAtt:
                - UsagePlanReminderTopic
                - TopicArn
              Effect: Allow
              Sid: VisualEditor1
    
0

The syntax error in your policy is likely due to the way you've specified the Resource for the SNS Publish action. In IAM policies, when referencing another resource using Ref, you need to use the Fn::GetAtt or !GetAtt intrinsic function to get the ARN of the resource. Here's the corrected version of your policy:

UsagePlanReminderLambdaPolicy:
  Type: 'AWS::IAM::ManagedPolicy'
  Properties:
    PolicyDocument:
      Version: '2012-10-17'
      Statement:
        - Action: 'apigateway:GET'
          Resource: '*'
          Effect: Allow
          Sid: VisualEditor0
        - Action: 'sns:Publish'
          Resource: 
            - !GetAtt UsagePlanReminderTopic.Arn
          Effect: Allow
          Sid: VisualEditor1
        - Action:
            - 'dynamodb:PutItem'
            - 'dynamodb:GetItem'
          Resource: '*'
          Effect: Allow
          Sid: VisualEditor2
    Description: Policy for Lambda
    Path: '/'

The main change is in the Resource field for the SNS Publish action. Instead of using Ref, use !GetAtt UsagePlanReminderTopic.Arn to get the ARN of the SNS topic.

Also, it's a good practice to enclose the Version in quotes ('2012-10-17') to ensure it's treated as a string.

For the Path property, I've added quotes around the '/' to make sure it's treated as a string.

These changes should resolve the syntax error in your policy. If you're still encountering issues, double-check that UsagePlanReminderTopic is correctly defined elsewhere in your template.
Sources
Troubleshoot IAM policies - AWS Identity and Access Management
Resolve IAM permission errors in CloudFormation | AWS re:Post

answered 2 years ago

  • As per auto suggestion I tried putting below but it says "Requested attribute Arn does not exist in schema for AWS::SNS::Topic" but the topic is present. Resource: Fn::GetAtt: - UsagePlanReminderTopic - Arn

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.