github.skymusic.top/operator-framework/operator-sdk@v0.8.2/doc/ansible/dev/finalizers.md (about)

     1  # Handling deletion events
     2  
     3  The default behavior of an Ansible Operator is to delete all resources the operator
     4  created during reconciliation when a managed resource is marked for deletion. This
     5  behavior is usually sufficient for applications that exist only in Kubernetes, but
     6  sometimes it is necessary to perform more complex operations (for example, when
     7  your action performed against a third party API needs to be undone). These more
     8  complex cases can still be handled by Ansible Operator, through the use of a finalizer.
     9  
    10  Finalizers allow controllers (such as an Ansible Operator) to implement asynchronous pre-delete hooks.
    11  This allows custom logic to run after a resource has been marked for deletion, but
    12  before the resource has actually been deleted from the Kubernetes cluster.
    13  For Ansible Operator, this hook takes the form of an Ansible playbook or role. You can
    14  define the mapping from your finalizer to a playbook or role by simply setting the
    15  `finalizer` field on the entry in your `watches.yaml`. You can also choose to re-run
    16  your top-level playbook or role with different variables set. The `watches.yaml`
    17  finalizer configuration accepts the following options:
    18  
    19  
    20  #### name
    21  `name` is required.
    22  
    23  This is the name of the finalizer. This is basically an arbitrary string, the existence
    24  of any finalizer string on a resource will prevent that resource from being deleted until
    25  the finalizer is removed. Ansible Operator will remove this string from the list of
    26  finalizers on successful execution of the specified role or playbook. A typical finalizer
    27  will be `finalizer.<group>`, where `<group>` is the group of the resource being managed.
    28  
    29  #### playbook
    30  
    31  One of `playbook`, `role`, or `vars` must be provided. If `playbook` is not provided, it
    32  will default to the playbook specified at the top level of the `watches.yaml`
    33  entry.
    34  
    35  This field is identical to the top-level `playbook` field. It requires an absolute
    36  path to a playbook on the operator’s file system.
    37  
    38  #### role
    39  
    40  One of `playbook`, `role`, or `vars` must be provided. If `role` is not provided, it
    41  will default to the role specified at the top level of the `watches.yaml` entry.
    42  
    43  This field is identical to the top-level `role` field. It requires an absolute
    44  path to a role on the operator’s file system.
    45  
    46  #### vars
    47  
    48  One of `playbook`, `role`, or `vars` must be provided.
    49  
    50  `vars` is an arbitrary map of key-value pairs. The contents of `vars` will be passed as `extra_vars` to the
    51  playbook or role specified in the finalizer block, or at the top-level if neither `playbook`
    52  or `role` was set for the finalizer.
    53  
    54  ## Examples
    55  
    56  Here are a few examples of `watches.yaml` files that specify a finalizer:
    57  
    58  ### Run top-level playbook or role with new variables
    59  ```yaml
    60  ---
    61  - version: v1alpha1
    62    group: app.example.com
    63    kind: Database
    64    playbook: /opt/ansible/playbook.yml
    65    finalizer:
    66      name: finalizer.app.example.com
    67      vars:
    68        state: absent
    69  ```
    70  
    71  This example will run `/opt/ansible/playbook.yml` when the Custom Resource
    72  is deleted. Because `vars` is set, the playbook will be run with `state` set to `absent`. Inside the playbook,
    73  the author can check this value and perform whatever cleanup is necessary.
    74  
    75  ```yaml
    76  ---
    77  - version: v1alpha1
    78    group: app.example.com
    79    kind: Database
    80    role: /opt/ansible/roles/database
    81    finalizer:
    82      name: finalizer.app.example.com
    83      vars:
    84        state: absent
    85  ```
    86  
    87  This example is nearly identical to the first, except it will run the `/opt/ansible/roles/database`
    88  role, rather than a playbook, with the `state` variable set to `absent`.
    89  
    90  ### Run a different playbook or role
    91  ```yaml
    92  ---
    93  - version: v1alpha1
    94    group: app.example.com
    95    kind: Database
    96    playbook: /opt/ansible/playbook.yml
    97    finalizer:
    98      name: finalizer.app.example.com
    99      role: /opt/ansible/roles/teardown_database
   100  ```
   101  
   102  This example will run the `/opt/ansible/roles/teardown_database` role when the Custom Resource is deleted.
   103  
   104  ```yaml
   105  ---
   106  - version: v1alpha1
   107    group: app.example.com
   108    kind: Database
   109    playbook: /opt/ansible/playbook.yml
   110    finalizer:
   111      name: finalizer.app.example.com
   112      playbook: /opt/ansible/destroy.yml
   113  ```
   114  
   115  This example will run the `/opt/ansible/destroy.yml` playbook when the Custom Resource is deleted.
   116  
   117  ### Run a different playbook or role with vars
   118  
   119  You can set `playbook` or `role` and `vars` at the same time. This can be useful if only a small
   120  part of your logic handles interacting with the component that requires cleanup. Rather than
   121  run all the logic again, you can specify only to run the role or playbook that handled the
   122  interaction, with a different variable set.
   123  
   124  ```yaml
   125  ---
   126  - version: v1alpha1
   127    group: app.example.com
   128    kind: Database
   129    playbook: /opt/ansible/playbook.yml
   130    finalizer:
   131      name: finalizer.app.example.com
   132      role: /opt/ansible/roles/manage_credentials
   133      vars:
   134        state: revoked
   135  ```
   136  
   137  
   138  For this example, assume our application configures automated backups to a third party service.
   139  On deletion, all we want to do is revoke the credentials used to backup the data. We run
   140  just the `/opt/ansible/roles/manage_credentials` role, which is imported by our playbook to
   141  create the credentials in the first place, but we pass the `state: revoked` option, which
   142  causes the role to invalidate our credentials. For everything else in our application,
   143  automatic deletion of dependent resources will be sufficient, so we can exit successfully and
   144  let the operator remove our finalizer and allow the resource to be deleted.
   145  
   146  ## Further reading
   147  • [Kubernetes finalizers](https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/#finalizers)