

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Automatisez les instantanés cohérents avec les applications avec Data Lifecycle Manager
<a name="automate-app-consistent-backups"></a>

Vous pouvez automatiser les instantanés cohérents par rapport à l’application avec Amazon Data Lifecycle Manager en activant les pré-scripts et les post-scripts dans vos politiques de cycle de vie des instantanés qui ciblent les instances.

Amazon Data Lifecycle Manager s'intègre à AWS Systems Manager (Systems Manager) pour prendre en charge des instantanés cohérents avec les applications. Amazon Data Lifecycle Manager utilise les documents de commande Systems Manager (SSM) qui incluent des pré-scripts et des post-scripts pour automatiser les actions nécessaires pour créer des instantanés cohérents par rapport à l’application. Avant qu'Amazon Data Lifecycle Manager ne lance la création d'un instantané, il exécute les commandes du pré-script pour les bloquer et les viderI/O. After Amazon Data Lifecycle Manager initiates snapshot creation, it runs the commands in the post script to thaw I/O.

Avec Amazon Data Lifecycle Manager, vous pouvez automatiser les instantanés cohérents par rapport à l’application pour les applications suivantes :
+ applications Windows avec Volume Shadow Copy Service (VSS) ;
+ SAP HANA à l'aide d'un AWS document SSDM géré. pour plus d’informations, consultez [Amazon EBS snapshots for SAP HANA](https://docs.aws.amazon.com/sap/latest/sap-hana/ebs-sap-hana.html).
+ Bases de données autogérées, telles que MySQL, PostgreSQL InterSystems ou IRIS, à l'aide de modèles de documents SSM

**Topics**
+ [Exigences relatives à l’utilisation des pré-scripts et post-scripts](#app-consistent-prereqs)
+ [Démarrage avec les instantanés cohérents par rapport à l’application](#app-consistent-get-started)
+ [Considérations relatives aux sauvegardes VSS avec Amazon Data Lifecycle Manager](#app-consistent-vss)
+ [Responsabilité partagée pour les instantanés cohérents par rapport à l’application](#shared-responsibility)

## Exigences relatives à l’utilisation des pré-scripts et post-scripts
<a name="app-consistent-prereqs"></a>

Le tableau suivant décrit les exigences relatives à l’utilisation des pré-scripts et des post-scripts avec Amazon Data Lifecycle Manager.


|  | Instantanés cohérents par rapport à l’application |  | 
| --- |--- |--- |
| Exigence | Sauvegarde VSS | Document SSM personnalisé | Autres cas d’utilisation | 
| --- |--- |--- |--- |
| Agent SSM installé et exécuté sur les instances cibles | ✓ | ✓ | ✓ | 
| Les exigences du système VSS sont satisfaites sur les instances cibles | ✓ |  |  | 
| Profil d'instance compatible VSS associé aux instances cibles | ✓ |  |  | 
| Composants VSS installés sur les instances cibles | ✓ |  |  | 
| Préparer un document SSM avec des commandes de script pré et post |  | ✓ | ✓ | 
| Préparer le rôle IAM d'Amazon Data Lifecycle Manager, exécuter des scripts avant et après | ✓ | ✓ | ✓ | 
| Créez une politique de capture instantanée qui cible les instances et qui est configurée pour les pré-scripts et les post-scripts | ✓ | ✓ | ✓ | 

## Démarrage avec les instantanés cohérents par rapport à l’application
<a name="app-consistent-get-started"></a>

Cette section explique les étapes à suivre pour automatiser les instantanés cohérents par rapport à l’application à l’aide d’Amazon Data Lifecycle Manager.

### Étape 1 : Préparer les instances cibles
<a name="prep-instances"></a>

Vous devez préparer les instances ciblées pour les instantanés cohérents par rapport à l’application à l’aide d’Amazon Data Lifecycle Manager. Effectuez l’une des actions suivantes en fonction de votre cas d’utilisation.

------
#### [ Prepare for VSS Backups ]

**Pour préparer vos instances cibles pour les sauvegardes VSS**

1. Installez l’agent SSM sur vos instances cibles, s’il n’est pas déjà installé. Si l’agent SSM est déjà installé sur vos instances cibles, ignorez cette étape. 

   Pour plus d'informations, consultez la section [Utilisation de l'agent SSM sur les instances EC2 pour Windows Server](https://docs.aws.amazon.com/systems-manager/latest/userguide/ssm-agent-windows.html).

1. Assurez-vous que l’agent SSM est en cours d’exécution. Pour plus d’informations, consultez [Vérification du statut de l’SSM Agent et démarrage de l’agent](https://docs.aws.amazon.com/systems-manager/latest/userguide/ssm-agent-status-and-restart.html).

1. Configurez Systems Manager pour des instances Amazon EC2. Pour plus d’informations, consultez [Configuration de Systems Manager pour des instances Amazon EC2](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-setting-up-ec2.html) dans le *Guide de l’utilisateur AWS Systems Manager *.

1. [ Assurez-vous que la configuration système requise pour les sauvegardes VSS est respectée](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/application-consistent-snapshots-prereqs.html).

1. [ Attachez un profil d’instance compatible avec VSS aux instances cibles](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/vss-iam-reqs.html).

1. [ Installez les composants VSS](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/application-consistent-snapshots-getting-started.html).

------
#### [ Prepare for SAP HANA backups ]

**Pour préparer vos instances cibles pour les sauvegardes SAP HANA**

1. Préparez l’environnement SAP HANA sur vos instances cibles. 

   1. Configurez votre instance avec SAP HANA. Si vous ne possédez pas encore d’environnement SAP HANA, vous pouvez consulter la rubrique [SAP HANA Environment Setup on AWS](https://docs.aws.amazon.com/sap/latest/sap-hana/std-sap-hana-environment-setup.html).

   1. Connectez-vous à SystemDB en tant qu’utilisateur administrateur approprié.

   1. Créez un utilisateur de sauvegarde de base de données à utiliser avec Amazon Data Lifecycle Manager.

      ```
      CREATE USER {{username}} PASSWORD {{password}} NO FORCE_FIRST_PASSWORD_CHANGE;
      ```

      Par exemple, la commande suivante crée un utilisateur nommé `dlm_user` avec le mot de passe `password`.

      ```
      CREATE USER dlm_user PASSWORD password NO FORCE_FIRST_PASSWORD_CHANGE;
      ```

   1. Attribuez le rôle `BACKUP OPERATOR` à l’utilisateur de sauvegarde de base de données que vous avez créé à l’étape précédente.

      ```
      GRANT BACKUP OPERATOR TO {{username}}
      ```

      Par exemple, la commande suivante attribue le rôle à un utilisateur nommé `dlm_user`.

      ```
      GRANT BACKUP OPERATOR TO dlm_user
      ```

   1. Connectez-vous au système d’exploitation en tant qu’administrateur, par exemple `{{sid}}adm`.

   1. Créez une entrée `hdbuserstore` pour stocker les informations de connexion afin que le document SSM SAP HANA puisse se connecter à SAP HANA sans que les utilisateurs aient à saisir ces informations.

      ```
      hdbuserstore set DLM_HANADB_SNAPSHOT_USER localhost:3{{hana_instance_number}}13 {{username}} {{password}}
      ```

      Par exemple :

      ```
      hdbuserstore set DLM_HANADB_SNAPSHOT_USER localhost:30013 dlm_user password
      ```

   1. Testez la connexion.

      ```
      hdbsql -U DLM_HANADB_SNAPSHOT_USER "select * from dummy"
      ```

1. Installez l’agent SSM sur vos instances cibles, s’il n’est pas déjà installé. Si l’agent SSM est déjà installé sur vos instances cibles, ignorez cette étape. 

   Pour plus d'informations, voir [Installation manuelle de l'agent SSM sur les instances EC2 pour Linux](https://docs.aws.amazon.com/systems-manager/latest/userguide/manually-install-ssm-agent-linux.html).

1. Assurez-vous que l’agent SSM est en cours d’exécution. Pour plus d’informations, consultez [Vérification du statut de l’SSM Agent et démarrage de l’agent](https://docs.aws.amazon.com/systems-manager/latest/userguide/ssm-agent-status-and-restart.html).

1. Configurez Systems Manager pour des instances Amazon EC2. Pour plus d’informations, consultez [Configuration de Systems Manager pour des instances Amazon EC2](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-setting-up-ec2.html) dans le *Guide de l’utilisateur AWS Systems Manager *.

------
#### [ Prepare for custom SSM documents ]

**Pour préparer les documents SSM personnalisés de vos instances cibles**

1. Installez l’agent SSM sur vos instances cibles, s’il n’est pas déjà installé. Si l’agent SSM est déjà installé sur vos instances cibles, ignorez cette étape. 
   + (Instances Linux) [Installation manuelle de l'agent SSM sur les instances EC2](https://docs.aws.amazon.com/systems-manager/latest/userguide/manually-install-ssm-agent-linux.html) pour Linux
   + (instances Windows) [Utilisation de l'agent SSM sur les instances EC2 pour](https://docs.aws.amazon.com/systems-manager/latest/userguide/ssm-agent-windows.html) Windows Server

1. Assurez-vous que l’agent SSM est en cours d’exécution. Pour plus d’informations, consultez [Vérification du statut de l’SSM Agent et démarrage de l’agent](https://docs.aws.amazon.com/systems-manager/latest/userguide/ssm-agent-status-and-restart.html).

1. Configurez Systems Manager pour des instances Amazon EC2. Pour plus d’informations, consultez [Configuration de Systems Manager pour des instances Amazon EC2](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-setting-up-ec2.html) dans le *Guide de l’utilisateur AWS Systems Manager *.

------

### Étape 2 : Préparer le document SSM
<a name="prep-ssm-doc"></a>

**Note**  
Cette étape est requise uniquement pour les documents SSM personnalisés. Elle n’est pas nécessaire pour les sauvegardes VSS ou SAP HANA. Pour les sauvegardes VSS et SAP HANA, Amazon Data Lifecycle Manager utilise le document AWS SSM géré.

Si vous automatisez des instantanés cohérents avec les applications pour une base de données autogérée, telle que MySQL, PostgreSQL ou InterSystems IRIS, vous devez créer un document de commande SSM qui inclut un pré-script à figer et à vider I/O avant le lancement de la création de snapshots, et un post-script à décongeler après le lancement de la création de snapshots. I/O 

Si votre base de données MySQL, PostgreSQL InterSystems ou IRIS utilise des configurations standard, vous pouvez créer un document de commande SSM à l'aide de l'exemple de contenu du document SSM ci-dessous. Si votre base de données MySQL, PostgreSQL InterSystems ou IRIS utilise une configuration non standard, vous pouvez utiliser l'exemple de contenu ci-dessous comme point de départ pour votre document de commande SSM, puis le personnaliser en fonction de vos besoins. Si vous souhaitez créer un nouveau document SSM à partir de zéro, vous pouvez également utiliser le modèle de document SSM vide ci-dessous et ajouter vos commandes pré et post dans les sections de document appropriées.

**Notez ce qui suit :**  
Il est de votre responsabilité de vous assurer que le document SSM exécute les actions correctes et requises pour la configuration de votre base de données.
La cohérence des instantanés par rapport à l’application est garantie uniquement si les pré-scripts et les post-scripts de votre document SSM parviennent à geler, à vider et à dégeler les E/S.
Le document SSM doit inclure les champs obligatoires pour `allowedValues`, notamment `pre-script`, `post-script` et `dry-run`. Amazon Data Lifecycle Manager exécutera des commandes sur votre instance en fonction du contenu de ces sections. Si votre document SSM ne contient pas ces sections, Amazon Data Lifecycle Manager le considérera comme un échec d’exécution.

------
#### [ MySQL sample document content ]

```
###===============================================================================###
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.

# 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.
###===============================================================================###
schemaVersion: '2.2'
description: Amazon Data Lifecycle Manager Pre/Post script for MySQL databases
parameters:
  executionId:
    type: String
    default: None
    description: (Required) Specifies the unique identifier associated with a pre and/or post execution
    allowedPattern: ^(None|[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12})$
  command:
  # Data Lifecycle Manager will trigger the pre-script and post-script actions during policy execution. 
  # 'dry-run' option is intended for validating the document execution without triggering any commands
  # on the instance. The following allowedValues will allow Data Lifecycle Manager to successfully 
  # trigger pre and post script actions.
    type: String
    default: 'dry-run'
    description: (Required) Specifies whether pre-script and/or post-script should be executed.
    allowedValues:
    - pre-script
    - post-script
    - dry-run

mainSteps:
- action: aws:runShellScript
  description: Run MySQL Database freeze/thaw commands
  name: run_pre_post_scripts
  precondition:
    StringEquals:
    - platformType
    - Linux
  inputs:
    runCommand:
    - |
      #!/bin/bash

      ###===============================================================================###
      ### Error Codes
      ###===============================================================================###
      # The following Error codes will inform Data Lifecycle Manager of the type of error 
      # and help guide handling of the error. 
      # The Error code will also be emitted via AWS Eventbridge events in the 'cause' field.
      # 1 Pre-script failed during execution - 201
      # 2 Post-script failed during execution - 202
      # 3 Auto thaw occurred before post-script was initiated - 203
      # 4 Pre-script initiated while post-script was expected - 204
      # 5 Post-script initiated while pre-script was expected - 205
      # 6 Application not ready for pre or post-script initiation - 206

      ###=================================================================###
      ### Global variables
      ###=================================================================###
      START=$(date +%s)
      # For testing this script locally, replace the below with OPERATION=$1.
      OPERATION={{ command }}
      FS_ALREADY_FROZEN_ERROR='freeze failed: Device or resource busy'
      FS_ALREADY_THAWED_ERROR='unfreeze failed: Invalid argument'
      FS_BUSY_ERROR='mount point is busy'

      # Auto thaw is a fail safe mechanism to automatically unfreeze the application after the 
      # duration specified in the global variable below. Choose the duration based on your
      # database application's tolerance to freeze.
      export AUTO_THAW_DURATION_SECS="60"

      # Add all pre-script actions to be performed within the function below
      execute_pre_script() {
          echo "INFO: Start execution of pre-script"
          # Check if filesystem is already frozen. No error code indicates that filesystem 
          # is not currently frozen and that the pre-script can proceed with freezing the filesystem.
          check_fs_freeze
          # Execute the DB commands to flush the DB in preparation for snapshot
          snap_db
          # Freeze the filesystem. No error code indicates that filesystem was succefully frozen
          freeze_fs

          echo "INFO: Schedule Auto Thaw to execute in ${AUTO_THAW_DURATION_SECS} seconds."
          $(nohup bash -c execute_schedule_auto_thaw  >/dev/null 2>&1 &)
      }

      # Add all post-script actions to be performed within the function below
      execute_post_script() {
          echo "INFO: Start execution of post-script"
          # Unfreeze the filesystem. No error code indicates that filesystem was successfully unfrozen.
          unfreeze_fs
          thaw_db
      }

      # Execute Auto Thaw to automatically unfreeze the application after the duration configured 
      # in the AUTO_THAW_DURATION_SECS global variable.
      execute_schedule_auto_thaw() {
          sleep ${AUTO_THAW_DURATION_SECS}
          execute_post_script
      }

      # Disable Auto Thaw if it is still enabled
      execute_disable_auto_thaw() {
          echo "INFO: Attempting to disable auto thaw if enabled"
          auto_thaw_pgid=$(pgrep -f execute_schedule_auto_thaw | xargs -i ps -hp {} -o pgid)
          if [ -n "${auto_thaw_pgid}" ]; then
              echo "INFO: execute_schedule_auto_thaw process found with pgid ${auto_thaw_pgid}"
              sudo pkill -g ${auto_thaw_pgid}
              rc=$?
              if [ ${rc} != 0 ]; then
                  echo "ERROR: Unable to kill execute_schedule_auto_thaw process. retval=${rc}"
              else
                  echo "INFO: Auto Thaw  has been disabled"
              fi
          fi
      }

      # Iterate over all the mountpoints and check if filesystem is already in freeze state.
      # Return error code 204 if any of the mount points are already frozen.
      check_fs_freeze() {
          for target in $(lsblk -nlo MOUNTPOINTS)
          do
              # Freeze of the root and boot filesystems is dangerous and pre-script does not freeze these filesystems.
              # Hence, we will skip the root and boot mountpoints while checking if filesystem is in freeze state.
              if [ $target == '/' ]; then continue; fi
              if [[ "$target" == *"/boot"* ]]; then continue; fi

              error_message=$(sudo mount -o remount,noatime $target 2>&1)
              # Remount will be a no-op without a error message if the filesystem is unfrozen.
              # However, if filesystem is already frozen, remount will fail with busy error message.
              if [ $? -ne 0 ];then
                  # If the filesystem is already in frozen, return error code 204
                  if [[ "$error_message" == *"$FS_BUSY_ERROR"* ]];then
                      echo "ERROR: Filesystem ${target} already frozen. Return Error Code: 204"
                      exit 204
                  fi
                  # If the check filesystem freeze failed due to any reason other than the filesystem already frozen, return 201
                  echo "ERROR: Failed to check_fs_freeze on mountpoint $target due to error - $errormessage"
                  exit 201
              fi
          done
      } 

      # Iterate over all the mountpoints and freeze the filesystem.
      freeze_fs() {
          for target in $(lsblk -nlo MOUNTPOINTS)
          do
              # Freeze of the root and boot filesystems is dangerous. Hence, skip filesystem freeze 
              # operations for root and boot mountpoints.
              if [ $target == '/' ]; then continue; fi
              if [[ "$target" == *"/boot"* ]]; then continue; fi
              echo "INFO: Freezing $target"
              error_message=$(sudo fsfreeze -f $target 2>&1)
              if [ $? -ne 0 ];then
                  # If the filesystem is already in frozen, return error code 204
                  if [[ "$error_message" == *"$FS_ALREADY_FROZEN_ERROR"* ]]; then
                      echo "ERROR: Filesystem ${target} already frozen. Return Error Code: 204"
                      sudo mysql -e 'UNLOCK TABLES;'
                      exit 204
                  fi
                  # If the filesystem freeze failed due to any reason other than the filesystem already frozen, return 201
                  echo "ERROR: Failed to freeze mountpoint $targetdue due to error - $errormessage"
                  thaw_db
                  exit 201
              fi
              echo "INFO: Freezing complete on $target"
          done
      }

      # Iterate over all the mountpoints and unfreeze the filesystem.
      unfreeze_fs() {
          for target in $(lsblk -nlo MOUNTPOINTS)
          do
              # Freeze of the root and boot filesystems is dangerous and pre-script does not freeze these filesystems.
              # Hence, will skip the root and boot mountpoints during unfreeze as well.
              if [ $target == '/' ]; then continue; fi
              if [[ "$target" == *"/boot"* ]]; then continue; fi
              echo "INFO: Thawing $target"
              error_message=$(sudo fsfreeze -u $target 2>&1)
              # Check if filesystem is already unfrozen (thawed). Return error code 204 if filesystem is already unfrozen.
              if [ $? -ne 0 ]; then
                  if [[ "$error_message" == *"$FS_ALREADY_THAWED_ERROR"* ]]; then
                      echo "ERROR: Filesystem ${target} is already in thaw state. Return Error Code: 205"
                      exit 205
                  fi
                  # If the filesystem unfreeze failed due to any reason other than the filesystem already unfrozen, return 202
                  echo "ERROR: Failed to unfreeze mountpoint $targetdue due to error - $errormessage"
                  exit 202
              fi
              echo "INFO: Thaw complete on $target"
          done    
      }

      snap_db() {
          # Run the flush command only when MySQL DB service is up and running
          sudo systemctl is-active --quiet mysqld.service
          if [ $? -eq 0 ]; then
              echo "INFO: Execute MySQL Flush and Lock command."
              sudo mysql -e 'FLUSH TABLES WITH READ LOCK;'
              # If the MySQL Flush and Lock command did not succeed, return error code 201 to indicate pre-script failure
              if [ $? -ne 0 ]; then
                  echo "ERROR: MySQL FLUSH TABLES WITH READ LOCK command failed."
                  exit 201
              fi
              sync
          else 
              echo "INFO: MySQL service is inactive. Skipping execution of MySQL Flush and Lock command."
          fi
      }

      thaw_db() {
          # Run the unlock command only when MySQL DB service is up and running
          sudo systemctl is-active --quiet mysqld.service
          if [ $? -eq 0 ]; then
              echo "INFO: Execute MySQL Unlock"
              sudo mysql -e 'UNLOCK TABLES;'
          else 
              echo "INFO: MySQL service is inactive. Skipping execution of MySQL Unlock command."
          fi
      }

      export -f execute_schedule_auto_thaw
      export -f execute_post_script
      export -f unfreeze_fs
      export -f thaw_db

      # Debug logging for parameters passed to the SSM document
      echo "INFO: ${OPERATION} starting at $(date) with executionId: ${EXECUTION_ID}"

      # Based on the command parameter value execute the function that supports 
      # pre-script/post-script operation
      case ${OPERATION} in
          pre-script)
              execute_pre_script
              ;;
          post-script)
              execute_post_script
              execute_disable_auto_thaw
              ;;
          dry-run)
              echo "INFO: dry-run option invoked - taking no action"
              ;;
          *)
              echo "ERROR: Invalid command parameter passed. Please use either pre-script, post-script, dry-run."
              exit 1 # return failure
              ;;
      esac

      END=$(date +%s)
      # Debug Log for profiling the script time
      echo "INFO: ${OPERATION} completed at $(date). Total runtime: $((${END} - ${START})) seconds."
```

------
#### [ PostgreSQL sample document content ]

```
###===============================================================================###
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.

# 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.
###===============================================================================###
schemaVersion: '2.2'
description: Amazon Data Lifecycle Manager Pre/Post script for PostgreSQL databases
parameters:
  executionId:
    type: String
    default: None
    description: (Required) Specifies the unique identifier associated with a pre and/or post execution
    allowedPattern: ^(None|[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12})$
  command:
  # Data Lifecycle Manager will trigger the pre-script and post-script actions during policy execution. 
  # 'dry-run' option is intended for validating the document execution without triggering any commands
  # on the instance. The following allowedValues will allow Data Lifecycle Manager to successfully 
  # trigger pre and post script actions.
    type: String
    default: 'dry-run'
    description: (Required) Specifies whether pre-script and/or post-script should be executed.
    allowedValues:
    - pre-script
    - post-script
    - dry-run

mainSteps:
- action: aws:runShellScript
  description: Run PostgreSQL Database freeze/thaw commands
  name: run_pre_post_scripts
  precondition:
    StringEquals:
    - platformType
    - Linux
  inputs:
    runCommand:
    - |
      #!/bin/bash

      ###===============================================================================###
      ### Error Codes
      ###===============================================================================###
      # The following Error codes will inform Data Lifecycle Manager of the type of error 
      # and help guide handling of the error. 
      # The Error code will also be emitted via AWS Eventbridge events in the 'cause' field.
      # 1 Pre-script failed during execution - 201
      # 2 Post-script failed during execution - 202
      # 3 Auto thaw occurred before post-script was initiated - 203
      # 4 Pre-script initiated while post-script was expected - 204
      # 5 Post-script initiated while pre-script was expected - 205
      # 6 Application not ready for pre or post-script initiation - 206

      ###===============================================================================###
      ### Global variables
      ###===============================================================================###
      START=$(date +%s)
      OPERATION={{ command }}
      FS_ALREADY_FROZEN_ERROR='freeze failed: Device or resource busy'
      FS_ALREADY_THAWED_ERROR='unfreeze failed: Invalid argument'
      FS_BUSY_ERROR='mount point is busy'

      # Auto thaw is a fail safe mechanism to automatically unfreeze the application after the 
      # duration specified in the global variable below. Choose the duration based on your
      # database application's tolerance to freeze.
      export AUTO_THAW_DURATION_SECS="60"

      # Add all pre-script actions to be performed within the function below
      execute_pre_script() {
          echo "INFO: Start execution of pre-script"
          # Check if filesystem is already frozen. No error code indicates that filesystem 
          # is not currently frozen and that the pre-script can proceed with freezing the filesystem.
          check_fs_freeze
          # Execute the DB commands to flush the DB in preparation for snapshot
          snap_db
          # Freeze the filesystem. No error code indicates that filesystem was succefully frozen
          freeze_fs

          echo "INFO: Schedule Auto Thaw to execute in ${AUTO_THAW_DURATION_SECS} seconds."
          $(nohup bash -c execute_schedule_auto_thaw  >/dev/null 2>&1 &)
      }

      # Add all post-script actions to be performed within the function below
      execute_post_script() {
          echo "INFO: Start execution of post-script"
          # Unfreeze the filesystem. No error code indicates that filesystem was successfully unfrozen
          unfreeze_fs
      }

      # Execute Auto Thaw to automatically unfreeze the application after the duration configured 
      # in the AUTO_THAW_DURATION_SECS global variable.
      execute_schedule_auto_thaw() {
          sleep ${AUTO_THAW_DURATION_SECS}
          execute_post_script
      }

      # Disable Auto Thaw if it is still enabled
      execute_disable_auto_thaw() {
          echo "INFO: Attempting to disable auto thaw if enabled"
          auto_thaw_pgid=$(pgrep -f execute_schedule_auto_thaw | xargs -i ps -hp {} -o pgid)
          if [ -n "${auto_thaw_pgid}" ]; then
              echo "INFO: execute_schedule_auto_thaw process found with pgid ${auto_thaw_pgid}"
              sudo pkill -g ${auto_thaw_pgid}
              rc=$?
              if [ ${rc} != 0 ]; then
                  echo "ERROR: Unable to kill execute_schedule_auto_thaw process. retval=${rc}"
              else
                  echo "INFO: Auto Thaw  has been disabled"
              fi
          fi
      }

      # Iterate over all the mountpoints and check if filesystem is already in freeze state.
      # Return error code 204 if any of the mount points are already frozen.
      check_fs_freeze() {
          for target in $(lsblk -nlo MOUNTPOINTS)
          do
              # Freeze of the root and boot filesystems is dangerous and pre-script does not freeze these filesystems.
              # Hence, we will skip the root and boot mountpoints while checking if filesystem is in freeze state.
              if [ $target == '/' ]; then continue; fi
              if [[ "$target" == *"/boot"* ]]; then continue; fi

              error_message=$(sudo mount -o remount,noatime $target 2>&1)
              # Remount will be a no-op without a error message if the filesystem is unfrozen.
              # However, if filesystem is already frozen, remount will fail with busy error message.
              if [ $? -ne 0 ];then
                  # If the filesystem is already in frozen, return error code 204
                  if [[ "$error_message" == *"$FS_BUSY_ERROR"* ]];then
                      echo "ERROR: Filesystem ${target} already frozen. Return Error Code: 204"
                      exit 204
                  fi
                  # If the check filesystem freeze failed due to any reason other than the filesystem already frozen, return 201
                  echo "ERROR: Failed to check_fs_freeze on mountpoint $target due to error - $errormessage"
                  exit 201
              fi
          done
      } 

      # Iterate over all the mountpoints and freeze the filesystem.
      freeze_fs() {
          for target in $(lsblk -nlo MOUNTPOINTS)
          do
              # Freeze of the root and boot filesystems is dangerous. Hence, skip filesystem freeze 
              # operations for root and boot mountpoints.
              if [ $target == '/' ]; then continue; fi
              if [[ "$target" == *"/boot"* ]]; then continue; fi
              echo "INFO: Freezing $target"
              error_message=$(sudo fsfreeze -f $target 2>&1)
              if [ $? -ne 0 ];then
                  # If the filesystem is already in frozen, return error code 204
                  if [[ "$error_message" == *"$FS_ALREADY_FROZEN_ERROR"* ]]; then
                      echo "ERROR: Filesystem ${target} already frozen. Return Error Code: 204"
                      exit 204
                  fi
                  # If the filesystem freeze failed due to any reason other than the filesystem already frozen, return 201
                  echo "ERROR: Failed to freeze mountpoint $targetdue due to error - $errormessage"
                  exit 201
              fi
              echo "INFO: Freezing complete on $target"
          done
      }

      # Iterate over all the mountpoints and unfreeze the filesystem.
      unfreeze_fs() {
          for target in $(lsblk -nlo MOUNTPOINTS)
          do
              # Freeze of the root and boot filesystems is dangerous and pre-script does not freeze these filesystems.
              # Hence, will skip the root and boot mountpoints during unfreeze as well.
              if [ $target == '/' ]; then continue; fi
              if [[ "$target" == *"/boot"* ]]; then continue; fi
              echo "INFO: Thawing $target"
              error_message=$(sudo fsfreeze -u $target 2>&1)
              # Check if filesystem is already unfrozen (thawed). Return error code 204 if filesystem is already unfrozen.
              if [ $? -ne 0 ]; then
                  if [[ "$error_message" == *"$FS_ALREADY_THAWED_ERROR"* ]]; then
                      echo "ERROR: Filesystem ${target} is already in thaw state. Return Error Code: 205"
                      exit 205
                  fi
                  # If the filesystem unfreeze failed due to any reason other than the filesystem already unfrozen, return 202
                  echo "ERROR: Failed to unfreeze mountpoint $targetdue due to error - $errormessage"
                  exit 202
              fi
              echo "INFO: Thaw complete on $target"
          done
      }

      snap_db() {
          # Run the flush command only when PostgreSQL DB service is up and running
          sudo systemctl is-active --quiet postgresql
          if [ $? -eq 0 ]; then
              echo "INFO: Execute Postgres CHECKPOINT"
              # PostgreSQL command to flush the transactions in memory to disk
              sudo -u postgres psql -c 'CHECKPOINT;'
              # If the PostgreSQL Command did not succeed, return error code 201 to indicate pre-script failure
              if [ $? -ne 0 ]; then
                  echo "ERROR: Postgres CHECKPOINT command failed."
                  exit 201
              fi
              sync
          else 
              echo "INFO: PostgreSQL service is inactive. Skipping execution of CHECKPOINT command."
          fi
      }

      export -f execute_schedule_auto_thaw
      export -f execute_post_script
      export -f unfreeze_fs

      # Debug logging for parameters passed to the SSM document
      echo "INFO: ${OPERATION} starting at $(date) with executionId: ${EXECUTION_ID}"

      # Based on the command parameter value execute the function that supports 
      # pre-script/post-script operation
      case ${OPERATION} in
          pre-script)
              execute_pre_script
              ;;
          post-script)
              execute_post_script
              execute_disable_auto_thaw
              ;;
          dry-run)
              echo "INFO: dry-run option invoked - taking no action"
              ;;
          *)
              echo "ERROR: Invalid command parameter passed. Please use either pre-script, post-script, dry-run."
              exit 1 # return failure
              ;;
      esac

      END=$(date +%s)
      # Debug Log for profiling the script time
      echo "INFO: ${OPERATION} completed at $(date). Total runtime: $((${END} - ${START})) seconds."
```

------
#### [ InterSystems IRIS sample document content ]

```
###===============================================================================###
# MIT License
# 
# Copyright (c) 2024 InterSystems
# 
# 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, subject to the following conditions:
# 
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
# 
# 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.
###===============================================================================###
schemaVersion: '2.2'
description: SSM Document Template for Amazon Data Lifecycle Manager Pre/Post script feature for InterSystems IRIS.
parameters:
  executionId:
    type: String
    default: None
    description: Specifies the unique identifier associated with a pre and/or post execution
    allowedPattern: ^(None|[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12})$
  command:
    type: String
    # Data Lifecycle Manager will trigger the pre-script and post-script actions. You can also use this SSM document with 'dry-run' for manual testing purposes.
    default: 'dry-run'
    description: (Required) Specifies whether pre-script and/or post-script should be executed.
    #The following allowedValues will allow Data Lifecycle Manager to successfully trigger pre and post script actions.
    allowedValues:
    - pre-script
    - post-script
    - dry-run

mainSteps:
- action: aws:runShellScript
  description: Run InterSystems IRIS Database freeze/thaw commands
  name: run_pre_post_scripts
  precondition:
    StringEquals:
    - platformType
    - Linux
  inputs:
    runCommand:
    - |
      #!/bin/bash
      ###===============================================================================###
      ### Global variables
      ###===============================================================================###
      DOCKER_NAME=iris
      LOGDIR=./
      EXIT_CODE=0
      OPERATION={{ command }}
      START=$(date +%s)
      
      # Check if Docker is installed
      # By default if Docker is present, script assumes that InterSystems IRIS is running in Docker
      # Leave only the else block DOCKER_EXEC line, if you run InterSystems IRIS non-containerised (and Docker is present).
      # Script assumes irissys user has OS auth enabled, change the OS user or supply login/password depending on your configuration.
      if command -v docker &> /dev/null
      then
        DOCKER_EXEC="docker exec $DOCKER_NAME"
      else
        DOCKER_EXEC="sudo -i -u irissys"
      fi
      
                    
      # Add all pre-script actions to be performed within the function below
      execute_pre_script() {
        echo "INFO: Start execution of pre-script"
        
        # find all iris running instances
        iris_instances=$($DOCKER_EXEC iris qall 2>/dev/null | tail -n +3 | grep '^up' | cut -c5-  | awk '{print $1}')
        echo "`date`: Running iris instances $iris_instances"
      
        # Only for running instances
        for INST in $iris_instances; do
      
          echo "`date`: Attempting to freeze $INST"
      
          # Detailed instances specific log
          LOGFILE=$LOGDIR/$INST-pre_post.log
          
          #check Freeze status before starting
          $DOCKER_EXEC irissession $INST -U '%SYS' "##Class(Backup.General).IsWDSuspendedExt()"
          freeze_status=$?
          if [ $freeze_status -eq 5 ]; then
            echo "`date`:   ERROR: $INST IS already FROZEN"
            EXIT_CODE=204
          else
            echo "`date`:   $INST is not frozen"
            # Freeze
            # Docs: https://docs.intersystems.com/irislatest/csp/documatic/%25CSP.Documatic.cls?LIBRARY=%25SYS&CLASSNAME=Backup.General#ExternalFreeze
            $DOCKER_EXEC irissession $INST -U '%SYS' "##Class(Backup.General).ExternalFreeze(\"$LOGFILE\",,,,,,600,,,300)"
            status=$?
      
            case $status in
              5) echo "`date`:   $INST IS FROZEN"
                ;;
              3) echo "`date`:   $INST FREEZE FAILED"
                EXIT_CODE=201
                ;;
              *) echo "`date`:   ERROR: Unknown status code: $status"
                EXIT_CODE=201
                ;;
            esac
            echo "`date`:   Completed freeze of $INST"
          fi
        done
        echo "`date`: Pre freeze script finished"
      }
                    
      # Add all post-script actions to be performed within the function below
      execute_post_script() {
        echo "INFO: Start execution of post-script"
      
        # find all iris running instances
        iris_instances=$($DOCKER_EXEC iris qall 2>/dev/null | tail -n +3 | grep '^up' | cut -c5-  | awk '{print $1}')
        echo "`date`: Running iris instances $iris_instances"
      
        # Only for running instances
        for INST in $iris_instances; do
      
          echo "`date`: Attempting to thaw $INST"
      
          # Detailed instances specific log
          LOGFILE=$LOGDIR/$INST-pre_post.log
      
          #check Freeze status befor starting
          $DOCKER_EXEC irissession $INST -U '%SYS' "##Class(Backup.General).IsWDSuspendedExt()"
          freeze_status=$?
          if [ $freeze_status -eq 5 ]; then
            echo "`date`:  $INST is in frozen state"
            # Thaw
            # Docs: https://docs.intersystems.com/irislatest/csp/documatic/%25CSP.Documatic.cls?LIBRARY=%25SYS&CLASSNAME=Backup.General#ExternalFreeze
            $DOCKER_EXEC irissession $INST -U%SYS "##Class(Backup.General).ExternalThaw(\"$LOGFILE\")"
            status=$?
      
            case $status in
              5) echo "`date`:   $INST IS THAWED"
                  $DOCKER_EXEC irissession $INST -U%SYS "##Class(Backup.General).ExternalSetHistory(\"$LOGFILE\")"
                ;;
              3) echo "`date`:   $INST THAW FAILED"
                  EXIT_CODE=202
                ;;
              *) echo "`date`:   ERROR: Unknown status code: $status"
                  EXIT_CODE=202
                ;;
            esac
            echo "`date`:   Completed thaw of $INST"
          else
            echo "`date`:   ERROR: $INST IS already THAWED"
            EXIT_CODE=205
          fi
        done
        echo "`date`: Post thaw script finished"
      }
      
      # Debug logging for parameters passed to the SSM document
        echo "INFO: ${OPERATION} starting at $(date) with executionId: ${EXECUTION_ID}"
                    
      # Based on the command parameter value execute the function that supports 
      # pre-script/post-script operation
      case ${OPERATION} in
        pre-script)
          execute_pre_script
          ;;
        post-script)
          execute_post_script
            ;;
        dry-run)
          echo "INFO: dry-run option invoked - taking no action"
          ;;
        *)
          echo "ERROR: Invalid command parameter passed. Please use either pre-script, post-script, dry-run."
          # return failure
          EXIT_CODE=1
          ;;
      esac
                    
      END=$(date +%s)
      # Debug Log for profiling the script time
      echo "INFO: ${OPERATION} completed at $(date). Total runtime: $((${END} - ${START})) seconds."
      exit $EXIT_CODE
```

Pour plus d'informations, consultez le [GitHub référentiel](https://github.com/intersystems-community/aws/blob/master/README.md).

------
#### [ Empty document template ]

```
###===============================================================================###
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.

# 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.
###===============================================================================###
schemaVersion: '2.2'
description: SSM Document Template for Amazon Data Lifecycle Manager Pre/Post script feature
parameters:
  executionId:
    type: String
    default: None
    description: (Required) Specifies the unique identifier associated with a pre and/or post execution
    allowedPattern: ^(None|[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12})$
  command:
  # Data Lifecycle Manager will trigger the pre-script and post-script actions during policy execution. 
  # 'dry-run' option is intended for validating the document execution without triggering any commands
  # on the instance. The following allowedValues will allow Data Lifecycle Manager to successfully 
  # trigger pre and post script actions.
    type: String
    default: 'dry-run'
    description: (Required) Specifies whether pre-script and/or post-script should be executed.
    allowedValues:
    - pre-script
    - post-script
    - dry-run

mainSteps:
- action: aws:runShellScript
  description: Run Database freeze/thaw commands
  name: run_pre_post_scripts
  precondition:
    StringEquals:
    - platformType
    - Linux
  inputs:
    runCommand:
    - |
      #!/bin/bash

      ###===============================================================================###
      ### Error Codes
      ###===============================================================================###
      # The following Error codes will inform Data Lifecycle Manager of the type of error 
      # and help guide handling of the error. 
      # The Error code will also be emitted via AWS Eventbridge events in the 'cause' field.
      # 1 Pre-script failed during execution - 201
      # 2 Post-script failed during execution - 202
      # 3 Auto thaw occurred before post-script was initiated - 203
      # 4 Pre-script initiated while post-script was expected - 204
      # 5 Post-script initiated while pre-script was expected - 205
      # 6 Application not ready for pre or post-script initiation - 206

      ###===============================================================================###
      ### Global variables
      ###===============================================================================###
      START=$(date +%s)
      # For testing this script locally, replace the below with OPERATION=$1.
      OPERATION={{ command }}

      # Add all pre-script actions to be performed within the function below
      execute_pre_script() {
          echo "INFO: Start execution of pre-script"
      }

      # Add all post-script actions to be performed within the function below
      execute_post_script() {
          echo "INFO: Start execution of post-script"
      }

      # Debug logging for parameters passed to the SSM document
      echo "INFO: ${OPERATION} starting at $(date) with executionId: ${EXECUTION_ID}"

      # Based on the command parameter value execute the function that supports 
      # pre-script/post-script operation
      case ${OPERATION} in
          pre-script)
              execute_pre_script
              ;;
          post-script)
              execute_post_script
              ;;
          dry-run)
              echo "INFO: dry-run option invoked - taking no action"
              ;;
          *)
              echo "ERROR: Invalid command parameter passed. Please use either pre-script, post-script, dry-run."
              exit 1 # return failure
              ;;
      esac

      END=$(date +%s)
      # Debug Log for profiling the script time
      echo "INFO: ${OPERATION} completed at $(date). Total runtime: $((${END} - ${START})) seconds."
```

------

Une fois que vous avez obtenu le contenu de votre document SSM, utilisez l’une des procédures suivantes pour créer le document SSM personnalisé.

------
#### [ Console ]

**Pour créer un document de commande SSM**

1. Ouvrez la AWS Systems Manager console à l'adresse [https://console.aws.amazon.com//systems-manager/](https://console.aws.amazon.com//systems-manager/).

1. Dans le volet de navigation, choisissez **Documents**, puis sélectionnez **Créer un document**, **Commande ou session**.

1. Pour **Name (Nom)**, saisissez un nom évocateur pour le document.

1. Pour **Type de cible**, sélectionnez**/AWS::EC2::Instance**.

1. Pour **Type de document**, sélectionnez **Commande**.

1. Dans le champ **Contenu**, sélectionnez **YAML**, puis collez le contenu du document.

1. Dans la section **Balises du document**, ajoutez une balise avec une clé de balise `DLMScriptsAccess` et une valeur de balise `true`.
**Important**  
La `DLMScriptsAccess:true` balise est requise par la politique de AWS gestion des **AWSDataLifecycleManagerSSMFullaccès** utilisée à l'*étape 3 : préparation du rôle IAM Amazon Data Lifecycle Manager*. La politique utilise la clé de condition `aws:ResourceTag` pour limiter l’accès aux documents SSM dotés de cette balise.

1. Sélectionnez **Créer un document**.

------
#### [ AWS CLI ]

**Pour créer un document de commande SSM**  
Utilisez la commande [create-document](https://docs.aws.amazon.com/cli/latest/reference/ssm/create-document.html). Pour `--name`, saisissez un nom descriptif pour le document Pour `--document-type`, spécifiez `Command`. Pour `--content`, spécifiez le chemin d’accès au fichier .yaml avec le contenu du document SSM. Pour `--tags`, spécifiez `"Key=DLMScriptsAccess,Value=true"`.

```
$ aws ssm create-document \
--content file:{{//path/to/file/documentContent.yaml}} \
--name "{{document_name}}" \
--document-type "Command" \
--document-format YAML \
--tags "Key=DLMScriptsAccess,Value=true"
```

------

### Étape 3 : Préparer le rôle IAM d’Amazon Data Lifecycle Manager
<a name="prep-iam-role"></a>

**Note**  
Cette étape est nécessaire si :  
Vous créez ou mettez à jour une politique de capture instantanée pre/post activée par script qui utilise un rôle IAM personnalisé.
Vous utilisez la ligne de commande pour créer ou mettre à jour une politique de capture instantanée pre/post activée par script qui utilise la valeur par défaut.
Si vous utilisez la console pour créer ou mettre à jour une politique d'instantanés pre/post activée par script qui utilise le rôle par défaut pour la gestion des instantanés (**AWSDataLifecycleManagerDefaultRole**), ignorez cette étape. Dans ce cas, nous associons automatiquement la politique **AWSDataLifecycleManagerSSMFulld'accès** à ce rôle.

Vous devez vous assurer que le rôle IAM que vous utilisez pour la politique accorde à Amazon Data Lifecycle Manager l’autorisation d’effectuer les actions SSM requises pour exécuter les pré-scripts et les post-scripts sur les instances ciblées par la politique.

Amazon Data Lifecycle Manager fournit une politique gérée (**AWSDataLifecycleManagerSSMFullAccess**) qui inclut les autorisations requises. Vous pouvez associer cette politique à votre rôle IAM pour gérer les instantanés afin de vous assurer qu’elle inclut les autorisations.

**Important**  
La politique AWSData LifecycleManager SSMFull d'accès géré utilise la clé de `aws:ResourceTag` condition pour restreindre l'accès à des documents SSM spécifiques lors de l'utilisation de scripts pré et post. Pour autoriser Amazon Data Lifecycle Manager à accéder aux documents SSM, vous devez vous assurer que vos documents SSM sont balisés avec `DLMScriptsAccess:true`.

Vous pouvez également créer manuellement une politique personnalisée ou attribuer les autorisations requises directement au rôle IAM que vous utilisez. Vous pouvez utiliser les mêmes autorisations que celles définies dans la politique AWSData LifecycleManager SSMFull d'accès géré, mais la clé de `aws:ResourceTag` condition est facultative. Si vous décidez de ne pas inclure cette clé de condition, vous n’avez pas besoin de baliser vos documents SSM avec `DLMScriptsAccess:true`.

Utilisez l'une des méthodes suivantes pour ajouter la politique **AWSDataLifecycleManagerSSMFulld'accès** à votre rôle IAM.

------
#### [ Console ]

**Pour attacher la politique gérée à votre rôle personnalisé**

1. Ouvrez la console IAM à l’adresse [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. Dans le panneau de navigation, choisissez **Roles (Rôles)**.

1. Recherchez et sélectionnez votre rôle personnalisé pour la gestion des instantanés.

1. Sous l’onglet **Permissions** (Autorisations), choisissez **Add Permissions** (Ajouter des autorisations), **Attach policies (Attacher des politiques)**.

1. Recherchez et sélectionnez la politique **AWSDataLifecycleManagerSSMFulld'accès** géré, puis choisissez **Ajouter des autorisations**.

------
#### [ AWS CLI ]

**Pour attacher la politique gérée à votre rôle personnalisé**  
Utilisez la commande [ attach-role-policy](https://docs.aws.amazon.com/cli/latest/reference/iam/attach-role-policy.html). Pour `---role-name`, spécifiez le nom de votre rôle personnalisé. Pour `--policy-arn`, spécifiez `arn:aws:iam::aws:policy/AWSDataLifecycleManagerSSMFullAccess`.

```
$ aws iam attach-role-policy \
--policy-arn arn:aws:iam::aws:policy/AWSDataLifecycleManagerSSMFullAccess \
--role-name {{your_role_name}}
```

------

### Étape 4 : Créer une politique de cycle de vie des instantanés
<a name="prep-policy"></a>

Pour automatiser les instantanés cohérents par rapport à l’application, vous devez créer une politique de cycle de vie des instantanés qui cible les instances, et configurer des pré-scripts et post-scripts pour cette politique.

------
#### [ Console ]

**Pour créer la politique de cycle de vie des instantanés**

1. Ouvrez la console Amazon EC2 à l’adresse [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/).

1. Dans le panneau de navigation, sélectionnez **Elastic Block Store**, **Gestionnaire de cycle de vie**, puis **Créer une stratégie de cycle de vie d’instantané**.

1. Dans la page **Sélectionner un type de stratégie**, choisissez **Stratégie d’instantané EBS**, puis **Suivant**.

1. Dans la section **Ressources cibles**, effectuez les opérations suivantes :

   1. Pour **Types de ressources cibles**, choisissez `Instance`.

   1. Pour **Balises de ressource cible**, spécifiez les balises de ressource qui identifient les instances à sauvegarder. Seules les ressources possédant les balises spécifiées seront sauvegardées.

1. Pour le **rôle IAM**, choisissez **AWSDataLifecycleManagerDefaultRole**(le rôle par défaut pour la gestion des instantanés) ou choisissez un rôle personnalisé que vous avez créé et préparé pour les pré-scripts et les post-scripts.

1. Configurez les planifications et les options supplémentaires selon les besoins. Nous vous recommandons de planifier les heures de création des instantanés pour des périodes correspondant à votre charge de travail, par exemple pendant les fenêtres de maintenance.

   Pour SAP HANA, nous vous recommandons d’activer la restauration d’instantané rapide.
**Note**  
Si vous activez une planification pour les sauvegardes VSS, vous ne pouvez pas activer **Exclure des volumes de données spécifiques** ou **Copier les balises depuis la source**.

1. Dans la section **Pré-scripts et post-scripts**, sélectionnez **Activer les pré-scripts et post-scripts**, puis effectuez les opérations suivantes, en fonction de votre charge de travail :
   + Pour créer des instantanés cohérents par rapport à l’application de vos applications Windows, sélectionnez **Sauvegarde VSS**.
   + Pour créer des instantanés cohérents par rapport à l’application de vos charges de travail SAP HANA, sélectionnez **SAP HANA**.
   + **Pour créer des instantanés cohérents avec les applications de toutes les autres bases de données et charges de travail, y compris vos bases de données MySQL, PostgreSQL ou InterSystems IRIS autogérées, à l'aide d'un document SSM personnalisé, sélectionnez Document SSM personnalisé.**

     1. Pour **Option d’automatisation**, choisissez **Pré-scripts et post-scripts**.

     1. Pour **Document SSM**, sélectionnez le document SSM que vous avez préparé.

1. En fonction de l’option que vous avez sélectionnée, configurez les options supplémentaires suivantes :
   + **Délai d’expiration du script** : (*document SSM personnalisé uniquement*) délai d’expiration au terme duquel Amazon Data Lifecycle Manager échoue à exécuter le script si celui-ci n’est pas terminé. Si un script ne s’exécute pas dans le délai imparti, Amazon Data Lifecycle Manager échoue. Le délai d’expiration s’applique aux pré-scripts et post-scripts individuellement. Le délai d’expiration minimum et par défaut est de 10 secondes. Et le délai d’expiration maximum est de 120 secondes.
   + **Relancer les scripts en échec** : sélectionnez cette option pour relancer les scripts qui ne se terminent pas dans le délai imparti. En cas d’échec du pré-script, Amazon Data Lifecycle Manager relance l’intégralité du processus de création d’instantanés, y compris l’exécution des pré-scripts et post-scripts. Si le post-script échoue, Amazon Data Lifecycle Manager relance uniquement le post-script ; dans ce cas, le pré-script sera terminé et l’instantané aura peut-être été créé.
   + **Prise par défaut d’instantanés en cas de panne** : sélectionnez cette option pour utiliser par défaut des instantanés en cas de panne si le pré-script ne s’exécute pas. Il s’agit du comportement de création d’instantanés par défaut pour Amazon Data Lifecycle Manager si les pré-scripts et post-scripts ne sont pas activés. Si vous avez activé les relances, Amazon Data Lifecycle Manager utilise par défaut des instantanés en cas de panne uniquement une fois que toutes les relances ont été épuisées. Si le pré-script échoue et que vous n’utilisez pas par défaut des instantanés en cas de panne, Amazon Data Lifecycle Manager ne crée pas d’instantanés pour l’instance pendant cette exécution planifiée.
**Note**  
Si vous créez des instantanés pour SAP HANA, vous souhaiterez peut-être désactiver cette option. Les instantanés en cas de panne des charges de travail SAP HANA ne peuvent pas être restaurés de la même manière.

1. Choisissez **Créer une politique par défaut**.
**Note**  
Si vous obtenez l’erreur `Role with name AWSDataLifecycleManagerDefaultRole already exists`, consultez [Résoudre les problèmes liés à Amazon Data Lifecycle Manager](dlm-troubleshooting.md) pour plus d’informations.

------
#### [ AWS CLI ]

**Pour créer la politique de cycle de vie des instantanés**  
Utilisez la [create-lifecycle-policy](https://docs.aws.amazon.com/cli/latest/reference/dlm/create-lifecycle-policy.html)commande et incluez les `Scripts` paramètres dans`CreateRule`. Pour plus d’informations sur les paramètres, consultez la [https://docs.aws.amazon.com/dlm/latest/APIReference/API_Script.html](https://docs.aws.amazon.com/dlm/latest/APIReference/API_Script.html).

```
$ aws dlm create-lifecycle-policy \
--description "{{policy_description}}" \
--state ENABLED \
--execution-role-arn {{iam_role_arn}} \
--policy-details file:{{//policyDetails.json}}
```

Lorsque `policyDetails.json` inclut l’un des éléments suivants, selon votre cas d’utilisation :
+ **Sauvegarde VSS**

  ```
  {
      "PolicyType": "EBS_SNAPSHOT_MANAGEMENT",
      "ResourceTypes": [
          "INSTANCE"
      ],
      "TargetTags": [{
          "Key": "{{tag_key}}",
          "Value": "{{tag_value}}"
      }],
      "Schedules": [{
          "Name": "{{schedule_name}}",
          "CreateRule": {
              "CronExpression": "{{cron_for_creation_frequency}}", 
              "Scripts": [{ 
                  "ExecutionHandler":"AWS_VSS_BACKUP",
                  "ExecuteOperationOnScriptFailure":{{true|false}},
                  "MaximumRetryCount":{{retries (0-3)}}
              }]
          },
          "RetainRule": {
              "Count": {{retention_count}}
          }
      }]
  }
  ```
+ **Sauvegardes SAP HANA**

  ```
  {
      "PolicyType": "EBS_SNAPSHOT_MANAGEMENT",
      "ResourceTypes": [
          "INSTANCE"
      ],
      "TargetTags": [{
          "Key": "{{tag_key}}",
          "Value": "{{tag_value}}"
      }],
      "Schedules": [{
          "Name": "{{schedule_name}}",
          "CreateRule": {
              "CronExpression": "{{cron_for_creation_frequency}}", 
              "Scripts": [{ 
                  "Stages": ["PRE","POST"],
                  "ExecutionHandlerService":"AWS_SYSTEMS_MANAGER",
                  "ExecutionHandler":"AWSSystemsManagerSAP-CreateDLMSnapshotForSAPHANA",
                  "ExecuteOperationOnScriptFailure":{{true|false}},
                  "ExecutionTimeout":{{timeout_in_seconds (10-120)}}, 
                  "MaximumRetryCount":{{retries (0-3)}}
              }]
          },
          "RetainRule": {
              "Count": {{retention_count}}
          }
      }]
  }
  ```
+ **Document SSM personnalisé**

  ```
  {
      "PolicyType": "EBS_SNAPSHOT_MANAGEMENT",
      "ResourceTypes": [
          "INSTANCE"
      ],
      "TargetTags": [{
          "Key": "{{tag_key}}",
          "Value": "{{tag_value}}"
      }],
      "Schedules": [{
          "Name": "{{schedule_name}}",
          "CreateRule": {
              "CronExpression": "{{cron_for_creation_frequency}}", 
              "Scripts": [{ 
                  "Stages": ["PRE","POST"],
                  "ExecutionHandlerService":"AWS_SYSTEMS_MANAGER",
                  "ExecutionHandler":"{{ssm_document_name|arn}}",
                  "ExecuteOperationOnScriptFailure":{{true|false}},
                  "ExecutionTimeout":{{timeout_in_seconds (10-120)}}, 
                  "MaximumRetryCount":{{retries (0-3)}}
              }]
          },
          "RetainRule": {
              "Count": {{retention_count}}
          }
      }]
  }
  ```

------

## Considérations relatives aux sauvegardes VSS avec Amazon Data Lifecycle Manager
<a name="app-consistent-vss"></a>

Avec Amazon Data Lifecycle Manager, vous pouvez sauvegarder et restaurer les applications Windows compatibles avec VSS (Volume Shadow Copy Service) exécutées sur des instances Amazon EC2. Si l’application possède un enregistreur VSS enregistré auprès de Windows VSS, Amazon Data Lifecycle Manager crée un instantané qui sera cohérent avec l’application pour cette application.

**Note**  
Amazon Data Lifecycle Manager ne prend actuellement en charge que les instantanés cohérents par rapport à l’application des ressources exécutées sur Amazon EC2, en particulier pour les scénarios de sauvegarde dans lesquels les données d’application peuvent être restaurées en remplaçant une instance existante par une nouvelle instance créée à partir de la sauvegarde. Les types d’instances ou applications ne sont pas tous pris en charge pour les sauvegardes VSS. *Pour plus d'informations, consultez la section [Instantanés Windows VSS cohérents avec les applications](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/application-consistent-snapshots.html) dans le guide de l'utilisateur Amazon EC2.* 

**Types d’instance non pris en charge**  
Les types d’instances Amazon EC2 suivants ne sont pas pris en charge pour les sauvegardes VSS. Si votre politique cible l’un de ces types d’instances, Amazon Data Lifecycle Manager peut toujours créer des sauvegardes VSS, mais les instantanés risquent de ne pas être balisés avec les balises système requises. Sans ces balises, les instantanés ne seront pas gérés par Amazon Data Lifecycle Manager après leur création. Vous aurez peut-être besoin de supprimer ces instantanés manuellement.
+ T3 : `t3.nano` \| `t3.micro`
+ T3a : `t3a.nano` \| `t3a.micro`
+ T2 : `t2.nano` \| `t2.micro`

## Responsabilité partagée pour les instantanés cohérents par rapport à l’application
<a name="shared-responsibility"></a>

**Vous devez vous assurer que :**
+ L'agent SSM est installé et up-to-date s'exécute sur vos instances cibles
+ Systems Manager est autorisé à effectuer les actions requises sur les instances cibles
+ Amazon Data Lifecycle Manager est autorisé à effectuer les actions Systems Manager requises pour exécuter des pré-scripts et des post-scripts sur les instances cibles.
+ Pour les charges de travail personnalisées, telles que les bases de données MySQL, PostgreSQL ou InterSystems IRIS autogérées, le document SSM que vous utilisez inclut les actions correctes et requises pour geler, vider et décongeler la configuration de votre base de données. I/O 
+ Les délais de création d’instantanés correspondent à votre planification de charge de travail. Par exemple, essayez de planifier la création d’instantanés pendant les fenêtres de maintenance planifiées.

**Amazon Data Lifecycle Manager garantit que :**
+ la création d’instantanés démarre dans les 60 minutes suivant l’heure de création d’instantanés prévue ;
+ les pré-scripts s’exécutent avant le lancement de la création d’instantanés ;
+ les post-scripts s’exécutent une fois que le pré-script a réussi et que la création d’instantanés a été lancée ; Amazon Data Lifecycle Manager exécute le post-script uniquement si le pré-script aboutit ; si le pré-script échoue, Amazon Data Lifecycle Manager n’exécute pas le post-script ;
+ les instantanés sont balisés avec les balises appropriées lors de leur création ;
+ CloudWatch les métriques et les événements sont émis lorsque les scripts sont lancés et lorsqu'ils échouent ou réussissent.