Comment résoudre les dépendances circulaires avec les modèles AWS Serverless Application Model (SAM) dans CloudFormation ?

Dernière mise à jour : 31/08/2021

Si je déploie un modèle AWS Serverless Application Model (SAM) dans AWS CloudFormation, j'obtiens une erreur similaire à la suivante : « Dépendance circulaire entre les ressources : [Fonction, Compartiment, FunctionRole, FunctionUploadPermission] ».

Brève description

Vous obtenez une erreur dans CloudFormation si vous utilisez l'exemple de modèle AWS SAM suivant :

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

Le modèle génère une erreur car il crée la dépendance circulaire suivante :

  1. La ressource Compartiment dépend de FunctionUploadPermission.
  2. FunctionUploadPermission dépend de la fonction.
  3. La fonction dépend de FunctionRole.
  4. FunctionRole dépend de la ressource Compartiment, qui crée une boucle.

Remarque : Dans le message d'erreur, la ressource FunctionUploadPermission est de type AWS::Lambda::Autorisation. Cette ressource est générée automatiquement par AWS SAM lorsque la propriété Événements pour AWS::Serverless::Fonction est spécifiée. La ressource FunctionRole est de type AWS::IAM::Rôle. Cette ressource est générée automatiquement par AWS SAM lorsque la propriété Rôle pour AWS::Serverless::Fonction n'est pas spécifiée.

Pour résoudre la dépendance circulaire, vous devez interrompre la boucle en remplaçant la référence dynamique à la ressource de compartiment.

Solution

Remplacez le modèle CloudFormation qui dispose d'une dépendance circulaire par le modèle suivant :

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

Dans le modèle, le nom du compartiment   dans la section Ressources de la déclaration de politique utilise les mêmes pseudo-paramètres que ceux utilisés dans la propriété BucketName de la ressource de compartiment. Vous pouvez désormais transmettre le nom du compartiment sans référencer directement ce compartiment. Par conséquent, l'erreur est résolue car la boucle de dépendance circulaire est interrompue. C'est-à-dire la boucle de dépendance circulaire résultant de FunctionRole en fonction de la ressource Compartiment.

Remarque : Remplacez s3://mybucket/function.zip par votre emplacement de fichier.


Cet article vous a-t-il été utile ?


Besoin d'aide pour une question technique ou de facturation ?