diff --git a/.gitea/workflows/docker-image.deploy.yml b/.gitea/workflows/docker-image.deploy.yml index c49d34c..3d2098f 100644 --- a/.gitea/workflows/docker-image.deploy.yml +++ b/.gitea/workflows/docker-image.deploy.yml @@ -22,5 +22,6 @@ jobs: uses: docker/build-push-action@v6 with: context: ${{gitea.workspace}}/docker + file: ${{gitea.workspace}}/docker/Dockerfile push: true tags: git.limbosolutions.com/kb/ansible:latest \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..95e35f3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +**/**env.local +**/**.local \ No newline at end of file diff --git a/docker/.gitignore b/docker/.gitignore new file mode 100644 index 0000000..4ac7cc0 --- /dev/null +++ b/docker/.gitignore @@ -0,0 +1,2 @@ +playbook-workspace/** +workspace/** diff --git a/docker/Dockerfile b/docker/Dockerfile index 861654b..10a820f 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -6,3 +6,13 @@ RUN apt-get install -y openssh-client RUN apt-get install python3-pip -y RUN apt-get install python3-virtualenv -y RUN pip3 install ansible --break-system-packages +RUN pip3 install ansible-runner --break-system-packages + +RUN mkdir /project +RUN mkdir /scripts +RUN mkdir /data + +COPY scripts /scripts +COPY playbook-sample-project /project + +ENTRYPOINT ["python3", "/scripts/run.py"] diff --git a/docker/docker-run-ansible-local.sh b/docker/docker-run-ansible-local.sh new file mode 100755 index 0000000..e31e9be --- /dev/null +++ b/docker/docker-run-ansible-local.sh @@ -0,0 +1,16 @@ +#/bin/bash +source docker/docker-run-ansible-local.env.local + + +docker build docker \ + -f docker/Dockerfile \ + -t ${IMAGE_NAME} + +docker run --rm \ + -e ANSIBLE_INVENTORY="${ANSIBLE_PLAYBOOK_INVENTORY}" \ + -e ANSIBLE_PRIVATE_KEY="${ANSIBLE_PLAYBOOK_PRIVATE_KEY}" \ + -e ANSIBLE_REMOTE_USER="${ANSIBLE_PLAYBOOK_REMOTE_USER}" \ + -v ${VOLUME_PATH}:/playbook-project.local $IMAGE_NAME + + + diff --git a/docker/playbook-sample-project/site.yml b/docker/playbook-sample-project/site.yml new file mode 100644 index 0000000..7f55360 --- /dev/null +++ b/docker/playbook-sample-project/site.yml @@ -0,0 +1,9 @@ +- name: Hello from ansible + hosts: all + tasks: + - name: Ping my hosts + ansible.builtin.ping: + + - name: Print message + ansible.builtin.debug: + msg: Hello world diff --git a/docker/scripts/run.py b/docker/scripts/run.py new file mode 100644 index 0000000..63386ea --- /dev/null +++ b/docker/scripts/run.py @@ -0,0 +1,100 @@ +import os +import sys +from ansible_runner import Runner, RunnerConfig +import subprocess + + +""" +https://docs.ansible.com/ansible/latest/cli/ansible-playbook.html + +usage: ansible-playbook [-h] [--version] [-v] [--private-key PRIVATE_KEY_FILE] + [-u REMOTE_USER] [-c CONNECTION] [-T TIMEOUT] + [--ssh-common-args SSH_COMMON_ARGS] + [--sftp-extra-args SFTP_EXTRA_ARGS] + [--scp-extra-args SCP_EXTRA_ARGS] + [--ssh-extra-args SSH_EXTRA_ARGS] + [-k | --connection-password-file CONNECTION_PASSWORD_FILE] + [--force-handlers] [--flush-cache] [-b] + [--become-method BECOME_METHOD] + [--become-user BECOME_USER] + [-K | --become-password-file BECOME_PASSWORD_FILE] + [-t TAGS] [--skip-tags SKIP_TAGS] [-C] [-D] + [-i INVENTORY] [--list-hosts] [-l SUBSET] + [-e EXTRA_VARS] [--vault-id VAULT_IDS] + [-J | --vault-password-file VAULT_PASSWORD_FILES] + [-f FORKS] [-M MODULE_PATH] [--syntax-check] + [--list-tasks] [--list-tags] [--step] + [--start-at-task START_AT_TASK] + playbook [playbook ...] +""" + + +def process_private_Keyfile(rc): + if(os.environ.get('ANSIBLE_PRIVATE_KEY') is not None): + + with open("/root/ansible_private_key", 'w') as file: + file.write(os.environ.get('ANSIBLE_PRIVATE_KEY')) + file.flush() + subprocess.run(['chmod', '600', '/root/ansible_private_key']) + rc.cmdline_args += "--private-key /root/ansible_private_key" + + elif (os.environ.get('ANSIBLE_PRIVATE_KEY_FILE') is not None): + rc.cmdline_args += "--private-key " + os.environ.get('ANSIBLE_PRIVATE_KEY_FILE') + + +def build_cmdLine_args(rc): + + if(rc.cmdline_args is None): + rc.cmdline_args="" + process_private_Keyfile(rc); + if(os.environ.get('ANSIBLE_REMOTE_USER') is not None): + print("---------------------------------------") + print("remote user:") + print(os.environ.get('ANSIBLE_REMOTE_USER')) + print("---------------------------------------") + rc.cmdline_args += " -u " + os.environ.get('ANSIBLE_REMOTE_USER') + + if(os.environ.get('ANSIBLE_VERBOSE') is not None): + print("---------------------------------------") + print("remote user:") + print(os.environ.get('ANSIBLE_VERBOSE')) + print("---------------------------------------") + rc.cmdline_args += " -vvv" + +def execute_playbook(projectdir): + + rc = RunnerConfig( + private_data_dir="/data", + project_dir=projectdir + ) + + rc.playbook=os.environ.get('ANSIBLE_PLAYBOOK', "site.yml") + rc.inventory=os.environ.get('ANSIBLE_INVENTORY', "127.0.0.1,") + build_cmdLine_args(rc) + + if(rc.inventory=="127.0.0.1,"): + rc.cmdline_args += "--limit 127.0.0.1 --connection local" + + rc.prepare() + print("---------------------------------------") + print("command:") + print(rc.generate_ansible_command()) + print("---------------------------------------") + r = Runner(config=rc) + r.run() + +def list_workspace(projectdir): + print("---------------------------------------") + print("project files:" + " " + projectdir) + items=os.listdir(projectdir) + for image in items: + print(image) + print("---------------------------------------") + +def main(): + projectdir = os.environ.get('ANSIBLE_PROJECT_DIR', "/project") + list_workspace(projectdir) + execute_playbook(projectdir) + +main() +