web-dev-qa-db-fra.com

La règle Ansible Cloudwatch signale que les appels ont échoué

J'ai créé un lambda AWS qui fonctionne bien lorsque je le teste et lorsque je crée un travail cron manuellement via une règle cloudwatch.

Il signale les mesures sous forme d'appels (non échoués) et enregistre également des détails sur l'exécution.

J'ai ensuite décidé de supprimer cette règle cloudwatch créée manuellement afin d'en créer une avec ansible.

  - name: Create lambda service.
    lambda:
      name: "{{ item.name }}"
      state: present
      Zip_file: "{{ item.Zip_file }}"
      runtime: 'python2.7'
      role: 'arn:aws:iam::12345678901:role/lambda_ecr_delete'
      handler: 'main.handler'
      region: 'eu-west-2'
      environment_variables: "{{ item.env_vars }}"
    with_items:
      - name: lamda_ecr_cleaner
        Zip_file: assets/scripts/ecr-cleaner.Zip
        env_vars:
          'DRYRUN': '0'
          'IMAGES_TO_KEEP': '20'
          'REGION': 'eu-west-2'
    register: new_lambda

  - name: Schedule a cloudwatch event.
    cloudwatchevent_rule:
      name: ecr_delete
      schedule_expression: "rate(1 day)"
      description: Delete old images in ecr repo.
      targets:
        - id: ecr_delete
          arn: "{{ item.configuration.function_arn }}"
    with_items: "{{ new_lambda.results }}"

Cela crée presque exactement la même règle cloudwatch. La seule différence que je peux voir avec celle créée manuellement réside dans les cibles, la version/l'alias lambda est défini sur Par défaut lorsqu'il est créé manuellement alors qu'il est défini sur version, avec un numéro de version correspondant lorsqu'il est créé avec ansible.

La règle cloudwatch créée avec ansible n'a échoué que pour les appels.

Une idée pourquoi c'est? Je ne vois aucun journal. Existe-t-il un moyen de définir également la version par défaut avec le module cloudwatchevent_rule dans ansible?

12
Bastian

J'ai perdu des heures avec ça aussi, même erreur et même confusion (pourquoi il n'y a pas de journal pour les invocations échouées?), Je vais partager ma "" solution "", ça va résoudre le problème à quelqu'un, et aidera les autres à déboguer et à trouver la solution ultime.

Remarque: Attention, cela pourrait permettre à n'importe quel compte AWS d'exécuter vos fonctions lambda

Puisque vous avez invoqué la fonction en créant manuellement la cible de la règle, je suppose que vous avez ajouté l'autorisation d'invocation au lambda de CloudWatch, mais il semble que l'ID du compte source soit différent lorsque l'événement est créé par cli/api et lorsqu'il est créé par Tableau de bord/console AWS

Si vous ajoutez la condition de compte source dans la permission d'invocation lambda du principal "events.amazonaws.com" pour empêcher tout compte AWS d'exécuter vos lambdas, supprimez-le (sous votre responsabilité!).

Donc, si votre politique lambda ressemble à ceci:

{
    "Sid": "<sid>",
    "Effect": "Allow",
    "Principal": {
        "Service": "events.amazonaws.com"
    },
    "Action": "lambda:InvokeFunction",,
    "Condition": {
        "StringEquals": {
            "AWS:SourceAccount": "<account-id>"
        }
    },
    "Resource": "arn:aws:lambda:<region>:<account-id>:function:<lambda-function>"
}

Supprimez le champ "Condition"

{
    "Sid": "sid",
    "Effect": "Allow",
    "Principal": {
        "Service": "events.amazonaws.com"
    },
    "Action": "lambda:InvokeFunction",,
    "Resource": "arn:aws:lambda:<region>:<account-id>:function:<lambda-function>"
}

Et "peut-être" cela fonctionnera pour vous.

Je pense que quelque chose de bizarre se produit avec les données du propriétaire/créateur de l'événement cloudwatch lorsque l'événement est créé par cli/api ... peut-être un bug? Pas certain. Je vais continuer à y travailler

11
ProtheanTom

Pour étendre la réponse ici https://docs.aws.Amazon.com/AmazonCloudWatch/latest/events/CWE_Troubleshooting.html#LAMfunctionNotInvoked . Puisque vous le créez via l'API, vous devez ajouter l'autorisation à Lambda comme mentionné précédemment. Sans compromettre la sécurité, vous pouvez effectuer les opérations suivantes:

Ajoutez une règle avec PutRule appel api, il vous renverra

{
   "RuleArn": "string"
}

Utilisez RuleArn dans l'appel Lambda AddPermission

aws lambda add-permission \
--function-name MyFunction \
--statement-id MyId \
--action 'lambda:InvokeFunction' \
--principal events.amazonaws.com \
--source-arn arn-from-PutRule-request
5
Gleb Oleg