This role configures a Linux-LIO based iSCSI target on a Linux host using targetcli
. Additionally this role includes Python modules to interact with targetcli
command which can be used separately for more advanced stuff. Modules implement checking, creating and deleting.
Tested with:
- Ubuntu 20.04
- Ubuntu 22.04
- Archlinux
Documentation about LIO and Target can be found here.
This role is not creating any disks/partitions/LVs. It is expected that they are already present on machine or created by some other role. For example: githubixx.lvm.
see CHANGELOG
# The iSCSI target(s) is/are configured via "iscsi_targets" nested variable.
# A quite minimal setup looks like this example:
#
# iscsi_targets:
# - name: "iqn.2021-11.blog.tauceti:{{ ansible_facts['nodename'] }}"
# disks:
# - name: lun_node1
# path: /dev/vdb
# type: block
# lunid: 0
# initiators:
# - name: iqn.2021-07.blog.tauceti:node1
# authentication:
# userid: node1user
# password: node1pw
# userid_mutual: node1sharedkey
# password_mutual: node1sharedsecret
# mapped_luns:
# - mapped_lunid: 0
# lunid: 0
# portals:
# - ip: "0.0.0.0"
#
# For more information see README.
iscsi_targets: []
The configuration above will create an iSCSI setup that will look like this (Output generated with targetcli 'ls'
):
# o- / .................................................................................... [...]
# o- backstores ......................................................................... [...]
# | o- block ............................................................. [Storage Objects: 1]
# | | o- lun_node1 ................................... [/dev/vdb (1.0GiB) write-thru activated]
# | | o- alua .............................................................. [ALUA Groups: 1]
# | | o- default_tg_pt_gp .................................. [ALUA state: Active/optimized]
# | o- fileio ............................................................ [Storage Objects: 0]
# | o- pscsi ............................................................. [Storage Objects: 0]
# | o- ramdisk ........................................................... [Storage Objects: 0]
# o- iscsi ....................................................................... [Targets: 1]
# | o- iqn.2021-11.blog.tauceti:ubuntu .............................................. [TPGs: 1]
# | o- tpg1 .......................................................... [no-gen-acls, no-auth]
# | o- acls ..................................................................... [ACLs: 1]
# | | o- iqn.2021-07.blog.tauceti:node1 .................................. [Mapped LUNs: 1]
# | | o- mapped_lun0 ........................................ [lun0 block/lun_node1 (rw)]
# | o- luns ..................................................................... [LUNs: 1]
# | | o- lun0 ............................. [block/lun_node1 (/dev/vdb) (default_tg_pt_gp)]
# | o- portals ............................................................... [Portals: 1]
# | o- 0.0.0.0:3260 ................................................................ [OK]
# o- loopback .................................................................... [Targets: 0]
# o- vhost ....................................................................... [Targets: 0]
# o- xen-pvscsi .................................................................. [Targets: 0]
iscsi_targets.name
specifies the name of the iSCSI target (the iSCSI server so to say). As you can see above this entry will appear under the iscsi
node in the targetcli
output.
disks
create one or more block storage object(s). In this case it will be called lun_node1
, the LUN ID will be 0
. The storage type will be a block
device which in this case is located at /dev/vdb
. This device can (and maybe even should) be a logical volume too of course.
initiators
defines all iSCSI initiators (the iSCSI clients - if you want - which wants to access the iSCSI target specified above). Every iSCSI initiator host (client) that wants to connect the iSCSI target (server) needs an entry here. The iSCSI initiator name normally can be found in /etc/iscsi/initiatorname.iscsi
on every initiator (client) after open-iscsi
package has been installed. The authentication
object contains either only userid
and password
and optional also userid_mutual
plus password_mutual
.
mapped_luns
assigns mapped LUNs (logical units) to initiator. Normally mapped_lunid
and lunid
matches the same lunid
in iscsi_targets.disks
. But it also could be different.
portals
allows to specify the IP address the iSCSI target service should listen on. E.g. if 0.0.0.0
is specified then the service will listen on all interfaces on port 3260
. Of course Ansible facts can also be used e.g. {{ ansible_default_ipv4.address | default(ansible_all_ipv4_addresses[0]) }}
.
#######################################
# Settings only relevant for Archlinux
#######################################
# "targetcli-fb" package is needed to configure iSCSI target. For Archlinux
# this package needs to be installed from AUR. This requires an AUR install
# helper like "yay", "paru", "pacaur", "trizen" or "pikaur". If such a helper
# is already installed on the target host then there is no need to install it
# via this role. In this case "iscsi_archlinux_aur_helper" needs to be
# set to "" (empty sting) and this role will skip the installation of an AUR helper.
# The install task picks one of the AUR helper mentioned above (in that order)
# to install the iSCSI packages.
iscsi_archlinux_aur_helper: yay
# While Ansible expects to SSH as root, makepkg or AUR helpers do not allow
# executing operations as root, they fail with "you cannot perform this
# operation as root". It is therefore recommended to have a user, which
# is non-root but has no need for password. If "iscsi_archlinux_aur_helper"
# variable is set it is assumed that the AUR helper user doesn't exist yet
# so it will be created. The user will be part of the "wheel" group.
iscsi_archlinux_aur_helper_user: aur_builder
For Archlinux kewlfft.aur Ansible collection is used to 1) install an AUR helper like yay and 2) to install targetcli utility from Archlinux User Repository.
- hosts: your-host
become: true
gather_facts: true
roles:
- githubixx.iscsi_target
vars:
iscsi_targets:
- name: "iqn.2021-11.blog.tauceti:{{ ansible_facts['nodename'] }}"
disks:
- name: lun_node1
path: /dev/vdb
type: block
lunid: 0
initiators:
- name: iqn.2021-07.blog.tauceti:node1
authentication:
userid: node1user
password: node1pw
userid_mutual: node1sharedkey
password_mutual: node1sharedsecret
mapped_luns:
- mapped_lunid: 0
lunid: 0
portals:
- ip: "0.0.0.0"
This role has a small test setup that is created using Molecule, libvirt (vagrant-libvirt) and QEMU/KVM. Please see my blog post Testing Ansible roles with Molecule, libvirt (vagrant-libvirt) and QEMU/KVM how to setup. The test configuration is here.
Afterwards molecule can be executed:
molecule converge
This will setup a few virtual machines (VM) with different supported Linux operating systems and installs iscsi_target
role.
To run a few tests:
molecule verify
To clean up run
molecule destroy
MIT/BSD
Original author: Ondrej Famera ansible.targetcli
Additional author: Ricardo Sanchez ansible-role-iscsi_target
Additional author (this role version): https://www.tauceti.blog