Files
algo/roles/cloud-ec2/tasks/prompts.yml
T
984831bcab fix: add explicit bool filters for Ansible 12 jinja2_native compatibility (#14963)
* fix: add explicit bool filters for Ansible 12 jinja2_native compatibility

Ansible 12 enables jinja2_native by default, which means string values
like "true"/"false" are no longer automatically coerced to booleans in
when: conditions and Jinja2 if statements. Add | bool filters to all
boolean variable references in tasks, templates, and handlers.

Also reformats long single-line Jinja2 conditionals into multi-line for
readability, fixes GCE default() calls for native mode, adds help
command to the algo script, and updates test fixtures to register the
bool filter.

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

* ci: add j2lint for Jinja2 template linting

Add j2lint (aristanetworks/j2lint) to catch syntax errors, spacing
issues, and operator formatting in Jinja2 templates. Integrated into
pre-commit hooks, lint.yml CI, and smart-tests.yml.

Rules S3/S5/S6/S7/V1 are ignored — they enforce conventions
incompatible with Ansible's config-file-embedded templates.

Also fixes int+1 → int + 1 operator spacing in server.conf.j2.

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

* fix: resolve all ansible-lint warnings and enforce zero-tolerance policy

Fix 18 jinja[spacing] errors across 12 files by moving Jinja2 block
delimiters to prevent YAML >- folding from introducing trailing spaces.

Fix 27 key-order[task] warnings across 17 files by reordering task keys
to canonical order (name → when → tags → environment → become → block).

Promote key-order[task] and yaml[line-length] from warn_list to hard
errors by removing warn_list entirely from .ansible-lint.

Add zero-tolerance warning policy to CLAUDE.md explaining why warnings
are unacceptable in a security tool and documenting resolution order.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 11:21:56 -05:00

141 lines
5.4 KiB
YAML

---
# Discover AWS credentials from standard locations
- name: Set AWS credentials file path
set_fact:
aws_credentials_path: "{{ lookup('env', 'AWS_SHARED_CREDENTIALS_FILE') | default(lookup('env', 'HOME') + '/.aws/credentials', true) }}"
aws_profile: "{{ lookup('env', 'AWS_PROFILE') | default('default', true) }}"
# Try to read credentials from file if not already provided
- when:
- aws_access_key is undefined
- lookup('env', 'AWS_ACCESS_KEY_ID')|length <= 0
block:
- name: Check if AWS credentials file exists
stat:
path: "{{ aws_credentials_path }}"
register: aws_creds_file
delegate_to: localhost
- name: Read AWS credentials from file
set_fact:
_file_access_key: "{{ lookup('ini', 'aws_access_key_id', section=aws_profile, file=aws_credentials_path, errors='ignore') | default('', true) }}"
_file_secret_key: "{{ lookup('ini', 'aws_secret_access_key', section=aws_profile, file=aws_credentials_path, errors='ignore') | default('', true) }}"
_file_session_token: "{{ lookup('ini', 'aws_session_token', section=aws_profile, file=aws_credentials_path, errors='ignore') | default('', true) }}"
when: aws_creds_file.stat.exists
no_log: true
# Prompt for credentials if still not available
- pause:
prompt: |
Enter your AWS Access Key ID (http://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html)
Note: Make sure to use an IAM user with an acceptable policy attached (see https://github.com/trailofbits/algo/blob/master/docs/deploy-from-ansible.md)
echo: false
register: _aws_access_key
when:
- aws_access_key is undefined
- lookup('env', 'AWS_ACCESS_KEY_ID')|length <= 0
- _file_access_key is undefined or _file_access_key|length <= 0
- pause:
prompt: |
Enter your AWS Secret Access Key (http://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html)
echo: false
register: _aws_secret_key
when:
- aws_secret_key is undefined
- lookup('env', 'AWS_SECRET_ACCESS_KEY')|length <= 0
- _file_secret_key is undefined or _file_secret_key|length <= 0
# Set final credentials with proper precedence
# Note: The 'true' parameter in default() is required for Ansible 12+ compatibility.
# Without it, empty strings from env lookups stop the default chain since they're
# "defined" values, not "undefined". The 'true' makes default() also trigger on
# falsy values (empty strings, None).
- set_fact:
access_key: >-
{{ aws_access_key
| default(lookup('env', 'AWS_ACCESS_KEY_ID'), true)
| default(_file_access_key, true)
| default(_aws_access_key.user_input | default(None), true) }}
secret_key: >-
{{ aws_secret_key
| default(lookup('env', 'AWS_SECRET_ACCESS_KEY'), true)
| default(_file_secret_key, true)
| default(_aws_secret_key.user_input | default(None), true) }}
session_token: >-
{{ aws_session_token
| default(lookup('env', 'AWS_SESSION_TOKEN'), true)
| default(_file_session_token, true)
| default('') }}
no_log: true
- when: region is undefined
block:
- name: Get regions
aws_region_info:
aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ secret_key }}"
aws_session_token: "{{ session_token if session_token else omit }}"
region: us-east-1
register: _aws_regions
no_log: true
- name: Set facts about the regions
set_fact:
aws_regions: "{{ _aws_regions.regions | sort(attribute='region_name') }}"
- name: Set the default region
set_fact:
default_region: >-
{%- for r in aws_regions -%}
{%- if r['region_name'] == "us-east-1" %}{{ loop.index }}{% endif -%}
{%- endfor %}
- pause:
prompt: |
What region should the server be located in?
(https://docs.aws.amazon.com/general/latest/gr/rande.html#ec2_region)
{% for r in aws_regions %}
{{ loop.index }}. {{ r['region_name'] }}
{% endfor %}
Enter the number of your desired region
[{{ default_region }}]
register: _algo_region
- name: Set algo_region and stack_name facts
set_fact:
algo_region: >-
{%- if region is defined -%}{{ region }}{%-
elif _algo_region.user_input -%}{{ aws_regions[_algo_region.user_input | int - 1]['region_name'] }}{%-
else -%}{{ aws_regions[default_region | int - 1]['region_name'] }}{%-
endif -%}
stack_name: "{{ algo_server_name | replace('.', '-') }}"
- when: cloud_providers.ec2.use_existing_eip
block:
- name: Get existing available Elastic IPs
ec2_eip_info:
aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ secret_key }}"
aws_session_token: "{{ session_token if session_token else omit }}"
region: "{{ algo_region }}"
register: raw_eip_addresses
no_log: true
- set_fact:
available_eip_addresses: "{{ raw_eip_addresses.addresses | selectattr('association_id', 'undefined') | list }}"
- pause:
prompt: >-
What Elastic IP would you like to use?
{% for eip in available_eip_addresses %}
{{ loop.index }}. {{ eip['public_ip'] }}
{% endfor %}
Enter the number of your desired Elastic IP
register: _use_existing_eip
- set_fact:
existing_eip: "{{ available_eip_addresses[_use_existing_eip.user_input | int - 1]['allocation_id'] }}"