Giter VIP home page Giter VIP logo

Comments (8)

ssenchenko avatar ssenchenko commented on May 27, 2024 1

I took your both code snippets and put together in a template less the API part on the function, because it doesn't mater for this issue.

Transform: AWS::Serverless-2016-10-31

Resources:
  MyFunc:
    Type: AWS::Serverless::Function
    Properties:
        InlineCode: >
            exports.handler = async (event) => {\
                return {
                    statusCode: 200,
                    body: JSON.stringify({ message: 'Hello, SAM!' }),\
                };
            };
        Handler: index.handler
        Runtime: n
        MemorySize: 1024
        Timeout: 99
        Policies:
            - CloudWatchLambdaInsightsExecutionRolePolicy
            - S3CrudPolicy:
                BucketName: 'my-bucket'
            - SQSSendMessagePolicy:
                QueueName: !GetAtt MyQueue.QueueName

  MyBucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: Delete
    Properties:
        OwnershipControls:
            Rules:
            - ObjectOwnership: ObjectWriter
        BucketName: my-bucket

Should look like a fragment of your template but let me know if you notice any details which are different.
Processed template (pure CloudFormation, w/o SAM resources) for that fragment looks like following:

{
 "Resources": {
  "MyBucket": {
   "Type": "AWS::S3::Bucket",
   "DeletionPolicy": "Delete",
   "Properties": {
    "OwnershipControls": {
     "Rules": [
      {
       "ObjectOwnership": "ObjectWriter"
      }
     ]
    },
    "BucketName": "my-bucket"
   }
  },
  "MyFunc": {
   "Type": "AWS::Lambda::Function",
   "Properties": {
    "Code": {
     "ZipFile": "exports.handler = async (event) => {\\\n    return {\n        statusCode: 200,\n        body: JSON.stringify({ message: 'Hello, SAM!' }),\\\n    };\n};\n"
    },
    "Handler": "index.handler",
    "MemorySize": 1024,
    "Role": {
     "Fn::GetAtt": [
      "MyFuncRole",
      "Arn"
     ]
    },
    "Runtime": "n",
    "Timeout": 99,
    "Tags": [
     {
      "Key": "lambda:createdBy",
      "Value": "SAM"
     }
    ]
   }
  },
  "MyFuncRole": {
   "Type": "AWS::IAM::Role",
   "Properties": {
    "AssumeRolePolicyDocument": {
     "Version": "2012-10-17",
     "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/CloudWatchLambdaInsightsExecutionRolePolicy"
    ],
    "Policies": [
     {
      "PolicyName": "MyFuncRolePolicy1",
      "PolicyDocument": {
       "Statement": [
        {
         "Action": [
          "s3:GetObject",
          "s3:ListBucket",
          "s3:GetBucketLocation",
          "s3:GetObjectVersion",
          "s3:PutObject",
          "s3:PutObjectAcl",
          "s3:GetLifecycleConfiguration",
          "s3:PutLifecycleConfiguration",
          "s3:DeleteObject"
         ],
         "Effect": "Allow",
         "Resource": [
          {
           "Fn::Sub": [
            "arn:${AWS::Partition}:s3:::${bucketName}",
            {
             "bucketName": "my-bucket"
            }
           ]
          },
          {
           "Fn::Sub": [
            "arn:${AWS::Partition}:s3:::${bucketName}/*",
            {
             "bucketName": "my-bucket"
            }
           ]
          }
         ]
        }
       ]
      }
     },
     {
      "PolicyName": "MyFuncRolePolicy2",
      "PolicyDocument": {
       "Statement": [
        {
         "Action": [
          "sqs:SendMessage*"
         ],
         "Effect": "Allow",
         "Resource": {
          "Fn::Sub": [
           "arn:${AWS::Partition}:sqs:${AWS::Region}:${AWS::AccountId}:${queueName}",
           {
            "queueName": {
             "Fn::GetAtt": [
              "MyQueue",
              "QueueName"
             ]
            }
           }
          ]
         }
        }
       ]
      }
     }
    ],
    "Tags": [
     {
      "Key": "lambda:createdBy",
      "Value": "SAM"
     }
    ]
   }
  }
 }
}

Please notice that

- S3CrudPolicy:
     BucketName: 'my-bucket'

has been transformed into

"PolicyName": "MyFuncRolePolicy1",
      "PolicyDocument": {
       "Statement": [
        {
         "Action": [
          "s3:GetObject",
          "s3:ListBucket",
          "s3:GetBucketLocation",
          "s3:GetObjectVersion",
          "s3:PutObject",
          "s3:PutObjectAcl",
          "s3:GetLifecycleConfiguration",
          "s3:PutLifecycleConfiguration",
          "s3:DeleteObject"
         ],
         "Effect": "Allow",
         "Resource": [
          {
           "Fn::Sub": [
            "arn:${AWS::Partition}:s3:::${bucketName}",
            {
             "bucketName": "my-bucket"
            }
           ]
          },
          {
           "Fn::Sub": [
            "arn:${AWS::Partition}:s3:::${bucketName}/*",
            {
             "bucketName": "my-bucket"
            }
           ]
          }
         ]
        }
       ]
      }
     },

It's one of the policies attached to the MyFuncRole. Can you see the same in your processed template?
If not, please share your original and processed templates.

Also, I encourage you to use connectors instead of policies. It can be a workaround for you now.

from serverless-application-model.

mildaniel avatar mildaniel commented on May 27, 2024

Hi @ehuebner, thanks for raising this issue. My hunch is that the underlying policy expects a bucket name in the same stack. This seems like an issue that is more relevant to the transform itself, so I will transfer the issue there.

In the meantime, you might be able to try creating your own policy https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-policy.html.

from serverless-application-model.

xazhao avatar xazhao commented on May 27, 2024

Hi @ehuebner thanks for raising this issue. I tried to reproduce using a serverless function with S3CrudPolicy and the policy was actually deployed. See the template below:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function 
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.9
      Architectures:
        - x86_64
      Policies:
        - S3CrudPolicy:
            BucketName: 'xxxxxx-bucket'

Could you verify the processed template to see if S3 permissions are there? You can go to CloudFormation Console, click the stack and click the Template then toggle View processed template to see the transformed template.

from serverless-application-model.

ehuebner avatar ehuebner commented on May 27, 2024

Hi @xazhao,
I checked the processed template and MyFuncRole only contains the policies CloudWatchLambdaInsightsExecutionRolePolicy and SQSSendMessagePolicy. The S3CrudPolicy is not processed

from serverless-application-model.

ehuebner avatar ehuebner commented on May 27, 2024

Hi @ssenchenko,
when I deploy the S3 bucket and the lambda function within the CF same stack, the policy is successfully created. I just did that and I can confirm it also works with application.

But as mentioned in my initial issue description, I have two stacks:

  • Stack A for the S3 bucket
  • Stack B for the lambda function
    The S3 bucket in Stack A will be used by multiple part from the application, so it needs to be accessible from multiple other CF stacks.

Is there any way to apply the S3CrudPolicy in the lambda of Stack A to access the S3 in Stack B?

Edit: I already tried connectors before I created this issue. But my sam deploy ... said it does not know the type AWS::Serverless::Connector.

from serverless-application-model.

GavinZZ avatar GavinZZ commented on May 27, 2024

@ehuebner Let me answer the questions one by one:

Is there any way to apply the S3CrudPolicy in the lambda of Stack A to access the S3 in Stack B?

Yes, and what you're doing is perfectly fine. If it doesn't work for you, please provide a more complete template so that we can help you more. But here's what I have and I confirmed that it's working.

S3 Bucket template.yaml

MyBucket:
        Type: AWS::S3::Bucket
        DeletionPolicy: Delete
        Properties:
            OwnershipControls:
                Rules:
                - ObjectOwnership: ObjectWriter
            BucketName: my-bucket

Deploy this using SAM CLI, sam deploy --guided. Add some random files to the bucket.

Lambda function template.yaml. I've used inline code to demonstrate how to access bucket defined in another stack.

Transform: AWS::Serverless-2016-10-31
Resources:
  MyFunc:
    Type: AWS::Serverless::Function
    Properties:
      InlineCode: |
        const { ListObjectsCommand, S3Client } = require("@aws-sdk/client-s3");

        const s3Client = new S3Client({});

        module.exports.handler = async (event, context) => {
          const bucketName = "my-bucket";

          try {
            const command = new ListObjectsCommand({ Bucket: bucketName });
            const data = await s3Client.send(command);
            const items = data.Contents?.map(item => item.Key) || [];
            return {
              statusCode: 200,
              body: JSON.stringify({
                message: "Successfully retrieved items from the bucket",
                items,
              }),
            };
          } catch (error) {
            console.error(error);
            return {
              statusCode: 500,
              body: JSON.stringify({
                message: "Failed to retrieve items from the bucket",
                error: error.message,
              }),
            };
          }
        };
      Runtime: nodejs20.x
      Handler: index.handler
      MemorySize: 1024
      Timeout: 99
      Policies:
          - S3CrudPolicy:
              BucketName: 'my-bucket'
      Events:
          Api:
              Type: Api
              Properties:
                  Path: /my-func
                  Method: POST

Deploy this using SAM CLI, sam deploy --guided.

Check the processed template in CloudFormation and you should see the S3CrudPolicy is replaced with the following

"Policies": [
          {
            "PolicyName": "MyFuncRolePolicy0",
            "PolicyDocument": {
              "Statement": [
                {
                  "Action": [
                    "s3:GetObject",
                    "s3:ListBucket",
                    "s3:GetBucketLocation",
                    "s3:GetObjectVersion",
                    "s3:PutObject",
                    "s3:PutObjectAcl",
                    "s3:GetLifecycleConfiguration",
                    "s3:PutLifecycleConfiguration",
                    "s3:DeleteObject"
                  ],
                  "Effect": "Allow",
                  "Resource": [
                    {
                      "Fn::Sub": [
                        "arn:${AWS::Partition}:s3:::${bucketName}",
                        {
                          "bucketName": "my-bucket"
                        }
                      ]
                    },
                    {
                      "Fn::Sub": [
                        "arn:${AWS::Partition}:s3:::${bucketName}/*",
                        {
                          "bucketName": "my-bucket"
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          }

Test invoking the lambda function will correctly show the contents (the random files you added in a previous step) in the bucket.

But my sam deploy ... said it does not know the type AWS::Serverless::Connector.

Is this the actual SAM CLI version you're using? SAM CLI, version 1.103.0. You can check by running sam --version. If that's right you should have access to use SAM connector.

Did you run sam build before running sam deploy?

from serverless-application-model.

GavinZZ avatar GavinZZ commented on May 27, 2024

Going to close this issue as the policies are correctly attached when the resources are defined in two stacks. Details of the stacks are provided above. Feel free to open another issue if it still doesn't work for you, please provide a more detailed/complete template.

from serverless-application-model.

github-actions avatar github-actions commented on May 27, 2024

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

from serverless-application-model.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.