|
6 | 6 | "_generator": { |
7 | 7 | "name": "bicep", |
8 | 8 | "version": "0.33.93.31351", |
9 | | - "templateHash": "18381383220572173991" |
| 9 | + "templateHash": "7878072835611628906" |
10 | 10 | } |
11 | 11 | }, |
12 | 12 | "functions": [ |
|
43 | 43 | "description": "A Remote Configuration-enabled API key for the Datadog account\n(see https://app.datadoghq.com/organization-settings/api-keys).\n" |
44 | 44 | } |
45 | 45 | }, |
| 46 | + "datadogAppKey": { |
| 47 | + "type": "securestring", |
| 48 | + "defaultValue": "", |
| 49 | + "metadata": { |
| 50 | + "description": "[Optional] A Datadog application key. If provided, it will be used to\nautomatically enable Agentless Scanning on the selected subscriptions.\n" |
| 51 | + } |
| 52 | + }, |
46 | 53 | "datadogSite": { |
47 | 54 | "type": "string", |
48 | 55 | "defaultValue": "datadoghq.com", |
|
137 | 144 | "metadata": { |
138 | 145 | "description": "Tags to apply to all resources." |
139 | 146 | } |
| 147 | + }, |
| 148 | + "_forceUpdateTag": { |
| 149 | + "type": "string", |
| 150 | + "defaultValue": "[utcNow()]", |
| 151 | + "metadata": { |
| 152 | + "description": "[Internal: do not change] Tag to force an update to the Datadog Agentless Scanning options." |
| 153 | + } |
140 | 154 | } |
141 | 155 | }, |
142 | 156 | "variables": { |
143 | | - "$fxv#0": "#!/bin/bash\nset +x\nset -u\nset -e\nset -o pipefail\n\nfatal_error () {\n printf \"FATAL ERROR: shutting down\\n\"\n shutdown -h now\n}\n\ntrap 'fatal_error' ERR\n\n# Remove SSH mock public key\nsed -i '/.*${ssh_mock_public_key}.*/d' '${ssh_authorized_keys_file}'\n\n# Enable the nbd module\nmodprobe nbd nbds_max=128\necho \"nbd\" > /etc/modules-load.d/nbd.conf\necho \"options nbd nbds_max=128\" > /etc/modprobe.d/nbd.conf\n\n# Install requirements\napt update\napt install -y curl\n\n# Remove uneeded packages\napt remove -y libx11-6\napt autoremove -y\n\n# Perform unattended upgrades\nunattended-upgrade -v\n\nre='@Microsoft.KeyVault\\(SecretUri=(https://.*)\\)'\nif [[ \"${api_key}\" =~ $re ]]; then\n echo \"Datadog API key is a Key Vault reference\"\n DD_API_KEY=\"ENC[${api_key}]\"\nelse\n DD_API_KEY=\"${api_key}\"\nfi\n\n# Append the last 6 bytes of the VM UUID to prevent hostname collisions\nVM_ID=$(cat /sys/devices/virtual/dmi/id/product_uuid)\nDD_HOSTNAME=\"$(hostname)-${VM_ID:(-12)}\"\nDD_SITE=\"${site}\"\nDD_AGENTLESS_VERSION=\"${scanner_version}\"\nDD_AGENTLESS_CHANNEL=\"${scanner_channel}\"\n\nhostnamectl hostname \"$DD_HOSTNAME\"\n\n# Install the agent\nDD_INSTALL_ONLY=true \\\n DD_API_KEY=\"TBD\" \\\n DD_SITE=\"$DD_SITE\" \\\n DD_HOSTNAME=\"$DD_HOSTNAME\" \\\n bash -c \"$(curl -L https://s3.amazonaws.com/dd-agent/scripts/install_script_agent7.sh)\"\n\n# Install the agentless-scanner\necho \"deb [signed-by=/usr/share/keyrings/datadog-archive-keyring.gpg] https://apt.datadoghq.com/ $DD_AGENTLESS_CHANNEL agentless-scanner\" >> /etc/apt/sources.list.d/datadog.list\napt update\nagentless_pkg_pattern=\"([[:digit:]]:)?$DD_AGENTLESS_VERSION(\\.[[:digit:]]+){0,1}(~rc\\.[[:digit:]]+)?(-[[:digit:]])?\"\nagentless_version_custom=\"$(apt-cache madison datadog-agentless-scanner | grep -E \"$agentless_pkg_pattern\" -om1)\" || true\nif [ -z \"$agentless_version_custom\" ]; then\n printf \"Could not find a version of datadog-agentless-scanner from %s\" \"$DD_AGENTLESS_VERSION\"\n exit 1\nfi\n# We mask/unmask because apt auto-starts the service, and we do\n# not want to start it before the configuration is in place.\nsystemctl mask datadog-agentless-scanner.service\napt install -y \"datadog-agentless-scanner=$agentless_version_custom\"\nsystemctl unmask datadog-agentless-scanner.service\n\n# Adding automatic reboot on kernel updates\ncat << EOF >> /etc/apt/apt.conf.d/50unattended-upgrades\nUnattended-Upgrade::Automatic-Reboot \"true\";\nUnattended-Upgrade::Automatic-Reboot-WithUsers \"true\";\nUnattended-Upgrade::Automatic-Reboot-Time \"now\";\nEOF\n\n# Perform unattended upgrades 10 min after boot, then every 3 hours\ncat << EOF > /etc/systemd/system/apt-daily-upgrade.timer\n[Unit]\nDescription=Daily apt upgrade and clean activities\nAfter=apt-daily.timer\n\n[Timer]\nOnActiveSec=10min\nOnCalendar=0/3:00:00\nPersistent=true\n\n[Install]\nWantedBy=timers.target\nEOF\n\nsystemctl daemon-reload\nsystemctl restart apt-daily-upgrade.timer\n\n# Activate agentless scanner logging\nmkdir -p /etc/datadog-agent/conf.d/agentless-scanner.d\ncat <<EOF > /etc/datadog-agent/conf.d/agentless-scanner.d/conf.yaml\nlogs:\n - type: file\n path: \"/var/log/datadog/agentless-scanner.log\"\n service: \"agentless-scanner\"\n source: go\n sourcecategory: sourcecode\nEOF\n\nchown -R dd-agent: /etc/datadog-agent/conf.d/agentless-scanner.d\n\n# Custom configuration for agent\ncat <<EOF > /etc/datadog-agent/datadog.yaml\napi_key: $DD_API_KEY\nsite: $DD_SITE\nhostname: $DD_HOSTNAME\nlogs_enabled: true\nec2_prefer_imdsv2: true\nsecret_backend_command: /usr/local/bin/dd-secret-backend\nEOF\n\ncat <<EOF > /usr/local/bin/dd-secret-backend\n#!/bin/bash\ndatadog-agentless-scanner secrets || exit 1\nEOF\nchown dd-agent: /usr/local/bin/dd-secret-backend\nchmod 700 /usr/local/bin/dd-secret-backend\n\ncat <<EOF > /etc/datadog-agent/agentless-scanner.yaml\nhostname: $DD_HOSTNAME\napi_key: $DD_API_KEY\nsite: $DD_SITE\nazure_client_id: ${azure_client_id}\ninstallation_mode: terraform\ninstallation_version: 0.11.6\nEOF\n\nchown dd-agent: /etc/datadog-agent/agentless-scanner.yaml\nchmod 600 /etc/datadog-agent/agentless-scanner.yaml\n\n# Restart the agent\nsystemctl restart datadog-agent\n\n# Stop the scanner after 24 hours. This will cause the health\n# probe to fail and trigger an automatic instance replacement.\nsystemd-run --on-boot=24h systemctl stop datadog-agentless-scanner\n\n# Enable and start datadog-agentless-scaner\nsystemctl enable --now datadog-agentless-scanner\n", |
| 157 | + "$fxv#0": "function Set-AzureAgentlessOptions {\n [CmdletBinding()]\n param (\n [Parameter(Mandatory, ValueFromPipeline)]\n [Guid[]]$Subscriptions,\n [Parameter(Mandatory)]\n [string]$DatadogSite,\n [Parameter(Mandatory, HelpMessage = \"Datadog API Key\")]\n [ValidatePattern(\"^[0-9a-f]{32}$\")]\n [string]$APIKey,\n [Parameter(Mandatory, HelpMessage = \"Datadog Application Key\")]\n [ValidatePattern(\"^[0-9a-f]{40}$\")]\n [string]$ApplicationKey\n )\n begin {\n $url = \"https://api.${DatadogSite}/api/v2/agentless_scanning/accounts/azure\"\n $headers = @{\n 'DD-API-KEY' = $APIKey\n 'DD-APPLICATION-KEY' = $ApplicationKey\n 'Dd-Call-Source' = \"arm-agentless\"\n }\n }\n process {\n $subscription_id = $_.ToString()\n $body = @{\n \"data\" = @{\n \"id\" = $subscription_id\n \"type\" = \"azure_scan_options\"\n \"attributes\" = @{\n \"vuln_containers_os\" = $true\n \"vuln_host_os\" = $true\n }\n }\n } | ConvertTo-Json\n\n $result = Invoke-RestMethod -Method POST -Uri $url -Headers $headers -Body $body -SkipHttpErrorCheck -StatusCodeVariable status\n if ($status -eq 409) {\n # Subscription already exists; update it instead\n $result = Invoke-RestMethod -Method PATCH -Uri \"${url}/${subscription_id}\" -Headers $headers -Body $body -SkipHttpErrorCheck -StatusCodeVariable status\n }\n if ($status -ge 200 -and $status -lt 300) {\n Write-Output \"Successfully enabled Agentless Scanning for subscription ${subscription_id}\"\n }\n else {\n Write-Error \"Failed to enable Agentless Scanning for subscription ${subscription_id}: $(ConvertTo-Json -Compress $result)\"\n }\n }\n}\n\nfunction Convert-ScopeToSubscriptionId {\n [CmdletBinding()]\n param (\n [Parameter(Mandatory, ValueFromPipeline)]\n [string[]]$Scopes\n )\n process {\n $scope = $_.Trim()\n if ($scope -match '^/subscriptions/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(/|$)') {\n return $Matches[1]\n }\n Write-Warning \"Ignoring scope: $scope\"\n }\n}\n\n${env:SCAN_SCOPES} |\nConvertFrom-Json |\nConvert-ScopeToSubscriptionId |\nSort-Object |\nGet-Unique |\nSet-AzureAgentlessOptions -APIKey ${env:DD_API_KEY} -ApplicationKey ${env:DD_APP_KEY} -DatadogSite ${env:DD_SITE}\n", |
| 158 | + "$fxv#1": "#!/bin/bash\nset +x\nset -u\nset -e\nset -o pipefail\n\nfatal_error () {\n printf \"FATAL ERROR: shutting down\\n\"\n shutdown -h now\n}\n\ntrap 'fatal_error' ERR\n\n# Remove SSH mock public key\nsed -i '/.*${ssh_mock_public_key}.*/d' '${ssh_authorized_keys_file}'\n\n# Enable the nbd module\nmodprobe nbd nbds_max=128\necho \"nbd\" > /etc/modules-load.d/nbd.conf\necho \"options nbd nbds_max=128\" > /etc/modprobe.d/nbd.conf\n\n# Install requirements\napt update\napt install -y curl\n\n# Remove uneeded packages\napt remove -y libx11-6\napt autoremove -y\n\n# Perform unattended upgrades\nunattended-upgrade -v\n\nre='@Microsoft.KeyVault\\(SecretUri=(https://.*)\\)'\nif [[ \"${api_key}\" =~ $re ]]; then\n echo \"Datadog API key is a Key Vault reference\"\n DD_API_KEY=\"ENC[${api_key}]\"\nelse\n DD_API_KEY=\"${api_key}\"\nfi\n\n# Append the last 6 bytes of the VM UUID to prevent hostname collisions\nVM_ID=$(cat /sys/devices/virtual/dmi/id/product_uuid)\nDD_HOSTNAME=\"$(hostname)-${VM_ID:(-12)}\"\nDD_SITE=\"${site}\"\nDD_AGENTLESS_VERSION=\"${scanner_version}\"\nDD_AGENTLESS_CHANNEL=\"${scanner_channel}\"\n\nhostnamectl hostname \"$DD_HOSTNAME\"\n\n# Install the agent\nDD_INSTALL_ONLY=true \\\n DD_API_KEY=\"TBD\" \\\n DD_SITE=\"$DD_SITE\" \\\n DD_HOSTNAME=\"$DD_HOSTNAME\" \\\n bash -c \"$(curl -L https://s3.amazonaws.com/dd-agent/scripts/install_script_agent7.sh)\"\n\n# Install the agentless-scanner\necho \"deb [signed-by=/usr/share/keyrings/datadog-archive-keyring.gpg] https://apt.datadoghq.com/ $DD_AGENTLESS_CHANNEL agentless-scanner\" >> /etc/apt/sources.list.d/datadog.list\napt update\nagentless_pkg_pattern=\"([[:digit:]]:)?$DD_AGENTLESS_VERSION(\\.[[:digit:]]+){0,1}(~rc\\.[[:digit:]]+)?(-[[:digit:]])?\"\nagentless_version_custom=\"$(apt-cache madison datadog-agentless-scanner | grep -E \"$agentless_pkg_pattern\" -om1)\" || true\nif [ -z \"$agentless_version_custom\" ]; then\n printf \"Could not find a version of datadog-agentless-scanner from %s\" \"$DD_AGENTLESS_VERSION\"\n exit 1\nfi\n# We mask/unmask because apt auto-starts the service, and we do\n# not want to start it before the configuration is in place.\nsystemctl mask datadog-agentless-scanner.service\napt install -y \"datadog-agentless-scanner=$agentless_version_custom\"\nsystemctl unmask datadog-agentless-scanner.service\n\n# Adding automatic reboot on kernel updates\ncat << EOF >> /etc/apt/apt.conf.d/50unattended-upgrades\nUnattended-Upgrade::Automatic-Reboot \"true\";\nUnattended-Upgrade::Automatic-Reboot-WithUsers \"true\";\nUnattended-Upgrade::Automatic-Reboot-Time \"now\";\nEOF\n\n# Perform unattended upgrades 10 min after boot, then every 3 hours\ncat << EOF > /etc/systemd/system/apt-daily-upgrade.timer\n[Unit]\nDescription=Daily apt upgrade and clean activities\nAfter=apt-daily.timer\n\n[Timer]\nOnActiveSec=10min\nOnCalendar=0/3:00:00\nPersistent=true\n\n[Install]\nWantedBy=timers.target\nEOF\n\nsystemctl daemon-reload\nsystemctl restart apt-daily-upgrade.timer\n\n# Activate agentless scanner logging\nmkdir -p /etc/datadog-agent/conf.d/agentless-scanner.d\ncat <<EOF > /etc/datadog-agent/conf.d/agentless-scanner.d/conf.yaml\nlogs:\n - type: file\n path: \"/var/log/datadog/agentless-scanner.log\"\n service: \"agentless-scanner\"\n source: go\n sourcecategory: sourcecode\nEOF\n\nchown -R dd-agent: /etc/datadog-agent/conf.d/agentless-scanner.d\n\n# Custom configuration for agent\ncat <<EOF > /etc/datadog-agent/datadog.yaml\napi_key: $DD_API_KEY\nsite: $DD_SITE\nhostname: $DD_HOSTNAME\nlogs_enabled: true\nec2_prefer_imdsv2: true\nsecret_backend_command: /usr/local/bin/dd-secret-backend\nEOF\n\ncat <<EOF > /usr/local/bin/dd-secret-backend\n#!/bin/bash\ndatadog-agentless-scanner secrets || exit 1\nEOF\nchown dd-agent: /usr/local/bin/dd-secret-backend\nchmod 700 /usr/local/bin/dd-secret-backend\n\ncat <<EOF > /etc/datadog-agent/agentless-scanner.yaml\nhostname: $DD_HOSTNAME\napi_key: $DD_API_KEY\nsite: $DD_SITE\nazure_client_id: ${azure_client_id}\ninstallation_mode: terraform\ninstallation_version: 0.11.6\nEOF\n\nchown dd-agent: /etc/datadog-agent/agentless-scanner.yaml\nchmod 600 /etc/datadog-agent/agentless-scanner.yaml\n\n# Restart the agent\nsystemctl restart datadog-agent\n\n# Stop the scanner after 24 hours. This will cause the health\n# probe to fail and trigger an automatic instance replacement.\nsystemd-run --on-boot=24h systemctl stop datadog-agentless-scanner\n\n# Enable and start datadog-agentless-scaner\nsystemctl enable --now datadog-agentless-scanner\n", |
144 | 159 | "sshMockPublicKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJWFDAB+VRKsHvHjIyiEN9izvhaosXAUMG1jPMo9hcnE", |
145 | 160 | "sshAuthorizedKeysFile": "[format('/home/{0}/.ssh/authorized_keys', parameters('adminUsername'))]", |
146 | 161 | "tags": "[union(parameters('resourceTags'), createObject('Datadog', 'true', 'DatadogAgentlessScanner', 'true'))]", |
|
173 | 188 | "osProfile": { |
174 | 189 | "computerNamePrefix": "agentless-scanning-", |
175 | 190 | "adminUsername": "[parameters('adminUsername')]", |
176 | | - "customData": "[base64(__bicep.replaceMultiple(variables('$fxv#0'), createObject('${api_key}', parameters('datadogAPIKey'), '${site}', parameters('datadogSite'), '${scanner_version}', parameters('scannerVersion'), '${scanner_channel}', parameters('scannerChannel'), '${scanner_repository}', parameters('scannerRepository'), '${azure_client_id}', reference('managedIdentity').clientId, '${ssh_mock_public_key}', variables('sshMockPublicKey'), '${ssh_authorized_keys_file}', variables('sshAuthorizedKeysFile'))))]", |
| 191 | + "customData": "[base64(__bicep.replaceMultiple(variables('$fxv#1'), createObject('${api_key}', parameters('datadogAPIKey'), '${site}', parameters('datadogSite'), '${scanner_version}', parameters('scannerVersion'), '${scanner_channel}', parameters('scannerChannel'), '${scanner_repository}', parameters('scannerRepository'), '${azure_client_id}', reference('managedIdentity').clientId, '${ssh_mock_public_key}', variables('sshMockPublicKey'), '${ssh_authorized_keys_file}', variables('sshAuthorizedKeysFile'))))]", |
177 | 192 | "linuxConfiguration": { |
178 | 193 | "disablePasswordAuthentication": true, |
179 | 194 | "ssh": { |
|
508 | 523 | "publicIPAllocationMethod": "Static" |
509 | 524 | } |
510 | 525 | }, |
| 526 | + "ddApiCall": { |
| 527 | + "condition": "[not(equals(parameters('datadogAppKey'), ''))]", |
| 528 | + "type": "Microsoft.Resources/deploymentScripts", |
| 529 | + "apiVersion": "2023-08-01", |
| 530 | + "name": "[format('{0}-ApiCall', variables('name'))]", |
| 531 | + "location": "[resourceGroup().location]", |
| 532 | + "tags": "[variables('tags')]", |
| 533 | + "kind": "AzurePowerShell", |
| 534 | + "properties": { |
| 535 | + "azPowerShellVersion": "12.3", |
| 536 | + "environmentVariables": [ |
| 537 | + { |
| 538 | + "name": "DD_API_KEY", |
| 539 | + "secureValue": "[parameters('datadogAPIKey')]" |
| 540 | + }, |
| 541 | + { |
| 542 | + "name": "DD_APP_KEY", |
| 543 | + "secureValue": "[parameters('datadogAppKey')]" |
| 544 | + }, |
| 545 | + { |
| 546 | + "name": "DD_SITE", |
| 547 | + "value": "[parameters('datadogSite')]" |
| 548 | + }, |
| 549 | + { |
| 550 | + "name": "SCAN_SCOPES", |
| 551 | + "value": "[string(parameters('scanScopes'))]" |
| 552 | + }, |
| 553 | + { |
| 554 | + "name": "NO_COLOR", |
| 555 | + "value": "true" |
| 556 | + } |
| 557 | + ], |
| 558 | + "forceUpdateTag": "[parameters('_forceUpdateTag')]", |
| 559 | + "scriptContent": "[variables('$fxv#0')]", |
| 560 | + "retentionInterval": "P1D", |
| 561 | + "timeout": "PT10M", |
| 562 | + "cleanupPreference": "OnExpiration" |
| 563 | + } |
| 564 | + }, |
511 | 565 | "delegateRoleAssignments": { |
512 | 566 | "copy": { |
513 | 567 | "name": "delegateRoleAssignments", |
|
0 commit comments