module

Krikri::PluginHelpers::Ec2Instance

Decision logic for amazon.aws.ec2_instance - the instance lifecycle module of the amazon.aws EC2 cluster (create, start, stop, restart, terminate), through the shared PluginHelpers::Ec2Api signed-request helper (RunInstances/StartInstances/StopInstances/ TerminateInstances/DescribeInstances/CreateTags/DeleteTags).

Like Ec2Key/Ec2SecurityGroup, the plan functions take the module params plus the ALREADY-FETCHED DescribeInstances result and return the exact mutating calls to make; the full #run wires it together and specs drive it through the Ec2Api transport seam.

Behavior mirrors the real module's surface (params confirmed against ansible-doc amazon.aws.ec2_instance):

  • Targeting: name (the Name tag) or instance_ids, optionally narrowed by filters. The idempotency lookup always adds a non-terminated instance-state-name filter (pending/running/ stopping/stopped) - a match in any of those states counts as existing for every state, and terminated instances never come back from DescribeInstances anyway.
  • state=present: launch (RunInstances) when no match; otherwise a no-op except for tag drift (missing tags applied via CreateTags, extra tags deleted via DeleteTags when both tags and purge_tags are set - the real module's default - with aws:-reserved keys left alone). Attribute drift (instance_type, user_data, ...) is deliberately not diffed: present "ensures instances exist, but does not guarantee any state".
  • state=running/started: launch when absent, StartInstances on stopped matches, no-op when already running.
  • state=stopped: StopInstances on matches not already stopped (running or still stopping); fails when no match exists (the real module cannot stop what is not there).
  • state=restarted/rebooted: Stop then Start.
  • state=terminated/absent: TerminateInstances, no-op when no match.
  • count: always launches that many new instances (never reconciles). exact_count: reconciles the match set to N - launching the difference, or terminating the surplus oldest-first (least recently created, per the real module's documented Launch Time ordering).
  • Tags: the name param is the Name tag; user tags are applied after RunInstances via a separate CreateTags call (RunInstances itself takes no tag params on the wire).
  • wait (default true) polls DescribeInstances after any mutating call until every affected instance reaches the target state (running/stopped/terminated; a terminated instance that has left DescribeInstances entirely counts as terminated), up to wait_timeout (default 600s, the real module's default).

Result shape matches real Ansible: instances is the list of DescribeInstances items shaped by Ec2Info.jsonify (camel_to_snake'd boto3 keys, state as the code/name dict, tags as the key-value dict).

Constants

NON_TERMINATED_STATES = ["pending", "running", "stopping", "stopped"]

The states a "matching" instance may be in for the idempotency lookup - everything except terminated/terminating.

VALID_STATES = ["present", "running", "started", "stopped", "restarted", "rebooted", "terminated", "absent"]

Class methods

desired_tags(name : String | Nil, params : Hash(String, String)) : Hash(String, String)

The full desired tag set: Name from the name param, overlaid by the user tags dict (which may deliberately override Name).

Source
lookup_params(name : String | Nil, instance_ids : Array(String), extra_filters : Array(Tuple(String, Array(String))), state_filter : Bool) : Array(Tuple(String, String))

InstanceId.N params plus the Filter.N.Name/Value.M pairs for the lookup: the caller's extra filters, the tag:Name filter when targeting by name (direct-ID targeting is exact already), and - for the idempotency lookup only - the non-terminated state filter.

Source
parse_instances(root : XML::Node) : Array(Instance)

DescribeInstancesResponse -> flat instance list across reservationSet/item/instancesSet/item.

Source
plan_present(name : String | Nil, params : Hash(String, String), existing : Array(Instance), wait : Bool) : Plan
Source
plan_restarted(existing : Array(Instance), wait : Bool) : Plan
Source
plan_running(name : String | Nil, params : Hash(String, String), existing : Array(Instance), wait : Bool) : Plan
Source
plan_stopped(existing : Array(Instance), wait : Bool) : Plan
Source
plan_terminate(existing : Array(Instance), wait : Bool) : Plan
Source
poll_interval
Source
poll_interval=(value : Float64) : Nil
Source
run_instances_params(params : Hash(String, String), count : Int32) : Array(Tuple(String, String))

RunInstances wire params. UserData is Base64-encoded (the EC2 Query API expects the encoded blob; boto3 does this conversion for the real module).

Source
security_groups(params : Hash(String, String)) : Array(String)

security_group (single) + security_groups (list) collapse into one SecurityGroupId.N list - the real module treats them as mutually exclusive spellings of the same thing.

Source
tag_diff_steps(desired : Hash(String, String), current : Hash(String, String), instance_id : String, purge : Bool) : Array(Ec2Api::Step)

Tag drift between the desired set and one instance's current tags: CreateTags for the missing/changed, DeleteTags for the surplus (only when purge_tags is set; aws:-reserved keys are never deletable).

Source
wait_for(region : String, credentials : Ec2Api::Credentials, instance_ids : Array(String), target_state : String, timeout : Int32) : Array(Instance)

Poll DescribeInstances until every requested instance reaches the target state. A terminated instance that has dropped out of DescribeInstances entirely counts as terminated (EC2 removes it from the response once the termination fully settles).

Source

Nested types