Commit graph

20 commits

Author SHA1 Message Date
Dan Guido
c495307027
Fix DigitalOcean cloud-init compatibility and deprecation warnings (#14801)
* Fix DigitalOcean cloud-init compatibility issue causing SSH timeout on port 4160

This commit addresses the issue described in GitHub issue #14800 where DigitalOcean
deployments fail during the "Wait until SSH becomes ready..." step due to cloud-init
not processing the write_files directive correctly.

## Problem
- DigitalOcean's cloud-init shows "Unhandled non-multipart (text/x-not-multipart) userdata" warning
- write_files module gets skipped, leaving SSH on default port 22 instead of port 4160
- Algo deployment times out when trying to connect to port 4160

## Solution
Added proactive detection and remediation to the DigitalOcean role:
1. Check if SSH is listening on the expected port (4160) after droplet creation
2. If not, automatically apply the SSH configuration manually via SSH on port 22
3. Verify SSH is now listening on the correct port before proceeding

## Changes
- Added SSH port check with 30-second timeout
- Added fallback remediation block that:
  - Connects via SSH on port 22 to apply Algo's SSH configuration
  - Backs up the original sshd_config
  - Applies the correct SSH settings (port 4160, security hardening)
  - Restarts the SSH service
  - Verifies the fix worked

This ensures DigitalOcean deployments succeed even when cloud-init fails to process
the user_data correctly, maintaining backward compatibility and reliability.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Implement cleaner fix for DigitalOcean cloud-init encoding issue

This replaces the previous workaround with two targeted fixes that address
the root cause of the "Unhandled non-multipart (text/x-not-multipart) userdata"
issue that prevents write_files from being processed.

## Root Cause
Cloud-init receives user_data as binary/bytes instead of UTF-8 string,
causing it to fail parsing and skip the write_files directive that
configures SSH on port 4160.

## Cleaner Solutions Implemented

### Fix 1: String Encoding (user_data | string)
- Added explicit string conversion to user_data template lookup
- Ensures DigitalOcean API receives proper UTF-8 string, not bytes
- Minimal change with maximum compatibility

### Fix 2: Use runcmd Instead of write_files
- Replaced write_files approach with runcmd shell commands
- Bypasses the cloud-init parsing issue entirely
- More reliable as it executes direct shell commands
- Includes automatic SSH config backup for safety

## Changes Made
- `roles/cloud-digitalocean/tasks/main.yml`: Added | string filter to user_data
- `files/cloud-init/base.yml`: Replaced write_files with runcmd approach
- Removed complex SSH detection/remediation workaround (no longer needed)

## Benefits
-  Fixes root cause instead of working around symptoms
-  Much simpler and more maintainable code
-  Backward compatible - no API changes required
-  Handles both potential failure modes (encoding + parsing)
-  All tests pass, linters clean

This should resolve DigitalOcean SSH timeout issues while being much
cleaner than the previous workaround approach.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix cloud-init header format for DigitalOcean compatibility

The space in '# cloud-config' (introduced in PR #14775) breaks cloud-init
YAML parsing on DigitalOcean, causing SSH configuration to be skipped.

Cloud-init documentation requires '#cloud-config' without a space.

Fixes #14800

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Revert to write_files approach for SSH configuration

Using write_files is more maintainable and Ansible-native than runcmd.
The root cause was the cloud-config header format, not write_files itself.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix Ansible deprecation and variable warnings

- Replace deprecated network filters with ansible.utils equivalents:
  - ipaddr → ansible.utils.ipaddr
  - ipmath → ansible.utils.ipmath
  - ipv4 → ansible.utils.ipv4
  - ipv6 → ansible.utils.ipv6
  - next_nth_usable → ansible.utils.next_nth_usable

- Fix reserved variable name: no_log → algo_no_log

- Fix SSH user groups warning by explicitly specifying groups parameter

Addresses deprecation warnings that would become errors after 2024-01-01.
All linter checks pass with only cosmetic warnings remaining.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Add comprehensive protection for cloud-config header format

- Add inline documentation explaining critical #cloud-config format requirement
- Exclude files/cloud-init/ from yamllint and ansible-lint to prevent automatic 'fixes'
- Create detailed README.md documenting the issue and protection measures
- Reference GitHub issue #14800 for future maintainers

This prevents regression of the critical cloud-init header format that
causes deployment failures when changed from '#cloud-config' to '# cloud-config'.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Add test for cloud-init header format to prevent regression

This test ensures the cloud-init header remains exactly ''#cloud-config''
without a space. The regression in PR #14775 that added a space broke
DigitalOcean deployments by causing cloud-init YAML parsing to fail,
resulting in SSH timeouts on port 4160.

Co-authored-by: Dan Guido <dguido@users.noreply.github.com>

* Refactor SSH config template and fix MOTD task permissions

- Use dedicated sshd_config template instead of inline content
- Add explicit become: true to MOTD task to fix permissions warning

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix no_log variable references after renaming to algo_no_log

Update all remaining references from old 'no_log' variable to 'algo_no_log'
in WireGuard, SSH tunneling, and StrongSwan roles. This fixes deployment
failures caused by undefined variable references.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Correct YAML indentation in cloud-init template for DigitalOcean

The indent filter was not indenting the first line of the sshd_config content,
causing invalid YAML structure that cloud-init couldn't parse. This resulted
in SSH timeouts during deployment as the port was never changed from 22 to 4160.

- Add first=True parameter to indent filter to ensure all lines are indented
- Remove extra indentation in base template to prevent double-indentation
- Add comprehensive test suite to validate template rendering and prevent regressions

Fixes deployment failures where cloud-init would show:
"Invalid format at line X: expected <block end>, but found '<scalar>'"

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Co-authored-by: Dan Guido <dguido@users.noreply.github.com>
2025-08-03 14:25:47 -04:00
Jack Ivanov
347f864abb
Ansible upgrade 6.1 (#14500)
* linting

* update ansible

* linters
2022-07-30 15:01:24 +03:00
Jack Ivanov
8c560719a5
skip pre tasks in update-users (#1921) 2020-12-08 13:23:24 +03:00
David Myers
8894dd0848
Discontinue use of the WireGuard PPA (#1855)
* Discontinue use of the WireGuard PPA

* Add instructions to update the system

* Change reboot instruction
2020-08-06 19:09:15 +03:00
Jack Ivanov
c14ff0d611
Ubuntu 20.04 support (#1782)
* ubuntu 20.04 support

* purge snapd for 20.04

* strongswan-starter fix
2020-05-10 13:48:30 +03:00
Jack Ivanov
1e8a9c5cf1
Generate mobileconfigs for WireGuard (#1698)
* Generate mobileconfigs for WireGuard

* add xmllint to wireguard profiles

* Enable onDemand prompts for WireGuard

* linting
2020-02-12 08:31:44 +01:00
Jack Ivanov
090a60d48d PKI to tmpfs (#1496)
* PKI to tmpfs

* Fixes
- diskutil to full path
- unmount and eject fixes

* Umount fix

* run diskutil info only on Darwin kernels

* fix shell tasks
2019-07-10 12:31:25 -04:00
elreydetoda
146cbc71ce Adding preshared key support (#1465)
* adding preshared key generation

* adding preshared folder

* Update client.conf.j2

adding preshared key options

* adding preshared keys to server template

* making sure private preshared is right

* making sure preshared keygen working for main.yml

* changing private to preshared for name

* changing to preshared dir instead of public
2019-06-05 08:31:16 +02:00
Jack Ivanov
25513cf925 Refactoring, Linting and additional tests (#1397)
* Refactoring, Linting and additional tests

* Vultr: Undefined variable and deprecation notes fix

* Travis-CI enable linters

* Azure: Update python requirements

* Update main.yml

* Update install.sh

* Add missing roles to ansible-lint

* Linting for skipped roles

* add .ansible-lint config
2019-04-26 11:48:28 -04:00
Jack Ivanov
c4ea88000b Refactoring to support roles inclusion (#1365) 2019-04-08 16:20:34 -04:00
Jack Ivanov
273c7665d3 Refactoring (#1334)
<!--- Provide a general summary of your changes in the Title above -->

## Description
Renames the vpn role to strongswan, and split up the variables to support 2 separate VPNs. Closes #1330 and closes #1162
Configures Ansible to use python3 on the server side. Closes #1024 
Removes unneeded playbooks, reorganises a lot of variables
Reorganises the `config` folder. Closes #1330
<details><summary>Here is how the config directory looks like now</summary>
<p>

```
configs/X.X.X.X/
|-- ipsec
|   |-- apple
|   |   |-- desktop.mobileconfig
|   |   |-- laptop.mobileconfig
|   |   `-- phone.mobileconfig
|   |-- manual
|   |   |-- cacert.pem
|   |   |-- desktop.p12
|   |   |-- desktop.ssh.pem
|   |   |-- ipsec_desktop.conf
|   |   |-- ipsec_desktop.secrets
|   |   |-- ipsec_laptop.conf
|   |   |-- ipsec_laptop.secrets
|   |   |-- ipsec_phone.conf
|   |   |-- ipsec_phone.secrets
|   |   |-- laptop.p12
|   |   |-- laptop.ssh.pem
|   |   |-- phone.p12
|   |   `-- phone.ssh.pem
|   `-- windows
|       |-- desktop.ps1
|       |-- laptop.ps1
|       `-- phone.ps1
|-- ssh-tunnel
|   |-- desktop.pem
|   |-- desktop.pub
|   |-- laptop.pem
|   |-- laptop.pub
|   |-- phone.pem
|   |-- phone.pub
|   `-- ssh_config
`-- wireguard
    |-- desktop.conf
    |-- desktop.png
    |-- laptop.conf
    |-- laptop.png
    |-- phone.conf
    `-- phone.png
```

![finder](https://i.imgur.com/FtOmKO0.png)

</p>
</details>

## Motivation and Context
This refactoring is focused to aim to the 1.0 release

## How Has This Been Tested?
Deployed to several cloud providers with various options enabled and disabled

## Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [x] Refactoring

## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
- [x] I have read the **CONTRIBUTING** document.
- [x] My code follows the code style of this project.
- [x] My change requires a change to the documentation.
- [x] I have updated the documentation accordingly.
- [x] All new and existing tests passed.
2019-03-10 13:16:34 -04:00
Jack Ivanov
66d30e3005
WireGuard update-users fix (#1183) 2018-11-12 18:03:31 +01:00
Jack Ivanov
fbc7b29456 WireGuard update-users fix (#1154) 2018-10-22 16:49:09 -04:00
Jack Ivanov
efc8dc7620
add tags for the wireguard qr code task. variables fix (#1147) 2018-10-14 10:22:45 +03:00
Jack Ivanov
1442586682 WireGuard: Generate QR codes (#1129)
* WireGuard: Generate QR codes

* Update client-android.md
2018-09-29 22:25:02 -04:00
Jack Ivanov
dbd68aa97d WireGuard BSD (#1083)
* WireGuard BSD

* Remove unneeded config option

* Enable PersistentKeepalive for NAT and Firewall Traversal Persistence

* Install dnscrypt-proxy from repositories
2018-09-27 04:18:12 -04:00
Jack Ivanov
e8947f318b Large refactor to support Ansible 2.5 (#976)
* Refactoring, booleans declaration and update users fix

* Make server_name more FQDN compatible

* Rename variables

* Define the default value for store_cakey

* Skip a prompt about the SSH user if deploying to localhost

* Disable reboot for non-cloud deployments

* Enable EC2 volume encryption by default

* Add default server value (localhost) for the local installation

Delete empty files

* Add default region to aws_region_facts

* Update docs

* EC2 credentials fix

* Warnings fix

* Update deploy-from-ansible.md

* Fix a typo

* Remove lightsail from the docs

* Disable EC2 encryption by default

* rename droplet to server

* Disable dependencies

* Disable tls_cipher_suite

* Convert wifi-exclude to a string. Update-users fix

* SSH access congrats fix

* 16.04 > 18.04

* Dont ask for the credentials if specified in the environment vars

* GCE server name fix
2018-08-27 10:05:45 -04:00
Jack Ivanov
53d1113881 Split up unattended upgrades (#1041) 2018-08-08 00:25:59 -04:00
Jack Ivanov
d1c58f0d28
apt_repository fix (#1017) 2018-07-02 16:33:31 +03:00
Jack Ivanov
3488e660ad Add WireGuard support for Android (#910)
* WireGuard Implementation

* Update client-android.md

* Update README.md

* WireGuard unattended upgrades

* Update README.md

* reload-module-on-update and syntax fix

* SaveConfig to true

* Azure firewall. Fixes #962

* Update README.md

* Update client-android.md
2018-05-24 08:15:27 -07:00