¿Cómo puedo resolver las dependencias circulares con plantillas de AWS Serverless Application Model (SAM) en CloudFormation?

3 minutos de lectura
0

Si despliego una plantilla de AWS Serverless Application Model (SAM) en AWS CloudFormation, recibo un error similar al siguiente: «Dependencia circular entre recursos: [Function, Bucket, FunctionRole, FunctionUploadPermission]».

Descripción breve

Si utiliza el siguiente ejemplo de plantilla de AWS SAM, recibe un error en CloudFormation:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Circular Dependency
Resources:
  Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub "{AWS::StackName}-${AWS::Region}-${AWS::AccountId}"
  Function:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: s3://mybucket/function.zip
      Runtime: nodejs12.x
      Handler: index.handler
      Policies:
        - Version: 2012-10-17
          Statement:
            - Effect: Allow
              Action: s3:GetObject*
              Resource: !Sub "arn:aws:s3:::${Bucket}*"
      Events:
        Upload:
          Properties:
            Bucket:
              Ref: Bucket
            Events: s3:ObjectCreated:*
          Type: S3

La plantilla produce un error porque crea la dependencia circular siguiente:

  1. El recurso Bucket depende de FunctionUploadPermission.
  2. FunctionUploadPermission depende de Function.
  3. Function depende de FunctionRole.
  4. FunctionRole depende del recurso Bucket, que crea un bucle.

Nota: En el mensaje de error, el recurso FunctionUploadPermission es del tipo AWS::Lambda::Permission. AWS SAM genera este recurso automáticamente cuando se especifica la propiedad Events para AWS::Serverless::Function. El recurso FunctionRole es del tipo AWS::IAM::Role. AWS SAM genera este recurso automáticamente cuando no se especifica la propiedad Role para AWS::Serverless::Function.

Para resolver la dependencia circular, debe interrumpir el bucle mediante la sustitución de la referencia dinámica al recurso del bucket.

Resolución

Sustituya la plantilla de CloudFormation que tiene una dependencia circular por la plantilla siguiente:

Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Circular Dependency
Resources:
  Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub "${AWS::StackName}-${AWS::Region}-${AWS::AccountId}"
  Function:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: s3://mybucket/function.zip
      Runtime: nodejs12.x
      Handler: index.handler
      Policies:
        - Version: 2012-10-17
          Statement:
            - Effect: Allow
              Action: s3:GetObject*
              Resource: !Sub "arn:aws:s3:::${AWS::StackName}-${AWS::Region}-${AWS::AccountId}*"
      Events:
        Upload:
          Properties:
            Bucket:
              Ref: Bucket
            Events: s3:ObjectCreated:*
          Type: S3

En la plantilla, el nombre del bucket de la sección Resources de la declaración de la política utiliza los mismos pseudoparámetros que se utilizan en la propiedad BucketName del recurso del bucket. Ahora puede incluir el nombre del bucket sin hacer referencia a ese bucket directamente. Por consiguiente, el error se resuelve porque el bucle de dependencia circular se interrumpe. Es decir, el bucle de dependencia circular derivado de FunctionRole dependiente del recurso Bucket.

Nota: Sustituya s3://mybucket/function.zip por la ubicación de su archivo.


Información relacionada

Fn::Sub (función intrínseca)

Ref (función intrínseca)

AWS::Serverless::Function

AWS::S3::Bucket

OFICIAL DE AWS
OFICIAL DE AWSActualizada hace 3 años