2
votes

Mettre à jour le groupe de journaux existant à l'aide de CloudFormation

J'ai un lambda qui a un groupe de journaux, disons LG-1, pour lequel la rétention est définie sur Never Expire (par défaut). Je dois modifier ce paramètre Never Expire à 1 mois. Je fais cela en utilisant CloudFormation. Comme le groupe de journaux existe déjà, lorsque j'essaye de déployer à nouveau mon lambda avec les modifications du modèle comme:

LambdaFunctionLogGroup:
Type: 'AWS::Logs::LogGroup'
DependsOn: MyLambda
Properties:
  RetentionInDays: 30
  LogGroupName: !Join 
    - ''
    - - /aws/lambda/
      - !Ref MyLambda

la mise à jour échoue avec l'erreur:

[Nom du groupe de journaux] existe déjà.

Une solution possible est de supprimer le groupe de journaux, puis de le créer à nouveau avec de nouvelles modifications comme indiqué ci-dessus, ce qui fonctionne parfaitement bien.

Mais je dois le faire sans supprimer le groupe de journaux car cela entraînera la suppression de tous les journaux précédents que j'ai.

Existe-t-il une solution de contournement possible?


0 commentaires

3 Réponses :


3
votes

Je pense qu'il est impossible de manipuler des ressources de CF qui existent déjà hors de la pile.

Une solution de contournement serait de changer le nom du Lambda comme my-lambda-v2 pour conserver l'ancien groupe de journaux avec le nouveau.

Après un mois, vous pouvez supprimer l'ancien.


4 commentaires

@ttulka le groupe de journaux initialement présent a été créé via CF uniquement, mais dans le cadre de la stratégie d'exécution lambda à l'aide de logs :: CreateLogGroup et non d'AWS :: Logs :: LogGroup.


@IllegalSkillsException Si votre modèle CF n'inclut pas la ressource AWS :: Logs :: LogGroup , cela signifie que le groupe de journaux a été créé par le lambda lui-même lors de sa toute première exécution, PAS < / b> par CF.


@ttulka Oh je vois. Donc, fondamentalement, c'était mon lambda qui créait le groupe de journaux et non CF! Merci :)


@ttulka Exactement. Vous pouvez accepter ma réponse si cela a aidé.



1
votes

Utilisez lambda backed customresource dans votre modèle cloudformation. La ressource personnalisée serait déclenchée automatiquement la première fois et mettrait à jour votre stratégie de rétention du groupe de journaux existant. Si vous en avez besoin, votre ressource lambda personnalisée doit être déclenchée à chaque fois, puis utilisez un moteur de création de modèles comme jinja2.

  LogRetentionSetFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: src
      Handler: set_retention_period.handler
      Role: !GetAtt LambdaRole.Arn
      DeploymentPreference:
        Type: AllAtOnce

  PermissionForLogRetentionSetup:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:invokeFunction
      FunctionName:
        Fn::GetAtt: [ LogRetentionSetFunction, Arn ]
      Principal: lambda.amazonaws.com

  InvokeLambdaFunctionToSetLogRetention:
    DependsOn: [PermissionForLogRetentionSetup]
    Type: Custom::SetLogRetention
    Properties:
      ServiceToken: !GetAtt LogRetentionSetFunction.Arn
      StackName: !Ref AWS::StackName
      AnyVariable: "Choose whatever you want to send"     
      Tags:
        'owner': !Ref owner
        'task': !Ref task

Vous pouvez essentiellement faire en sorte que votre modèle CF fasse (presque) tout ce que vous voulez en utilisant la ressource personnalisée

Plus d'informations (Boto3, vous pouvez trouver le SDK correspondant à la langue que vous utilisez) - https://boto3.amazonaws.com/v1/documentation/api/1.9.42/reference/services/logs.html#CloudWatchLogs. Client.put_retention_policy

EDIT: Dans le modèle CloudFormation, cela ressemblerait à ceci:

import boto3

client = boto3.client('logs')
response = client.put_retention_policy(
    logGroupName='string',
    retentionInDays=123
)

La fonction lambda aurait le code qui configure la rétention du journal selon le code que j'ai déjà spécifié auparavant.

Pour plus d'informations, veuillez google "lambda basé sur des ressources personnalisées". Aussi pour vous donner une longueur d'avance, j'ai ajouté l'encre ci-dessous: https://docs.aws.amazon.com/ AWSCloudFormation / latest / UserGuide / template-custom-resources.html


4 commentaires

Pouvez-vous l'expliquer en termes de modèle CF et non de code? Je n'ai pas obtenu «Utiliser lambda backed customresource dans votre modèle cloudformation». Quelle ressource personnalisée?


Veuillez vous référer à la modification de ma réponse initialement fournie!


1. Je devrai faire ce changement dans le modèle lambda existant ou créer un nouveau? 2. Il y aura donc un nouveau lambda qui sera créé et que lambda sera déclenché par l'ancien modèle CF de lamba et le nouveau lambda mettra à jour l'ancienne rétention lambda? Je trouve cette ressource personnalisée très difficile à comprendre et à mettre en œuvre


1. Vous pouvez l'ajouter dans le même modèle que celui où vous avez votre lambda, vous n'auriez rien à créer de nouveau. 2. Exactement, les ressources personnalisées sont déclenchées une fois (sauf si vous ajoutez quelque chose pour changer le nom de la ressource de manière dynamique). 3. Les ressources personnalisées (basées sur Lambda) vous donnent la liberté d'effectuer tout ce que vous ne pouvez pas faire en utilisant directement CloudFormation. Faites-moi savoir si vous avez des questions spécifiques concernant la mise en œuvre de cette solution.



2
votes

@ttulka a répondu:

".. il est impossible de manipuler des ressources de CF qui existent déjà hors de la pile."

Mais en fait, le problème est plus général que cela et s'applique aux ressources créées à l'intérieur de la pile. Cela a à voir avec la ressource AWS CloudFormation " Politique de remplacement ". Pour certaines ressources, la manière dont CloudFormation "met à jour" la ressource consiste à créer une nouvelle ressource, puis à supprimer l'ancienne ressource (cela s'appelle " Remplacement " politique de mise à jour). Cela signifie qu'il y a une période pendant laquelle vous avez deux ressources du même type avec plusieurs des mêmes propriétés existant en même temps. Mais si une certaine propriété de ressource doit être unique, les deux ressources ne peuvent pas exister en même temps si elles ont la même valeur pour cette propriété, donc ... CloudFormation explose.

AWS :: Logs :: LogGroup.LogGroupName est l'une de ces propriétés. AWS: : CloudWatch :: Alarm.AlarmName est un autre exemple.

Une solution consiste à annuler la définition du nom pour qu'un nom aléatoire soit utilisé, à effectuer une mise à jour, puis à redéfinir le nom sur sa valeur fixe prévisible et à mettre à jour à nouveau.

Rant: C'est un problème ennuyeux qui ne devrait vraiment pas exister. C'est à dire. AWS CF devrait être suffisamment intelligent pour ne pas avoir à utiliser cette implémentation de remplacement de ressources bizarre et maladroite. Mais ... c'est AWS CF pour vous ...


0 commentaires