diff --git a/vm-ansible/Pulumi.yaml b/vm-ansible/Pulumi.yaml index 8fc7ae7..b373e5f 100644 --- a/vm-ansible/Pulumi.yaml +++ b/vm-ansible/Pulumi.yaml @@ -1,5 +1,47 @@ +--- name: ${PROJECT} description: ${DESCRIPTION} runtime: python template: description: A Pulumi deployment with libvirt and Python + config: + libvirt:uri: + type: String + default: "qemu:///system" + description: "QEMU service path" + hostname: + type: String + default: ${PROJECT} + description: Hostname + image: + type: String + default: bookworm + description: Image name (see additional_configs.py) + vcpu: + type: Integer + default: 1 + description: Number of vCPU of the VM + ram: + type: Integer + default: 2048 + description: MBs of RAM of the VM + disksize: + type: Integer + default: 20 + description: GBs of disk space of the VM + poolpath: + type: String + default: /var/tmp/libvirt/pulumi + description: Path to the new pool + username: + type: String + default: syntaxerrormmm + description: Username to create in the cloud-init phase + password: + type: String + default: cicciopasticcio + description: Password of the username in the cloud-init phase + playbooks: + type: String + default: 'deploy.yml' + description: "Ansible Playbooks to implement, separate by commas." diff --git a/vm-ansible/__main__.py b/vm-ansible/__main__.py index eccc3a5..fd8cdc1 100644 --- a/vm-ansible/__main__.py +++ b/vm-ansible/__main__.py @@ -3,55 +3,51 @@ import pulumi import pulumi_libvirt as lv import pulumi_command as command -import yaml -from dotmap import DotMap +import pulumiverse_time as time +import additional_configs as add from jinja2 import Template from passlib.hash import sha512_crypt -conf = DotMap(yaml.safe_load(open("./input.yaml", "r").read())) -cloudimages = DotMap(yaml.safe_load(open('cloud-images.yaml').read())) - -# Replacing readed password with its own counterpart. -conf.password = sha512_crypt.hash(conf.password, rounds=4096) - config = pulumi.Config() +env = { + 'username': config.get('username'), + 'password': config.get('password'), + 'sshkeys': add.SSH_KEYS, + 'name': config.get('hostname'), +} + pool = lv.Pool("pool", type = "dir", - path = conf.poolpath + path = config.get('poolpath') ) baseimg = lv.Volume("base-image", pool = pool.name, - source = cloudimages[conf.image] - #source = "https://cdimage.debian.org/images/cloud/bullseye-backports/20220711-1073/debian-11-backports-generic-amd64-20220711-1073.qcow2" + source = add.CLOUD_IMAGES[config.get('image')] ) volume = lv.Volume("disk", base_volume_id = baseimg.id, pool = pool.name, - size = int(conf.disksize) * 1024 ** 3 + size = int(config.get('disksize')) * 1024 ** 3 ) # Stream configuration files -userdata = Template(open("./cloud-init/user-data.jinja", "r").read()).render(conf) -metadata = Template(open("./cloud-init/meta-data.jinja", "r").read()).render(conf) -networkconfig = open("./cloud-init/network-config", "r").read() - cloudinit = lv.CloudInitDisk("cloud-init", - meta_data = metadata, - user_data = userdata, - network_config = networkconfig + meta_data = Template(open("./cloud-init/meta-data.jinja", "r").read()).render(env), + user_data = Template(open("./cloud-init/user-data.jinja", "r").read()).render(env), + network_config = open("./cloud-init/network-config", "r").read() ) -vm = lv.Domain(conf.name, +vm = lv.Domain(config.get('hostname'), boot_devices = [ lv.DomainBootDeviceArgs( devs = [ "hd", "cdrom" ] ) ], cloudinit = cloudinit.id, - vcpu = conf.vcpu, + vcpu = config.get('vcpu'), disks = [ lv.DomainDiskArgs(volume_id = volume.id, scsi=True) ], - memory = int(conf.ram), + memory = int(config.get('ram')), network_interfaces = [ lv.DomainNetworkInterfaceArgs( network_name = "default", wait_for_lease = True @@ -66,20 +62,25 @@ vm = lv.Domain(conf.name, ) ) -# Creating the inventory file -inventory = command.local.Command("a-inventory", - create = vm.network_interfaces[0]['addresses'][0].apply( - lambda ipaddr: f"echo '{conf.name} ansible_host={ipaddr} ansible_user={conf.username}' >./inventory" - ), - delete = "rm -f ./inventory", +wait_time = time.Sleep("wait_time", create_duration="30s", opts = pulumi.ResourceOptions(depends_on = [ vm ]) ) -# Applying the command -execute_ansible = command.local.Command("a-deploy", - create = f"ansible-playbook {conf.ansible_playbook}", - delete = "rm -f ./ansible.log", - opts = pulumi.ResourceOptions(depends_on = [ inventory ]) +# Creating the inventory file +inventory = command.local.Command("a-inventory", + create = vm.network_interfaces[0]['addresses'][0].apply( + lambda ipaddr: f"echo '{env['name']} ansible_host={ipaddr} ansible_user={env['username']}' >./inventory" + ), + delete = "rm -f ./inventory", + opts = pulumi.ResourceOptions(depends_on = [ wait_time ]) ) +# Applying the command +for playbook in config.get('playbooks').split(','): + execute_ansible = command.local.Command(f"a-{playbook.split('.')[0]}", + create = f"ansible-playbook {playbook}", + delete = "rm -f ./ansible.log", + opts = pulumi.ResourceOptions(depends_on = [ inventory ]) + ) + pulumi.export("ip", vm.network_interfaces[0]['addresses'][0]) diff --git a/vm-ansible/additional_configs.py b/vm-ansible/additional_configs.py new file mode 100644 index 0000000..25dfc13 --- /dev/null +++ b/vm-ansible/additional_configs.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# encoding: utf-8 + +CLOUD_IMAGES = { + 'buster': 'https://cloud.debian.org/images/cloud/buster-backports/latest/debian-10-backports-generic-amd64.qcow2', + 'bullseye': 'https://cloud.debian.org/images/cloud/bullseye-backports/latest/debian-11-backports-generic-amd64.qcow2', + 'bookworm': 'https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2', + 'centos7': 'https://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud-2211.qcow2' +} + +SSH_KEYS = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFioHkaV1NhX6NCqsJakJw8EVBOcDHm1MEbpY499CPtG syntaxerrormmm@fisso", + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILu91hBh8pNRt4eE1pug0Y4jCHZDCcMJ+vj3CiF5EQHV syntaxerrormmm@syntaxxps", + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILH5q/ObtC4VhNT88gebezP/svpvCoQLoZCh4DvUn4xq syntaxerrormmm@taz", + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGdTHkPCPUhvrcGgU9M6/BaEeirStM/kBnFxsLyXyelt syntaxerrormmm@kurotsuchi" +] diff --git a/vm-ansible/cloud-images.yaml b/vm-ansible/cloud-images.yaml deleted file mode 100644 index 3c8c74d..0000000 --- a/vm-ansible/cloud-images.yaml +++ /dev/null @@ -1,4 +0,0 @@ -buster: https://cloud.debian.org/images/cloud/buster-backports/latest/debian-10-backports-generic-amd64.qcow2 -bullseye: https://cloud.debian.org/images/cloud/bullseye-backports/latest/debian-11-backports-generic-amd64.qcow2 -bookworm: https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2 -centos7: https://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud-2211.qcow2 diff --git a/vm-ansible/input.yaml b/vm-ansible/input.yaml deleted file mode 100644 index 2736830..0000000 --- a/vm-ansible/input.yaml +++ /dev/null @@ -1,18 +0,0 @@ ---- -# Basic VM configuration -name: virtual-machine -vcpu: 1 -ram: 2048 -disksize: 20 -username: syntaxerrormmm -password: cicciopasticcio -sshkeys: - - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFioHkaV1NhX6NCqsJakJw8EVBOcDHm1MEbpY499CPtG syntaxerrormmm@fisso" - - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILu91hBh8pNRt4eE1pug0Y4jCHZDCcMJ+vj3CiF5EQHV syntaxerrormmm@syntaxxps" - - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILH5q/ObtC4VhNT88gebezP/svpvCoQLoZCh4DvUn4xq syntaxerrormmm@taz" - -image: bookworm -poolpath: /var/tmp/libvirt/pulumi - -# Ansible configuration -ansible_playbook: deploy.yml diff --git a/vm-ansible/requirements.txt b/vm-ansible/requirements.txt index 85c6487..376d08d 100644 --- a/vm-ansible/requirements.txt +++ b/vm-ansible/requirements.txt @@ -1,8 +1,7 @@ pyyaml>=6.0 -dotmap>=1.3.30 -protobuf==3.20.1 pulumi>=3.0.0,<4.0.0 pulumi_libvirt>=0.3.0 pulumi-command>=0.4.1 +pulumiverse-time Jinja2>=3.1.2 passlib>=1.7.4