diff --git a/README.md b/README.md
index 4878c177..257a7d4a 100644
--- a/README.md
+++ b/README.md
@@ -47,9 +47,9 @@ To deploy the Datadog Agent on hosts, add the Datadog role and your API key to y
| `datadog_disable_default_checks` | Set to `true` to remove all default checks. |
| `datadog_config` | Settings for the main Agent configuration file:
- `/etc/datadog-agent/datadog.yaml` for Agent v6 and v7,
- `/etc/dd-agent/datadog.conf` for Agent v5 (under the `[Main]` section). |
| `datadog_config_ex` | (Optional) Extra INI sections to go in `/etc/dd-agent/datadog.conf` (Agent v5 only). |
-| `datadog_apt_repo` | Override the default Datadog `apt` repository. |
+| `datadog_apt_repo` | Override the default Datadog `apt` repository. Make sure to use the `signed-by` option if repository metadata is signed using Datadog's signing keys: `deb [signed-by=/usr/share/keyrings/datadog-archive-keyring.gpg] https://yourrepo`. |
| `datadog_apt_cache_valid_time` | Override the default apt cache expiration time (defaults to 1 hour). |
-| `datadog_apt_key_url_new` | Override the default URL to Datadog `apt` key (key ID `382E94DE`; the deprecated `datadog_apt_key_url` variable refers to an expired key that's been removed from the role). |
+| `datadog_apt_key_url_new` | Override the location from which to obtain Datadog `apt` key (the deprecated `datadog_apt_key_url` variable refers to an expired key that's been removed from the role). The URL is expected to be a GPG keyring containing keys `382E94DE` and `F14F620E`. |
| `datadog_yum_repo` | Override the default Datadog `yum` repository. |
| `datadog_yum_repo_gpgcheck` | Override the default `repo_gpgcheck` value (`yes`) - use `no` to turn off repodata GPG signature verification. Note that repodata signature verification is always turned off for Agent 5. |
| `datadog_yum_gpgcheck` | Override the default `gpgcheck` value (`yes`) - use `no` to turn off package GPG signature verification. |
@@ -64,7 +64,6 @@ To deploy the Datadog Agent on hosts, add the Datadog role and your API key to y
| `datadog_zypper_gpgkey_e09422b3` | Override the default URL to the Datadog `zypper` key used to verify Agent v6.14+ packages (key ID `E09422B3`). |
| `datadog_zypper_gpgkey_e09422b3_sha256sum` | Override the default checksum of the `datadog_zypper_gpgkey_e09422b3` key. |
| `datadog_agent_allow_downgrade` | Set to `yes` to allow Agent downgrades on apt-based platforms (use with caution, see `defaults/main.yml` for details). **Note**: On Centos this only works with Ansible 2.4+. |
-| `use_apt_backup_keyserver` | Set to `true` to use the backup keyserver instead of the default one. |
| `datadog_enabled` | Set to `false` to prevent `datadog-agent` service from starting (defaults to `true`). |
| `datadog_additional_groups` | Either a list, or a string containing a comma-separated list of additional groups for the `datadog_user` (Linux only). |
| `datadog_windows_ddagentuser_name` | The name of Windows user to create/use, in the format `\` (Windows only). |
@@ -262,6 +261,8 @@ If you previously used the Agent v5 variables, use the **new** variables below w
| `datadog_agent5_yum_repo` | `datadog_yum_repo` |
| `datadog_agent5_zypper_repo` | `datadog_zypper_repo` |
+Since version 4.9.0, the `use_apt_backup_keyserver` variable has been removed, as APT keys are now obtained from https://keys.datadoghq.com.
+
#### Windows
When the variable `datadog_windows_download_url` is not set, the official Windows MSI package corresponding to the `datadog_agent_major_version` is used:
@@ -487,6 +488,8 @@ Alternatively, if your playbook **only runs on Windows hosts**, use the followin
### Debian stretch
+**Note:** this information applies to versions of the role prior to 4.9.0. Since 4.9.0, the `apt_key` module is no longer used by the role.
+
On Debian Stretch, the `apt_key` module used by the role requires an additional system dependency to work correctly. The dependency (`dirmngr`) is not provided by the module. Add the following configuration to your playbooks to make use of the present role:
```yml
@@ -498,7 +501,6 @@ On Debian Stretch, the `apt_key` module used by the role requires an additional
apt:
name: dirmngr
state: present
-
roles:
- { role: datadog.datadog, become: yes }
vars:
diff --git a/defaults/main.yml b/defaults/main.yml
index 3c65a9de..8c51082f 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -59,12 +59,8 @@ datadog_agent_flavor: "datadog-agent"
# Use the datadog_apt_repo variable to override the repository used.
datadog_apt_repo: ""
-
datadog_apt_cache_valid_time: 3600
datadog_apt_key_retries: 5
-use_apt_backup_keyserver: false
-datadog_apt_keyserver: hkp://keyserver.ubuntu.com:80
-datadog_apt_backup_keyserver: hkp://pool.sks-keyservers.net:80
# Default yum repo and keys
@@ -157,10 +153,23 @@ win_install_args: " "
# The following variables are for internal use only, do not modify them.
#
+datadog_apt_trusted_d_keyring: "/etc/apt/trusted.gpg.d/datadog-archive-keyring.gpg"
+datadog_apt_usr_share_keyring: "/usr/share/keyrings/datadog-archive-keyring.gpg"
+datadog_apt_key_current_name: "DATADOG_APT_KEY_CURRENT"
+# NOTE: we don't use URLs starting with https://keys.datadoghq.com/, as Python
+# on older Debian/Ubuntu doesn't support SNI and get_url would fail on them
+datadog_apt_default_keys:
+ - key: "{{ datadog_apt_key_current_name }}"
+ value: https://s3.amazonaws.com/public-signing-keys/DATADOG_APT_KEY_CURRENT.public
+ - key: A2923DFF56EDA6E76E55E492D3A80E30382E94DE
+ value: https://s3.amazonaws.com/public-signing-keys/DATADOG_APT_KEY_382E94DE.public
+ - key: D75CEA17048B9ACBF186794B32637D44F14F620E
+ value: https://s3.amazonaws.com/public-signing-keys/DATADOG_APT_KEY_F14F620E.public
+
# The default apt repository for each major Agent version is specified in the following variables.
-datadog_agent5_apt_repo: "deb https://apt.datadoghq.com/ stable main"
-datadog_agent6_apt_repo: "deb https://apt.datadoghq.com/ stable 6"
-datadog_agent7_apt_repo: "deb https://apt.datadoghq.com/ stable 7"
+datadog_agent5_apt_repo: "deb [signed-by={{ datadog_apt_usr_share_keyring }}] https://apt.datadoghq.com/ stable main"
+datadog_agent6_apt_repo: "deb [signed-by={{ datadog_apt_usr_share_keyring }}] https://apt.datadoghq.com/ stable 6"
+datadog_agent7_apt_repo: "deb [signed-by={{ datadog_apt_usr_share_keyring }}] https://apt.datadoghq.com/ stable 7"
# The default yum repository for each major Agent version is specified in the following variables.
datadog_agent5_yum_repo: "https://yum.datadoghq.com/rpm/{{ ansible_facts.architecture }}"
diff --git a/tasks/_apt-key-import.yml b/tasks/_apt-key-import.yml
new file mode 100644
index 00000000..7b3afe6d
--- /dev/null
+++ b/tasks/_apt-key-import.yml
@@ -0,0 +1,83 @@
+# We allow users to specify a file from which to import keys, so we expect
+# that to be a binary keyring; at the same time, we have ascii armored
+# individual keys at keys.datadoghq.com that we import. The below procedure
+# can be called for a URL pointing to a keyring or an ascii armored file
+# and extract and import a specific key from it (we specialcase the
+# DATADOG_APT_KEY_CURRENT value, which we always expect to be ascii
+# armored individual key).
+
+# NOTE: we use 'noqa risky-shell-pipe' throughout this file, because Debian's
+# default shell is /bin/sh which doesn't have a pipefail option and the
+# presence of a different shell isn't guaranteed.
+
+# NOTE: in order to display Ansible's `changed: [hostname]` properly throughout
+# tasks in this file, we added `changed_when: false` to a lot of them, even if
+# they actually run every time (e.g. importing the CURRENT key). The reason is
+# that they operate inside a temporary directory and they don't have a
+# permanent effect on the host (nothing will actually change on the host
+# whether these tasks run or not) except the last one - the actual import of
+# the key to `datadog_apt_usr_share_keyring`.
+
+- name: "Set local variables for processed key {{ item.key }}"
+ set_fact:
+ key_fingerprint: "{{ item.key }}"
+ keyring_url: "{{ item.value }}"
+
+- name: "Find out whether key {{ key_fingerprint }} is already imported"
+ shell: "gpg --no-default-keyring --keyring {{ datadog_apt_usr_share_keyring }} --list-keys --with-fingerprint --with-colons | grep {{ key_fingerprint }}" # noqa risky-shell-pipe
+ register: key_exists_result
+ failed_when: false # we expect the command to fail when the key is not found; we never want this task to fail
+ changed_when: key_exists_result.rc != 0
+ when: key_fingerprint != datadog_apt_key_current_name # we always want to import the CURRENT key
+
+- name: "Set local helper variable for determining key import (when not {{ datadog_apt_key_current_name }})"
+ set_fact:
+ key_needs_import: "{{ 'false' if key_exists_result.rc == 0 else 'true' }}"
+ when: key_fingerprint != datadog_apt_key_current_name
+
+- name: "Set local helper variable for determining key import (when {{ datadog_apt_key_current_name }})"
+ set_fact:
+ key_needs_import: "true"
+ when: key_fingerprint == datadog_apt_key_current_name
+
+- name: "Create temporary directory for key manipulation"
+ tempfile:
+ state: directory
+ suffix: keys
+ register: tempdir
+ when: key_needs_import
+ changed_when: false
+
+- name: "Download {{ keyring_url }} to import key {{ key_fingerprint }}"
+ get_url:
+ url: "{{ keyring_url }}"
+ dest: "{{ tempdir.path }}/{{ key_fingerprint }}"
+ force: yes
+ when: key_needs_import
+ changed_when: false
+
+# gpg --dearmor called on a binary keyring does nothing
+- name: "Ensure downloaded file for {{ key_fingerprint }} is a binary keyring"
+ shell: "cat {{ tempdir.path }}/{{ key_fingerprint }} | gpg --dearmor > {{ tempdir.path }}/binary.gpg" # noqa risky-shell-pipe
+ when: key_needs_import
+ changed_when: false
+
+- name: "Extract the required key from the binary keyring (when not {{ datadog_apt_key_current_name }})"
+ shell: "gpg --no-default-keyring --keyring {{ tempdir.path }}/binary.gpg --export {{ key_fingerprint }} > {{ tempdir.path }}/single.gpg"
+ when: key_fingerprint != datadog_apt_key_current_name and key_needs_import
+ changed_when: false
+
+- name: "Extract the required key from the binary keyring (when {{ datadog_apt_key_current_name }})"
+ copy:
+ src: "{{ tempdir.path }}/binary.gpg"
+ dest: "{{ tempdir.path }}/single.gpg"
+ mode: "0600"
+ remote_src: yes
+ when: key_fingerprint == datadog_apt_key_current_name and key_needs_import
+ changed_when: false
+
+- name: "Import key {{ key_fingerprint }} to {{ datadog_apt_usr_share_keyring }} keyring"
+ shell: "cat {{ tempdir.path }}/single.gpg | gpg --no-default-keyring --keyring {{ datadog_apt_usr_share_keyring }} --import --batch" # noqa risky-shell-pipe
+ when: key_needs_import
+ register: key_import_result
+ changed_when: '"imported: 1" in key_import_result.stderr'
diff --git a/tasks/pkg-debian.yml b/tasks/pkg-debian.yml
index 7f7c6c98..5367ddcd 100644
--- a/tasks/pkg-debian.yml
+++ b/tasks/pkg-debian.yml
@@ -6,43 +6,44 @@
state: present
when: not ansible_check_mode
-- name: Install apt-key from keyserver (Expires 2022)
- apt_key:
- id: A2923DFF56EDA6E76E55E492D3A80E30382E94DE
- keyserver: "{{ datadog_apt_backup_keyserver if use_apt_backup_keyserver else datadog_apt_keyserver }}"
- state: present
- # keyserver.ubuntu.com is a pool of server, we should retry if one of them is down
- register: result
- until: not result.failed is defined or not result.failed
- retries: "{{ datadog_apt_key_retries }}"
- when: datadog_apt_key_url_new is not defined
+- name: "Check if {{ datadog_apt_usr_share_keyring }} exists with correct mode"
+ stat:
+ path: "{{ datadog_apt_usr_share_keyring }}"
+ register: apt_keyring_file
-- name: Install Datadog apt-key from url (Expires 2022)
- apt_key:
- id: A2923DFF56EDA6E76E55E492D3A80E30382E94DE
- url: "{{ datadog_apt_key_url_new }}"
- state: present
- when: datadog_apt_key_url_new is defined
+- name: "Ensure {{ datadog_apt_usr_share_keyring }} exists"
+ file:
+ path: "{{ datadog_apt_usr_share_keyring }}"
+ owner: root
+ group: root
+ mode: "0644"
+ state: touch
+ when: not ansible_check_mode and (not apt_keyring_file.stat.exists or not apt_keyring_file.stat.mode == "0644")
-- name: Install apt-key from keyserver (Expires 2032)
- apt_key:
- id: D75CEA17048B9ACBF186794B32637D44F14F620E
- keyserver: "{{ datadog_apt_backup_keyserver if use_apt_backup_keyserver else datadog_apt_keyserver }}"
- state: present
- # keyserver.ubuntu.com is a pool of server, we should retry if one of them is down
- register: result_2032
- until: not result_2032.failed is defined or not result_2032.failed
- retries: "{{ datadog_apt_key_retries }}"
- when: datadog_apt_key_url_new is not defined
+- name: Install apt keys from default URLs
+ include_tasks: _apt-key-import.yml
+ with_items:
+ "{{ datadog_apt_default_keys }}"
+ when: datadog_apt_key_url_new is not defined and not ansible_check_mode
-- name: Install Datadog apt-key from url (Expires 2032)
- apt_key:
- id: D75CEA17048B9ACBF186794B32637D44F14F620E
- url: "{{ datadog_apt_key_url_new }}"
- state: present
- when: datadog_apt_key_url_new is defined
+- name: Install apt keys from custom URL
+ include_tasks: _apt-key-import.yml
+ with_items:
+ - key: A2923DFF56EDA6E76E55E492D3A80E30382E94DE
+ value: "{{ datadog_apt_key_url_new }}"
+ - key: D75CEA17048B9ACBF186794B32637D44F14F620E
+ value: "{{ datadog_apt_key_url_new }}"
+ when: datadog_apt_key_url_new is defined and not ansible_check_mode
+
+- name: "Ensure {{ datadog_apt_trusted_d_keyring }} exists with same contents as {{ datadog_apt_usr_share_keyring }} for older distro versions"
+ copy:
+ src: "{{ datadog_apt_usr_share_keyring }}"
+ dest: "{{ datadog_apt_trusted_d_keyring }}"
+ mode: "0644"
+ remote_src: yes
+ when: ((ansible_distribution == 'Debian' and ansible_lsb.major_release|int < 9) or (ansible_distribution == 'Ubuntu' and ansible_lsb.major_release|int < 16)) and not ansible_check_mode
-- name: Ensure Datadog non-https repositories are deprecated
+- name: Ensure Datadog non-https repositories and repositories not using signed-by option are deprecated
apt_repository:
repo: "{{ item }}"
state: "absent"
@@ -51,6 +52,9 @@
- "deb http://apt.datadoghq.com/ stable main"
- "deb http://apt.datadoghq.com/ stable 6"
- "deb http://apt.datadoghq.com/ stable 7"
+ - "deb https://apt.datadoghq.com/ stable main"
+ - "deb https://apt.datadoghq.com/ stable 6"
+ - "deb https://apt.datadoghq.com/ stable 7"
when: not ansible_check_mode
- name: Ensure Datadog repository is up-to-date