Compare commits

...

8 Commits

Author SHA1 Message Date
Christer Warén
21acf6f0cb Rename olympus.intra.tjas to olympus.juva.tjas 2025-08-08 18:42:01 +03:00
Christer Warén
b86a8c9c4b Fix typo in Deployer tasks 2025-08-08 18:33:33 +03:00
Christer Warén
b0b1a0f19d Add kea-dhcp4.conf to Kea files 2025-08-08 18:28:03 +03:00
Christer Warén
8931fda671 Update olympus host variables 2025-08-08 18:27:30 +03:00
Christer Warén
9803cad577 Install Kea server as new DHCP server in Deployer tasks 2025-08-08 18:27:30 +03:00
Christer Warén
03a4760ab5 Update data directory location to be static in root user directory 2025-08-08 18:27:30 +03:00
Christer Warén
30e04c8667 Update DHCP server configuration 2025-08-08 18:27:30 +03:00
Christer Warén
fa8775abc1 Update network device configurations to INSTRUCTIONS.md 2025-08-08 18:26:36 +03:00
10 changed files with 660 additions and 131 deletions

View File

@@ -14,12 +14,12 @@
r1.net.tjas r1.net.tjas
``` ```
!
version 12.4 version 12.4
service timestamps debug datetime msec service timestamps debug datetime msec
service timestamps log datetime msec service timestamps log datetime msec
no service password-encryption no service password-encryption
! !
!
hostname r1.net.tjas hostname r1.net.tjas
! !
boot-start-marker boot-start-marker
@@ -61,28 +61,28 @@ interface FastEthernet0/1
interface FastEthernet0/1.10 interface FastEthernet0/1.10
description "TINU - INTERNET" description "TINU - INTERNET"
encapsulation dot1Q 10 encapsulation dot1Q 10
ip address 192.168.1.1 255.255.255.0 ip address 192.168.1.1 255.255.255.224
ip helper-address 192.168.2.10 ip helper-address 192.168.2.10
no snmp trap link-status no snmp trap link-status
! !
interface FastEthernet0/1.20 interface FastEthernet0/1.20
description "JUVA - INTRA" description "JUVA - INTRA"
encapsulation dot1Q 20 encapsulation dot1Q 20
ip address 192.168.2.1 255.255.255.0 ip address 192.168.2.1 255.255.255.224
ip helper-address 192.168.2.10 ip helper-address 192.168.2.10
no snmp trap link-status no snmp trap link-status
! !
interface FastEthernet0/1.30 interface FastEthernet0/1.30
description "AITO - TOIMISTO" description "AITO - TOIMISTO"
encapsulation dot1Q 30 encapsulation dot1Q 30
ip address 192.168.3.1 255.255.255.0 ip address 192.168.3.1 255.255.255.224
ip helper-address 192.168.2.10 ip helper-address 192.168.2.10
no snmp trap link-status no snmp trap link-status
! !
interface FastEthernet0/1.69 interface FastEthernet0/1.69
description "SIVE - HALLINTA" description "SIVE - HALLINTA"
encapsulation dot1Q 69 encapsulation dot1Q 69
ip address 192.168.69.1 255.255.255.0 ip address 192.168.69.1 255.255.255.192
ip helper-address 192.168.69.20 ip helper-address 192.168.69.20
no snmp trap link-status no snmp trap link-status
! !
@@ -95,11 +95,6 @@ ip classless
! !
ip http server ip http server
! !
access-list 1 permit 192.168.0.0
access-list 1 permit 192.168.1.0
access-list 1 permit 192.168.2.0
access-list 1 permit 192.168.3.0
access-list 1 deny any
! !
control-plane control-plane
! !
@@ -126,26 +121,27 @@ vlan 1
exit exit
vlan 10 vlan 10
name "TINU" name "TINU"
ip address 192.168.1.2 255.255.255.0 ip address 192.168.1.2 255.255.255.224
tagged 1 tagged 1
exit exit
vlan 20 vlan 20
name "JUVA" name "JUVA"
no ip address
tagged 1-2 tagged 1-2
exit exit
vlan 30 vlan 30
name "AITO" name "AITO"
no ip address
tagged 1,3 tagged 1,3
exit exit
vlan 69 vlan 69
name "SIVE" name "SIVE"
ip address 192.168.69.11 255.255.255.0 ip address 192.168.69.11 255.255.255.192
tagged 1,2,3 tagged 1-3
exit exit
ip authorized-managers 192.168.69.20 ip authorized-managers 192.168.69.20 255.255.255.255
ip ssh ip ssh
password manager password manager
``` ```
s2.net.tjas s2.net.tjas
@@ -161,13 +157,13 @@ vlan 1
vlan 20 vlan 20
name "JUVA" name "JUVA"
untagged 2-24 untagged 2-24
ip address 192.168.2.2 255.255.255.0 ip address 192.168.2.2 255.255.255.224
tagged 1 tagged 1-2
exit exit
vlan 69 vlan 69
name "SIVE" name "SIVE"
ip address 192.168.69.12 255.255.255.0 ip address 192.168.69.12 255.255.255.192
tagged 1,2 tagged 1-2
exit exit
ip authorized-managers 192.168.69.20 255.255.255.255 ip authorized-managers 192.168.69.20 255.255.255.255
ip ssh ip ssh
@@ -186,14 +182,14 @@ vlan 1
exit exit
vlan 30 vlan 30
name "AITO" name "AITO"
untagged 2-24 ip address 192.168.3.2 255.255.255.224
ip address 192.168.3.2 255.255.255.0 tagged 1,13-24
tagged 1 untagged
exit exit
vlan 69 vlan 69
name "SIVE" name "SIVE"
untagged 2-24 untagged 2-24
ip address 192.168.69.13 255.255.255.0 ip address 192.168.69.13 255.255.255.192
tagged 1 tagged 1
exit exit
ip authorized-managers 192.168.69.20 255.255.255.255 ip authorized-managers 192.168.69.20 255.255.255.255

View File

@@ -106,20 +106,85 @@ authoritative;
# } # }
#} #}
subnet 192.168.1.0 netmask 255.255.255.0 { subnet 192.168.1.0 netmask 255.255.255.240 {
range 192.168.1.2 192.168.1.254; range 192.168.1.2 192.168.1.14;
option routers 192.168.1.1; option routers 192.168.1.1;
option broadcast-address 192.168.1.255; option broadcast-address 192.168.1.15;
host r1.net.tjas {
hardware ethernet 00:1d:46:dc:80:09;
fixed-address 192.168.1.1;
} }
subnet 192.168.2.0 netmask 255.255.255.0 { host s1.net.tjas {
range 192.168.2.2 192.168.2.254; hardware ethernet 9c:8e:99:9b:c3:80;
fixed-address 192.168.1.2;
}
}
subnet 192.168.2.0 netmask 255.255.255.224 {
range 192.168.2.2 192.168.2.30;
option routers 192.168.2.1; option routers 192.168.2.1;
option broadcast-address 192.168.2.255; option broadcast-address 192.168.2.31;
host r1.net.tjas {
hardware ethernet 00:1d:46:dc:80:09;
fixed-address 192.168.2.1;
} }
subnet 192.168.3.0 netmask 255.255.255.0 { host s2.net.tjas {
range 192.168.3.2 192.168.3.254; hardware ethernet 00:24:a8:f1:c7:40;
option routers 192.168.3.1; fixed-address 192.168.2.2;
option broadcast-address 192.168.3.255; }
host olympus.intra.tjas {
hardware ethernet 90:1b:0e:5b:18:fa;
fixed-address 192.168.2.10;
}
}
subnet 192.168.3.0 netmask 255.255.255.224 {
range 192.168.3.2 192.168.3.30;
option routers 192.168.3.1;
option broadcast-address 192.168.3.31;
host r1.net.tjas {
hardware ethernet 00:1d:46:dc:80:09;
fixed-address 192.168.3.1;
}
host s3.net.tjas {
hardware ethernet 00:1f:fe:ab:9e:c0;
fixed-address 192.168.3.2;
}
}
subnet 192.168.69.0 netmask 255.255.255.192 {
range 192.168.69.2 192.168.69.62;
option broadcast-address 192.168.69.63;
host r1.net.tjas {
hardware ethernet 00:1d:46:dc:80:09;
fixed-address 192.168.69.1;
}
host s1.net.tjas {
hardware ethernet 9c:8e.99:9b:c3:80;
fixed-address 192.168.3.11;
}
host s2.net.tjas {
hardware ethernet 00:24:a8:f1:c7:40;
fixed-address 192.168.3.12;
}
host s3.net.tjas {
hardware ethernet 00:1f:fe:ab:9e:c0;
fixed-address 192.168.3.13;
}
host olympus.intra.tjas {
hardware ethernet 90:1b:0e:5b:18:fa;
fixed-address 192.168.69.20;
}
} }

461
files/kea/kea-dhcp4.conf Normal file
View File

@@ -0,0 +1,461 @@
// This is a basic configuration for the Kea DHCPv4 server. Subnet declarations
// are mostly commented out and no interfaces are listed. Therefore, the servers
// will not listen or respond to any queries.
// The basic configuration must be extended to specify interfaces on which
// the servers should listen. There are a number of example options defined.
// These probably don't make any sense in your network. Make sure you at least
// update the following, before running this example in your network:
// - change the network interface names
// - change the subnets to match your actual network
// - change the option values to match your network
//
// This is just a very basic configuration. Kea comes with large suite (over 30)
// of configuration examples and extensive Kea User's Guide. Please refer to
// those materials to get better understanding of what this software is able to
// do. Comments in this configuration file sometimes refer to sections for more
// details. These are section numbers in Kea User's Guide. The version matching
// your software should come with your Kea package, but it is also available
// in ISC's Knowledgebase (https://kea.readthedocs.io; the direct link for
// the stable version is https://kea.readthedocs.io/).
//
// This configuration file contains only DHCPv4 server's configuration.
// If configurations for other Kea services are also included in this file they
// are ignored by the DHCPv4 server.
{
// DHCPv4 configuration starts here. This section will be read by DHCPv4 server
// and will be ignored by other components.
"Dhcp4": {
// Add names of your network interfaces to listen on.
"interfaces-config": {
// See section 8.2.4 for more details. You probably want to add just
// interface name (e.g. "eth0" or specific IPv4 address on that
// interface name (e.g. "eth0/192.0.2.1").
"interfaces": [ ]
// Kea DHCPv4 server by default listens using raw sockets. This ensures
// all packets, including those sent by directly connected clients
// that don't have IPv4 address yet, are received. However, if your
// traffic is always relayed, it is often better to use regular
// UDP sockets. If you want to do that, uncomment this line:
// "dhcp-socket-type": "udp"
},
// Kea supports control channel, which is a way to receive management
// commands while the server is running. This is a Unix domain socket that
// receives commands formatted in JSON, e.g. config-set (which sets new
// configuration), config-reload (which tells Kea to reload its
// configuration from file), statistic-get (to retrieve statistics) and many
// more. For detailed description, see Sections 8.8, 16 and 15.
"control-socket": {
"socket-type": "unix",
"socket-name": "/run/kea/kea4-ctrl-socket"
},
// Use Memfile lease database backend to store leases in a CSV file.
// Depending on how Kea was compiled, it may also support SQL databases
// (MySQL and/or PostgreSQL). Those database backends require more
// parameters, like name, host and possibly user and password.
// There are dedicated examples for each backend. See Section 7.2.2 "Lease
// Storage" for details.
"lease-database": {
// Memfile is the simplest and easiest backend to use. It's an in-memory
// C++ database that stores its state in CSV file.
"type": "memfile",
"lfc-interval": 3600
},
// Kea allows storing host reservations in a database. If your network is
// small or you have few reservations, it's probably easier to keep them
// in the configuration file. If your network is large, it's usually better
// to use database for it. To enable it, uncomment the following:
// "hosts-database": {
// "type": "mysql",
// "name": "kea",
// "user": "kea",
// "password": "kea",
// "host": "localhost",
// "port": 3306
// },
// See Section 7.2.3 "Hosts storage" for details.
// Setup reclamation of the expired leases and leases affinity.
// Expired leases will be reclaimed every 10 seconds. Every 25
// seconds reclaimed leases, which have expired more than 3600
// seconds ago, will be removed. The limits for leases reclamation
// are 100 leases or 250 ms for a single cycle. A warning message
// will be logged if there are still expired leases in the
// database after 5 consecutive reclamation cycles.
"expired-leases-processing": {
"reclaim-timer-wait-time": 10,
"flush-reclaimed-timer-wait-time": 25,
"hold-reclaimed-time": 3600,
"max-reclaim-leases": 100,
"max-reclaim-time": 250,
"unwarned-reclaim-cycles": 5
},
// Global timers specified here apply to all subnets, unless there are
// subnet specific values defined in particular subnets.
"renew-timer": 900,
"rebind-timer": 1800,
"valid-lifetime": 3600,
// Many additional parameters can be specified here:
// - option definitions (if you want to define vendor options, your own
// custom options or perhaps handle standard options
// that Kea does not support out of the box yet)
// - client classes
// - hooks
// - ddns information (how the DHCPv4 component can reach a DDNS daemon)
//
// Some of them have examples below, but there are other parameters.
// Consult Kea User's Guide to find out about them.
// These are global options. They are going to be sent when a client
// requests them, unless overwritten with values in more specific scopes.
// The scope hierarchy is:
// - global (most generic, can be overwritten by class, subnet or host)
// - class (can be overwritten by subnet or host)
// - subnet (can be overwritten by host)
// - host (most specific, overwrites any other scopes)
//
// Not all of those options make sense. Please configure only those that
// are actually useful in your network.
//
// For a complete list of options currently supported by Kea, see
// Section 7.2.8 "Standard DHCPv4 Options". Kea also supports
// vendor options (see Section 7.2.10) and allows users to define their
// own custom options (see Section 7.2.9).
"option-data": [
// When specifying options, you typically need to specify
// one of (name or code) and data. The full option specification
// covers name, code, space, csv-format and data.
// space defaults to "dhcp4" which is usually correct, unless you
// use encapsulate options. csv-format defaults to "true", so
// this is also correct, unless you want to specify the whole
// option value as long hex string. For example, to specify
// domain-name-servers you could do this:
// {
// "name": "domain-name-servers",
// "code": 6,
// "csv-format": "true",
// "space": "dhcp4",
// "data": "192.0.2.1, 192.0.2.2"
// }
// but it's a lot of writing, so it's easier to do this instead:
{
"name": "domain-name-servers",
"data": "192.0.2.1, 192.0.2.2"
},
// Typically people prefer to refer to options by their names, so they
// don't need to remember the code names. However, some people like
// to use numerical values. For example, option "domain-name" uses
// option code 15, so you can reference to it either by
// "name": "domain-name" or "code": 15.
{
"code": 15,
"data": "example.org"
},
// Domain search is also a popular option. It tells the client to
// attempt to resolve names within those specified domains. For
// example, name "foo" would be attempted to be resolved as
// foo.mydomain.example.com and if it fails, then as foo.example.com
{
"name": "domain-search",
"data": "mydomain.example.com, example.com"
},
// String options that have a comma in their values need to have
// it escaped (i.e. each comma is preceded by two backslashes).
// That's because commas are reserved for separating fields in
// compound options. At the same time, we need to be conformant
// with JSON spec, that does not allow "\,". Therefore the
// slightly uncommon double backslashes notation is needed.
// Legal JSON escapes are \ followed by "\/bfnrt character
// or \u followed by 4 hexadecimal numbers (currently Kea
// supports only \u0000 to \u00ff code points).
// CSV processing translates '\\' into '\' and '\,' into ','
// only so for instance '\x' is translated into '\x'. But
// as it works on a JSON string value each of these '\'
// characters must be doubled on JSON input.
{
"name": "boot-file-name",
"data": "EST5EDT4\\,M3.2.0/02:00\\,M11.1.0/02:00"
},
// Options that take integer values can either be specified in
// dec or hex format. Hex format could be either plain (e.g. abcd)
// or prefixed with 0x (e.g. 0xabcd).
{
"name": "default-ip-ttl",
"data": "0xf0"
}
// Note that Kea provides some of the options on its own. In particular,
// it sends IP Address lease type (code 51, based on valid-lifetime
// parameter, Subnet mask (code 1, based on subnet definition), Renewal
// time (code 58, based on renew-timer parameter), Rebind time (code 59,
// based on rebind-timer parameter).
],
// Other global parameters that can be defined here are option definitions
// (this is useful if you want to use vendor options, your own custom
// options or perhaps handle options that Kea does not handle out of the box
// yet).
// You can also define classes. If classes are defined, incoming packets
// may be assigned to specific classes. A client class can represent any
// group of devices that share some common characteristic, e.g. Windows
// devices, iphones, broken printers that require special options, etc.
// Based on the class information, you can then allow or reject clients
// to use certain subnets, add special options for them or change values
// of some fixed fields.
"client-classes": [
{
// This specifies a name of this class. It's useful if you need to
// reference this class.
"name": "voip",
// This is a test. It is an expression that is being evaluated on
// each incoming packet. It is supposed to evaluate to either
// true or false. If it's true, the packet is added to specified
// class. See Section 12 for a list of available expressions. There
// are several dozens. Section 8.2.14 for more details for DHCPv4
// classification and Section 9.2.19 for DHCPv6.
"test": "substring(option[60].hex,0,6) == 'Aastra'",
// If a client belongs to this class, you can define extra behavior.
// For example, certain fields in DHCPv4 packet will be set to
// certain values.
"next-server": "192.0.2.254",
"server-hostname": "hal9000",
"boot-file-name": "/dev/null"
// You can also define option values here if you want devices from
// this class to receive special options.
}
],
// Another thing possible here are hooks. Kea supports a powerful mechanism
// that allows loading external libraries that can extract information and
// even influence how the server processes packets. Those libraries include
// additional forensic logging capabilities, ability to reserve hosts in
// more flexible ways, and even add extra commands. For a list of available
// hook libraries, see https://gitlab.isc.org/isc-projects/kea/wikis/Hooks-available.
// "hooks-libraries": [
// {
// // Forensic Logging library generates forensic type of audit trail
// // of all devices serviced by Kea, including their identifiers
// // (like MAC address), their location in the network, times
// // when they were active etc.
// "library": "/usr/lib/x86_64-linux-gnu/kea/hooks/libdhcp_legal_log.so",
// "parameters": {
// "path": "/var/lib/kea",
// "base-name": "kea-forensic4"
// }
// },
// {
// // Flexible identifier (flex-id). Kea software provides a way to
// // handle host reservations that include addresses, prefixes,
// // options, client classes and other features. The reservation can
// // be based on hardware address, DUID, circuit-id or client-id in
// // DHCPv4 and using hardware address or DUID in DHCPv6. However,
// // there are sometimes scenario where the reservation is more
// // complex, e.g. uses other options that mentioned above, uses part
// // of specific options or perhaps even a combination of several
// // options and fields to uniquely identify a client. Those scenarios
// // are addressed by the Flexible Identifiers hook application.
// "library": "/usr/lib/x86_64-linux-gnu/kea/hooks/libdhcp_flex_id.so",
// "parameters": {
// "identifier-expression": "relay4[2].hex"
// }
// }
// ],
// Below an example of a simple IPv4 subnet declaration. Uncomment to enable
// it. This is a list, denoted with [ ], of structures, each denoted with
// { }. Each structure describes a single subnet and may have several
// parameters. One of those parameters is "pools" that is also a list of
// structures.
"subnet4": [
{
// This defines the whole subnet. Kea will use this information to
// determine where the clients are connected. This is the whole
// subnet in your network. This is mandatory parameter for each
// subnet.
"subnet": "192.0.2.0/24",
// Pools define the actual part of your subnet that is governed
// by Kea. Technically this is optional parameter, but it's
// almost always needed for DHCP to do its job. If you omit it,
// clients won't be able to get addresses, unless there are
// host reservations defined for them.
"pools": [ { "pool": "192.0.2.1 - 192.0.2.200" } ],
// These are options that are subnet specific. In most cases,
// you need to define at least routers option, as without this
// option your clients will not be able to reach their default
// gateway and will not have Internet connectivity.
"option-data": [
{
// For each IPv4 subnet you most likely need to specify at
// least one router.
"name": "routers",
"data": "192.0.2.1"
}
],
// Kea offers host reservations mechanism. Kea supports reservations
// by several different types of identifiers: hw-address
// (hardware/MAC address of the client), duid (DUID inserted by the
// client), client-id (client identifier inserted by the client) and
// circuit-id (circuit identifier inserted by the relay agent).
//
// Kea also support flexible identifier (flex-id), which lets you
// specify an expression that is evaluated for each incoming packet.
// Resulting value is then used for as an identifier.
//
// Note that reservations are subnet-specific in Kea. This is
// different than ISC DHCP. Keep that in mind when migrating
// your configurations.
"reservations": [
// This is a reservation for a specific hardware/MAC address.
// It's a rather simple reservation: just an address and nothing
// else.
{
"hw-address": "1a:1b:1c:1d:1e:1f",
"ip-address": "192.0.2.201"
},
// This is a reservation for a specific client-id. It also shows
// the this client will get a reserved hostname. A hostname can
// be defined for any identifier type, not just client-id.
{
"client-id": "01:11:22:33:44:55:66",
"ip-address": "192.0.2.202",
"hostname": "special-snowflake"
},
// The third reservation is based on DUID. This reservation defines
// a special option values for this particular client. If the
// domain-name-servers option would have been defined on a global,
// subnet or class level, the host specific values take preference.
{
"duid": "01:02:03:04:05",
"ip-address": "192.0.2.203",
"option-data": [ {
"name": "domain-name-servers",
"data": "10.1.1.202, 10.1.1.203"
} ]
},
// The fourth reservation is based on circuit-id. This is an option
// inserted by the relay agent that forwards the packet from client
// to the server. In this example the host is also assigned vendor
// specific options.
//
// When using reservations, it is useful to configure
// reservations-global, reservations-in-subnet,
// reservations-out-of-pool (subnet specific parameters)
// and host-reservation-identifiers (global parameter).
{
"client-id": "01:12:23:34:45:56:67",
"ip-address": "192.0.2.204",
"option-data": [
{
"name": "vivso-suboptions",
"data": "4491"
},
{
"name": "tftp-servers",
"space": "vendor-4491",
"data": "10.1.1.202, 10.1.1.203"
}
]
},
// This reservation is for a client that needs specific DHCPv4
// fields to be set. Three supported fields are next-server,
// server-hostname and boot-file-name
{
"client-id": "01:0a:0b:0c:0d:0e:0f",
"ip-address": "192.0.2.205",
"next-server": "192.0.2.1",
"server-hostname": "hal9000",
"boot-file-name": "/dev/null"
},
// This reservation is using flexible identifier. Instead of
// relying on specific field, sysadmin can define an expression
// similar to what is used for client classification,
// e.g. substring(relay[0].option[17],0,6). Then, based on the
// value of that expression for incoming packet, the reservation
// is matched. Expression can be specified either as hex or
// plain text using single quotes.
//
// Note: flexible identifier requires flex_id hook library to be
// loaded to work.
{
"flex-id": "'s0mEVaLue'",
"ip-address": "192.0.2.206"
}
// You can add more reservations here.
]
// You can add more subnets there.
}
],
// There are many, many more parameters that DHCPv4 server is able to use.
// They were not added here to not overwhelm people with too much
// information at once.
// Logging configuration starts here. Kea uses different loggers to log various
// activities. For details (e.g. names of loggers), see Chapter 18.
"loggers": [
{
// This section affects kea-dhcp4, which is the base logger for DHCPv4
// component. It tells DHCPv4 server to write all log messages (on
// severity INFO or more) to a file.
"name": "kea-dhcp4",
"output_options": [
{
// Specifies the output file. There are several special values
// supported:
// - stdout (prints on standard output)
// - stderr (prints on standard error)
// - syslog (logs to syslog)
// - syslog:name (logs to syslog using specified name)
// Any other value is considered a name of the file
"output": "stdout",
// Shorter log pattern suitable for use with systemd,
// avoids redundant information
"pattern": "%-5p %m\n",
// This governs whether the log output is flushed to disk after
// every write.
// "flush": false,
// This specifies the maximum size of the file before it is
// rotated.
// "maxsize": 1048576,
// This specifies the maximum number of rotated files to keep.
// "maxver": 8
}
],
// This specifies the severity of log messages to keep. Supported values
// are: FATAL, ERROR, WARN, INFO, DEBUG
"severity": "ERROR",
// If DEBUG level is specified, this value is used. 0 is least verbose,
// 99 is most verbose. Be cautious, Kea can generate lots and lots
// of logs if told to do so.
"debuglevel": 0
}
]
}
}

24
init.sh
View File

@@ -35,32 +35,32 @@ ti-header "Asennetaan PVJJK 1.VOS TJAS Infran riippuvuudet APT-paketinhallinnall
apt-get install -y python3-pip python3-venv jq git curl lsb-release apt-get install -y python3-pip python3-venv jq git curl lsb-release
echo -e "\n\n" echo -e "\n\n"
mkdir -p ~/.ssh/keys/pvjjk-1vos-tjas &> /dev/null mkdir -p /root/.ssh/keys/pvjjk-1vos-tjas &> /dev/null
if [[ ! -f ~/.ssh/keys/pvjjk-1vos-tjas/infra ]] if [[ ! -f /root/.ssh/keys/pvjjk-1vos-tjas/infra ]]
then then
ti-header "Generoidaan SSH-avain Infra-repon käyttöön..." ti-header "Generoidaan SSH-avain Infra-repon käyttöön..."
ssh-keygen -f ~/.ssh/keys/pvjjk-1vos-tjas/infra -t ed25519 -N '' -C $(hostname --fqdn) ssh-keygen -f /root/.ssh/keys/pvjjk-1vos-tjas/infra -t ed25519 -N '' -C $(hostname --fqdn)
echo -e "\n\n" echo -e "\n\n"
fi fi
ti-header "Luodaan Ansiblelle virtuaalinen ympäristö..." ti-header "Luodaan Ansiblelle virtuaalinen ympäristö..."
python3 -m venv ~/.venv/ansible python3 -m venv /root/.venv/ansible
echo -e "\n\n" echo -e "\n\n"
ti-header "Asennetaan Ansiblen riippuvuudet..." ti-header "Asennetaan Ansiblen riippuvuudet..."
~/.venv/ansible/bin/pip3 install cryptography dnspython hvac jmespath netaddr pexpect /root/.venv/ansible/bin/pip3 install cryptography dnspython hvac jmespath netaddr pexpect
echo -e "\n\n" echo -e "\n\n"
ti-header "Asennetaan Ansible..." ti-header "Asennetaan Ansible..."
~/.venv/ansible/bin/pip3 install ansible /root/.venv/ansible/bin/pip3 install ansible
echo -e "\n\n" echo -e "\n\n"
ti-header "Asennetaan Ansible kokoelmat..." ti-header "Asennetaan Ansible kokoelmat..."
~/.venv/ansible/bin/ansible-galaxy collection install ansible.posix containers.podman --upgrade /root/.venv/ansible/bin/ansible-galaxy collection install ansible.posix containers.podman --upgrade
echo -e "\n\n" echo -e "\n\n"
ti-header "Lisää SSH-avain Infra-repon käyttöön..." ti-header "Lisää SSH-avain Infra-repon käyttöön..."
cat ~/.ssh/keys/pvjjk-1vos-tjas/infra.pub cat /root/.ssh/keys/pvjjk-1vos-tjas/infra.pub
echo -n "Onko avain lisätty Github-repoon? [K/E]" echo -n "Onko avain lisätty Github-repoon? [K/E]"
while [[ -z $SSHKEY_QUESTION || ! -z $SSHKEY_QUESTION && $SSHKEY_QUESTION != "K" ]] while [[ -z $SSHKEY_QUESTION || ! -z $SSHKEY_QUESTION && $SSHKEY_QUESTION != "K" ]]
@@ -69,8 +69,8 @@ do
done done
echo -e "\n\n" echo -e "\n\n"
mkdir -p ~/.ansible/vault &> /dev/null mkdir -p /root/.ansible/vault &> /dev/null
if [[ ! -f ~/.ansible/vault/pvjjk-1vos-tjas ]] if [[ ! -f /root/.ansible/vault/pvjjk-1vos-tjas ]]
then then
ti-header "Syötä Ansible Vaultin salasana..." ti-header "Syötä Ansible Vaultin salasana..."
echo -n "Salasana: " echo -n "Salasana: "
@@ -80,14 +80,14 @@ then
if [[ ! -z $VAULT_PASSWORD ]] if [[ ! -z $VAULT_PASSWORD ]]
then then
echo "$VAULT_PASSWORD" > ~/.ansible/vault/pvjjk-1vos-tjas echo "$VAULT_PASSWORD" > /root/.ansible/vault/pvjjk-1vos-tjas
fi fi
done done
echo -e "\n\n" echo -e "\n\n"
fi fi
ti-header "Suoritetaan Infran asennus..." ti-header "Suoritetaan Infran asennus..."
~/.venv/ansible/bin/ansible-pull -U ssh://git@github.com/cwchristerw/tjas-infra -d ~/.ansible/pull/pvjjk-1vos-tjas/infra --accept-host-key --private-key ~/.ssh/keys/pvjjk-1vos-tjas/infra --vault-password-file ~/.ansible/vault/pvjjk-1vos-tjas tasks.yml -t installer /root/.venv/ansible/bin/ansible-pull -U ssh://git@github.com/cwchristerw/tjas-infra -d /root/.ansible/pull/pvjjk-1vos-tjas/infra --accept-host-key --private-key /root/.ssh/keys/pvjjk-1vos-tjas/infra --vault-password-file /root/.ansible/vault/pvjjk-1vos-tjas tasks.yml -t installer
echo -e "\n\n" echo -e "\n\n"
echo " echo "

View File

@@ -1,34 +0,0 @@
$ANSIBLE_VAULT;1.2;AES256;pvjjk-1vos-tjas
33376562363863333566646437313135363332623231643964346461613335623062303161643566
3038343664303937646664393536356463633966613633320a626663353131613163316234316433
31323230383964383634636338333836613264613064316664616537313934303830303166386633
6363653364646434360a633235636339336531666234666134666166653539623634343363643161
33656438306262356132346163626566656166653333643465366136653465373535353838383439
64626663376536633834336564663665353632393537326366313130633330646562666238353936
30363230323330316534343165373433663036393866626438613035636339616164303761333135
65316437663663663764663463333833663937346636383364303366393264393061383164353533
33323230383464313565316134346334343565643331653333316437396461633133323662626635
61633362303261643039313566616537316333346562366165373961383734663934653236663934
39653261663730373136363130626332303836636362613661306164643361363062353864393465
66383833653261383562313939656465623736656132383530313739313264356335616631613864
30373338346563346361383462336338303235306139346530363665376335363230386232323734
61316463656135356431313236613132323937303533356433376633626462303632616462663730
30313163306233616164306136643032393839353230373439653363323863383266363432356438
35366361623731353934646230333165636635346166366530633863343936393138306534343563
65396136656438613931313965396638353333313962663133663632613430396331656230356264
66343731396534633761323863303936323937306334366539346264373936663231613961313637
65306161356539366234613131386565343666653133363635336335316263663431373837636636
63633232623733343932363862366233326666626164313330353830383563316533636539636263
35386339393663623739623663396333643662343031363530343738663833663166313632376433
63303861633063333365306137373739633030393133333733636266306237383034653635396664
32373831636435613235623862613037663838333731386336656665646634373339626637653661
30343435323934626538353631383533363163633662326263646364383437383961656136626664
61306662646435343538333737386535623763376566373833393133353030346563326136383435
66363838343539383462313933366531333339333032363530636235633461316162643065313333
36633338326530653336353030363536363932663038373337653766373630313237343536323762
66633137383631333333386532303864633930663031653639373438643564613338646463623963
31323366373330346430393435393638363032613864633334303138363765363162613638346234
31633831313535373862646132616562623532303266623666333164613638646339643838333839
31623533393830353234303664313662373737373139323035366430646266393939626333376136
33346432356339323732393864363838656430633035303864636436393066393531333030636337
61333432666539333534383663313964636433306161353465346366333766623138

View File

@@ -0,0 +1,41 @@
$ANSIBLE_VAULT;1.2;AES256;pvjjk-1vos-tjas
32353036303137643762623464643039333838656134613535633764316264623731656663323435
6431613031346665633266366338373135393265303933340a613665656364346562636230383130
34316235316631646161346636383634666137636336396664656337633764643438383565656434
3465656532396265640a643435346535653665656263346564366238316333363536646563623033
34363530373732613561623830663832643237613230323136373635343434366361626435623061
61343832336661656366646564633464306237326330386533633965366631636431666162666134
31306631363131343962663962643432383965303931346238313663623539336535353930323538
36643164623537663531393039643437623833366135643862666237303961663132643762346235
66376662623838636361383436366562393462313430303163653664316162316339356333653936
63353365326166643463306139306134363932646465343634633465333634373033623561643130
32333566353562336534663134336234383663663464333430333962383836323539323031363166
38343632626237636337386362633630383934303437623461316539386235323231663564613233
33383532313738613762633532646266623431376164663864386237346130316530613161373337
62323764383161663234626639326638316334346236353836356463376239353033616636636636
37376265656432353262393966636230363265353236643638343465623365343639313030336236
36363163373366376232393961613231373730616564363630383336613266303238386133316533
62373766666333613461353430316664663364333266363761333339356561303637396164663565
62636261303233353235383632623132636533616264346463396566386462656135383534666333
38656439323732383534343632353161393364393537626262383465666462323336633764393866
33623639373138636233646335623630613533386565326363323830313036616635343133656638
35323862353338653637663863643031643765313236666664656162356166663663656366306134
64613138623464353839316163653239356238313834616661336130306539393039393439653466
34316664356166376665333031666164356239623332383330346332613364643561313731653336
30613864316665366533316263356561343030346535623764313264323765633035663237633530
30383566303661613332353631663163363334336436333665363965383963356265613731616231
38613632633430346531326134396333363533626466616565623432383031313037656161313764
33656230343539316464336533613864373332343231396134396161653137393338396361336330
34333265333738663330636161333035313831626134633062363265373734303733313131636164
34616435633965356263346633326135333865393565316138633337323635323164343338653566
35373366633432666131366436336633323039653466313338326362636262323735393865663939
62353963656539366662336666353635626135653166633630333937363634343534626465626463
61616632643131323237353362373766323663633936623334336231653037323539303533656439
30343133623436626630343462363861336630386664303362646338663630396131393461323931
30373432643235636136396661326439616434363563333334343534346465663538623936326636
36393636323438366639306262386437363936313064616534326633353439646137316337313061
39326239653434313438386331613631393063376433646531383361363434613934306633323230
39393965643762623330373661333032326363636134653838336162623564653933353265613233
37623632633437356365366265303937356139623237353964646166373036393864613935303233
36323665316664333362356132653235663035303135313733613632616134316365656662333839
65653162663265626438

View File

@@ -1,6 +1,6 @@
--- ---
pvjjk_1vos_tjas: pvjjk_1vos_tjas:
hosts: hosts:
olympus.intra.tjas: olympus.juva.tjas:
vars: vars:
ansible_python_interpreter: /usr/bin/python3 ansible_python_interpreter: /usr/bin/python3

View File

@@ -2,7 +2,7 @@
- name: "Deployer - SSH - Add Authorized Keys" - name: "Deployer - SSH - Add Authorized Keys"
ansible.builtin.template: ansible.builtin.template:
src: './files/ssh/authorized_keys' src: './files/ssh/authorized_keys'
dest: '~/.ssh/authorized_keys' dest: '/root/.ssh/authorized_keys'
tags: tags:
- ssh - ssh
@@ -24,14 +24,14 @@
- name: "Deployer - Yggdrasil - Configure - Create Folder" - name: "Deployer - Yggdrasil - Configure - Create Folder"
ansible.builtin.file: ansible.builtin.file:
path: "~/data/yggdrasil/" path: "/root/data/yggdrasil/"
state: directory state: directory
tags: tags:
- yggdrasil - yggdrasil
- name: "Deployer - Yggdrasil - Configure - Create Subfolders" - name: "Deployer - Yggdrasil - Configure - Create Subfolders"
ansible.builtin.file: ansible.builtin.file:
dest: '~/data/yggdrasil/{{ item.path }}' dest: '/root/data/yggdrasil/{{ item.path }}'
state: directory state: directory
with_filetree: './files/yggdrasil/' with_filetree: './files/yggdrasil/'
loop_control: loop_control:
@@ -44,7 +44,7 @@
- name: "Deployer - Yggdrasil - Configure - Generating & Transferring Files" - name: "Deployer - Yggdrasil - Configure - Generating & Transferring Files"
ansible.builtin.template: ansible.builtin.template:
src: '{{ item.src }}' src: '{{ item.src }}'
dest: '~/data/yggdrasil/{{ item.path }}' dest: '/root/data/yggdrasil/{{ item.path }}'
register: deployerTaskY1 register: deployerTaskY1
with_filetree: './files/yggdrasil/' with_filetree: './files/yggdrasil/'
loop_control: loop_control:
@@ -69,9 +69,9 @@
- name: "Deployer - Yggdrasil - Pull Image" - name: "Deployer - Yggdrasil - Pull Image"
containers.podman.podman_image: containers.podman.podman_image:
name: pvjjk-1vos-tjas/nginx name: pvjjk-1vos-tjas/yggdrasil
tag: latest tag: latest
path: "~/data/yggdrasil" path: "/root/data/yggdrasil"
build: build:
format: docker format: docker
force: true force: true
@@ -80,7 +80,7 @@
- name: "Deployer - Yggdrasil - Run Container" - name: "Deployer - Yggdrasil - Run Container"
containers.podman.podman_container: containers.podman.podman_container:
name: yggdrasil name: yggdrasil
image: pvjjk-1vos-tjas/nginx:latest image: pvjjk-1vos-tjas/yggdrasil:latest
state: started state: started
recreate: on recreate: on
network: host network: host
@@ -96,31 +96,9 @@
tags: tags:
- yggdrasil - yggdrasil
# - name: "Deployer - DHCP - Install"
# ansible.builtin.apt:
# name:
# - isc-dhcp-server
# state: latest
# - name: "Deployer - DHCP - Config"
# ansible.builtin.template:
# src: './files/dhcp/dhcpd.conf'
# dest: '/etc/dhcp/dhcpd.conf'
# register: deployerTaskD1
# tags:
# - dhcp
# - name: "Deployer : DHCP : Restart"
# ansible.builtin.systemd_service:
# name: isc-dhcp-server
# state: restarted
# enabled: true
# when:
# - (deployerTaskD1 is defined and deployerTaskD1.changed) or deployerTaskD1 is undefined
- name: "Deployer - MariaDB - Create Folder" - name: "Deployer - MariaDB - Create Folder"
ansible.builtin.file: ansible.builtin.file:
path: ~/data/mariadb path: /root/data/mariadb
state: directory state: directory
tags: tags:
- mariadb - mariadb
@@ -140,7 +118,7 @@
restart: on restart: on
network: host network: host
volumes: volumes:
- "~/data/mariadb:/var/lib/mysql" - "/root/data/mariadb:/var/lib/mysql"
restart_policy: always restart_policy: always
env: env:
MYSQL_ROOT_PASSWORD: "{{ config.mariadb.users.root.password }}" MYSQL_ROOT_PASSWORD: "{{ config.mariadb.users.root.password }}"
@@ -205,16 +183,38 @@
tags: tags:
- mariadb - mariadb
- name: "Deployer - Kea - Install"
ansible.builtin.apt:
name:
- kea
state: latest
# - name: "Deployer - DHCP - Config"
# ansible.builtin.template:
# src: './files/dhcp/dhcpd.conf'
# dest: '/etc/dhcp/dhcpd.conf'
# register: deployerTaskD1
# tags:
# - dhcp
# - name: "Deployer : DHCP : Restart"
# ansible.builtin.systemd_service:
# name: isc-dhcp-server
# state: restarted
# enabled: true
# when:
# - (deployerTaskD1 is defined and deployerTaskD1.changed) or deployerTaskD1 is undefined
- name: "Deployer - PowerDNS - Configure - Create Folder" - name: "Deployer - PowerDNS - Configure - Create Folder"
ansible.builtin.file: ansible.builtin.file:
path: "~/data/powerdns/" path: "/root/data/powerdns/"
state: directory state: directory
tags: tags:
- powerdns - powerdns
- name: "Deployer - PowerDNS - Configure - Create Subfolders" - name: "Deployer - PowerDNS - Configure - Create Subfolders"
ansible.builtin.file: ansible.builtin.file:
dest: '~/data/powerdns/{{ item.path }}' dest: '/root/data/powerdns/{{ item.path }}'
state: directory state: directory
with_filetree: './files/powerdns/' with_filetree: './files/powerdns/'
loop_control: loop_control:
@@ -227,7 +227,7 @@
- name: "Deployer - PowerDNS - Configure - Generating & Transferring Files" - name: "Deployer - PowerDNS - Configure - Generating & Transferring Files"
ansible.builtin.template: ansible.builtin.template:
src: '{{ item.src }}' src: '{{ item.src }}'
dest: '~/data/powerdns/{{ item.path }}' dest: '/root/data/powerdns/{{ item.path }}'
register: deployerTaskP1 register: deployerTaskP1
with_filetree: './files/powerdns/' with_filetree: './files/powerdns/'
loop_control: loop_control:
@@ -253,7 +253,7 @@
network: host network: host
restart_policy: always restart_policy: always
volumes: volumes:
- "~/data/powerdns/config.conf:/etc/powerdns/pdns.conf:ro" - /root/data/powerdns/config.conf:/etc/powerdns/pdns.conf:ro"
when: when:
- (deployerTaskP1 is defined and deployerTaskP1.changed) or deployerTaskP1 is undefined or (deployerTaskP2 is defined and deployerTaskP2.changed) or deployerTaskP2 is undefined - (deployerTaskP1 is defined and deployerTaskP1.changed) or deployerTaskP1 is undefined or (deployerTaskP2 is defined and deployerTaskP2.changed) or deployerTaskP2 is undefined
tags: tags:
@@ -261,14 +261,14 @@
- name: "Deployer - Nginx - Configure - Create Folder" - name: "Deployer - Nginx - Configure - Create Folder"
ansible.builtin.file: ansible.builtin.file:
path: "~/data/nginx/" path: "/root/data/nginx/"
state: directory state: directory
tags: tags:
- nginx - nginx
- name: "Deployer - Nginx - Configure - Create Subfolders" - name: "Deployer - Nginx - Configure - Create Subfolders"
ansible.builtin.file: ansible.builtin.file:
dest: '~/data/nginx/{{ item.path }}' dest: '/root/data/nginx/{{ item.path }}'
state: directory state: directory
with_filetree: './files/nginx/' with_filetree: './files/nginx/'
loop_control: loop_control:
@@ -281,7 +281,7 @@
- name: "Deployer - Nginx - Configure - Generating & Transferring Files" - name: "Deployer - Nginx - Configure - Generating & Transferring Files"
ansible.builtin.template: ansible.builtin.template:
src: '{{ item.src }}' src: '{{ item.src }}'
dest: '~/data/nginx/{{ item.path }}' dest: '/root/data/nginx/{{ item.path }}'
register: deployerTaskN1 register: deployerTaskN1
with_filetree: './files/nginx/' with_filetree: './files/nginx/'
loop_control: loop_control:

View File

@@ -12,14 +12,14 @@
- "task.stdout.find('0 upgraded, 0 newly installed, 0 to remove') == -1" - "task.stdout.find('0 upgraded, 0 newly installed, 0 to remove') == -1"
- name: "Init : Python 3 : Configure - Virtual Environment : Test" - name: "Init : Python 3 : Configure - Virtual Environment : Test"
ansible.builtin.raw: "~/.venv/ansible/bin/pip3" ansible.builtin.raw: "/root/.venv/ansible/bin/pip3"
register: task632 register: task632
changed_when: false changed_when: false
failed_when: false failed_when: false
- name: "Init : Python 3 : Configure - Virtual Environment : Delete" - name: "Init : Python 3 : Configure - Virtual Environment : Delete"
ansible.builtin.file: ansible.builtin.file:
path: "~/.venv/ansible" path: "/root/.venv/ansible"
state: absent state: absent
when: when:
- "task632.stdout.find(\"ModuleNotFoundError: No module named 'pip'\") != -1" - "task632.stdout.find(\"ModuleNotFoundError: No module named 'pip'\") != -1"
@@ -29,7 +29,7 @@
name: pip name: pip
state: latest state: latest
extra_args: --upgrade extra_args: --upgrade
virtualenv: ~/.venv/ansible virtualenv: /root/.venv/ansible
virtualenv_command: "python3 -m venv" virtualenv_command: "python3 -m venv"
- name: "Installer : Tools : Install" - name: "Installer : Tools : Install"
@@ -102,22 +102,22 @@
name: ansible name: ansible
state: latest state: latest
extra_args: --upgrade extra_args: --upgrade
virtualenv: ~/.venv/ansible virtualenv: /root/.venv/ansible
virtualenv_command: "python3 -m venv" virtualenv_command: "python3 -m venv"
tags: tags:
- ansible - ansible
- name: "Installer : Ansible : Create Folder" - name: "Installer : Ansible : Create Folder"
ansible.builtin.file: ansible.builtin.file:
path: ~/bin path: /root/bin
state: directory state: directory
tags: tags:
- ansible - ansible
- name: "Installer : Ansible : Create Symbolic Links" - name: "Installer : Ansible : Create Symbolic Links"
ansible.builtin.file: ansible.builtin.file:
src: ~/.venv/ansible/bin/{{ binary }} src: /root/.venv/ansible/bin/{{ binary }}
dest: ~/bin/{{ binary }} dest: /root/bin/{{ binary }}
state: link state: link
vars: vars:
binaries: binaries:
@@ -144,7 +144,7 @@
name: "{{ library }}" name: "{{ library }}"
state: latest state: latest
extra_args: --upgrade extra_args: --upgrade
virtualenv: ~/.venv/ansible virtualenv: /root/.venv/ansible
virtualenv_command: "python3 -m venv" virtualenv_command: "python3 -m venv"
vars: vars:
libraries: libraries:
@@ -164,7 +164,7 @@
name: pymysql name: pymysql
state: latest state: latest
extra_args: --upgrade extra_args: --upgrade
virtualenv: ~/.venv/ansible virtualenv: /root/.venv/ansible
virtualenv_command: "python3 -m venv" virtualenv_command: "python3 -m venv"
tags: tags:
- mariadb - mariadb
@@ -184,7 +184,7 @@
name: "PVJJK 1.VOS TJAS - Infra - Maintenance" name: "PVJJK 1.VOS TJAS - Infra - Maintenance"
hour: "*/3" hour: "*/3"
minute: "0" minute: "0"
job: "~/.venv/ansible/bin/ansible-pull -U ssh://git@github.com/cwchristerw/tjas-infra -d ~/.ansible/pull/pvjjk-1vos-tjas/infra --accept-host-key --private-key ~/.ssh/keys/pvjjk-1vos-tjas/infra --vault-password-file ~/.ansible/vault/pvjjk-1vos-tjas tasks.yml -t maintenance" job: "/root/.venv/ansible/bin/ansible-pull -U ssh://git@github.com/cwchristerw/tjas-infra -d /root/.ansible/pull/pvjjk-1vos-tjas/infra --accept-host-key --private-key /root/.ssh/keys/pvjjk-1vos-tjas/infra --vault-password-file /root/.ansible/vault/pvjjk-1vos-tjas tasks.yml -t maintenance"
tags: tags:
- cron - cron
@@ -192,6 +192,6 @@
ansible.builtin.cron: ansible.builtin.cron:
name: "PVJJK 1.VOS TJAS - Infra - Deployer" name: "PVJJK 1.VOS TJAS - Infra - Deployer"
minute: "*/5" minute: "*/5"
job: "~/.venv/ansible/bin/ansible-pull -U ssh://git@github.com/cwchristerw/tjas-infra -d ~/.ansible/pull/pvjjk-1vos-tjas/infra --accept-host-key --private-key ~/.ssh/keys/pvjjk-1vos-tjas/infra --vault-password-file ~/.ansible/vault/pvjjk-1vos-tjas tasks.yml -t deployer" job: "/root/.venv/ansible/bin/ansible-pull -U ssh://git@github.com/cwchristerw/tjas-infra -d /root/.ansible/pull/pvjjk-1vos-tjas/infra --accept-host-key --private-key /root/.ssh/keys/pvjjk-1vos-tjas/infra --vault-password-file /root/.ansible/vault/pvjjk-1vos-tjas tasks.yml -t deployer"
tags: tags:
- cron - cron

View File

@@ -4,7 +4,7 @@
name: "{{ library }}" name: "{{ library }}"
state: latest state: latest
extra_args: --upgrade extra_args: --upgrade
virtualenv: ~/.venv/ansible virtualenv: /root/.venv/ansible
virtualenv_command: "python3 -m venv" virtualenv_command: "python3 -m venv"
vars: vars:
libraries: libraries:
@@ -24,7 +24,7 @@
name: ansible name: ansible
state: latest state: latest
extra_args: --upgrade extra_args: --upgrade
virtualenv: ~/.venv/ansible virtualenv: /root/.venv/ansible
virtualenv_command: "python3 -m venv" virtualenv_command: "python3 -m venv"
- name: "Maintenance : MariaDB : Dependencies / Python Library : pymysql" - name: "Maintenance : MariaDB : Dependencies / Python Library : pymysql"
@@ -32,7 +32,7 @@
name: pymysql name: pymysql
state: latest state: latest
extra_args: --upgrade extra_args: --upgrade
virtualenv: ~/.venv/ansible virtualenv: /root/.venv/ansible
virtualenv_command: "python3 -m venv" virtualenv_command: "python3 -m venv"
- name: "Maintenance : Podman : Prune" - name: "Maintenance : Podman : Prune"