Ansibleで、ユーザパスワード期限ポリシーを変えたい!!
対応状況整理
項目 | chageオプション | Ansible(userモジュール) |
---|---|---|
min days | -m | password_expire_min |
max days | -M | password_expire_max |
warn days | -W | 非対応 |
Inactive days | -I | 非対応 |
対応してないので、
shellモジュール or カスタムモジュールしかない。
参考:
https://www.ansiblepilot.com/articles/user-password-expiration-ansible-module-user/
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/user_module.html
カスタムモジュール作成
update_password_policy.py
#!/usr/bin/python
from ansible.module_utils.basic import AnsibleModule
import os
def get_current_policy(module, user):
with open("/etc/shadow", "r") as shadow_file:
shadow_data = shadow_file.readlines()
user_data = None
for line in shadow_data:
if line.startswith(user + ":"):
user_data = line
break
if not user_data:
module.fail_json(msg="User not found in /etc/shadow")
_, _, mindays, maxdays, warndays, inactive, _, _, = user_data.split(":")[1:9]
current_policy = {
"maxdays": int(maxdays) if maxdays != '' else -1,
"mindays": int(mindays) if mindays != '' else -1,
"warndays": int(warndays) if warndays != '' else -1,
"inactive": int(inactive) if inactive != '' else -1
}
return current_policy
def main():
module_args = dict(
user=dict(type='str', required=True),
maxdays=dict(type='int', required=True),
mindays=dict(type='int', required=True),
warndays=dict(type='int', required=True),
inactive=dict(type='int', required=True)
)
module = AnsibleModule(
argument_spec=module_args,
supports_check_mode=True
)
# Get current password policy
current_policy = get_current_policy(module, module.params['user'])
chage_command = [
"chage",
"-M", str(module.params['maxdays']),
"-m", str(module.params['mindays']),
"-W", str(module.params['warndays']),
"-I", str(module.params['inactive']),
module.params['user']
]
# Check if policy needs to be updated
update_required = False
for param in ['maxdays', 'mindays', 'warndays', 'inactive']:
if module.params[param] != current_policy[param]:
update_required = True
break
# If update is not required, exit with no changes
if not update_required:
module.exit_json(changed=False, msg="Password policy is already up-to-date")
if module.check_mode:
module.exit_json(changed=True)
rc = os.system(" ".join(chage_command))
if rc == 0:
result = {"changed": True, "user": module.params["user"]}
else:
result = {"failed": True, "msg": "chage command failed with return code {}".format(rc)}
module.exit_json(**result)
if __name__ == '__main__':
main()
デバッグ
module_args.json
{
"ANSIBLE_MODULE_ARGS": {
"user": "hogehoge",
"mindays": "-1",
"maxdays": "-1",
"warndays": "-1",
"inactive": "-1"
}
}
$ python3 update_password_policy.py < module_args.json
カスタムモジュールの配置場所とか、Ansible実行方法は流石は割愛
余談。
-I(アイ)
-l(エル)
見辛すぎだろ。