diff --git a/.gitignore b/.gitignore index 61ef6bd..1e25f6b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ .DS_Store *_rsa *.pub -# Only include the template: -/host_inventory.yaml +# Only include the templates here. +/host_vars/*/*.yml TCBSD*.vdi TCBSD*.iso diff --git a/Makefile b/Makefile index b496212..834e771 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,9 @@ # This is the IP address of the PLC. PLC_IP ?= -PLC_HOSTNAME ?= my-plcname +PLC_HOSTNAME ?= test-plc-01 PLC_NET_ID ?= $(PLC_IP).1.1 PLC_USERNAME ?= Administrator +PLC_HOST_VARS = host_vars/$(PLC_HOSTNAME)/vars.yml SSH_KEY_FILENAME ?= $(shell pwd)/tcbsd_key_rsa # This auto-detects your local adapter's IP address. It may be completely wrong. @@ -43,16 +44,17 @@ ssh-setup: ssh: ssh -i "$(SSH_KEY_FILENAME)" "$(PLC_USERNAME)@$(PLC_IP)" $(SSH_ARGS) -host_inventory.yaml: Makefile host_inventory.yaml.template +$(PLC_HOST_VARS): Makefile tcbsd-plc.yaml.template # This substitutes our local environment into ``host_inventory.yaml.template`` # and writes ``host_inventory.yaml`` - envsubst < "host_inventory.yaml.template" > "$@" + @mkdir -p $(shell dirname "$@") + envsubst < "tcbsd-plc.yaml.template" > "$@" -run-bootstrap: host_inventory.yaml tcbsd-bootstrap-playbook.yaml - ansible-playbook tcbsd-bootstrap-playbook.yaml -i host_inventory.yaml +run-bootstrap: $(PLC_HOST_VARS) tcbsd-bootstrap-playbook.yaml + ansible-playbook tcbsd-bootstrap-playbook.yaml -run-provision: run-bootstrap host_inventory.yaml tcbsd-provision-playbook.yaml - ansible-playbook tcbsd-provision-playbook.yaml -i host_inventory.yaml +run-provision: run-bootstrap tcbsd-provision-playbook.yaml + ansible-playbook tcbsd-provision-playbook.yaml add-route: # NOTE: the add_route script lazily uses environment variables instead of diff --git a/README.md b/README.md index d71b62f..e64c9c2 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,30 @@ ## twincat-bsd-ansible-testing +twincat-bsd-ansible-testing: trying out ansible for provisioning TwinCAT BSD PLCs. + ### Install requirements -* VirtualBox -* TwinCAT BSD image from Beckhoff +If you have a physical PLC to use, you'll only need the following: + * bash * ansible -* ``gettext`` to interpolate the host inventory template +* ``gettext`` to interpolate the host variable template + +To work using a PLC Virtual Machine (i.e., without a physical PLC), you'll also +need the following: + +* VirtualBox +* TwinCAT BSD image from Beckhoff + +### TcBSD Documentation + +Here's some documentation from Beckhoff on the OS: + +[TwinCAT_BSD_en.pdf](https://download.beckhoff.com/download/Document/ipc/embedded-pc/embedded-pc-cx/TwinCAT_BSD_en.pdf) + +And their security recommendations: + +[IPC_Security_Guideline_TwinCATBSD_en.pdf](https://download.beckhoff.com/download/document/product-security/Guidelines/IPC_Security_Guideline_TwinCATBSD_en.pdf) ### Create a VirtualBox VM @@ -90,12 +108,12 @@ This will generate a VM with: Run: 1. ``make ssh-setup`` (SSH key + initial login) -2. ``make host_inventory.yaml`` (create host inventory configuration file) +2. ``make host_vars/test-plc-01/vars.yml`` (create host variable configuration file) 3. ``make run-bootstrap`` (install Python on the PLC, required for ansible) 4. ``make run-provision`` (provision the PLC) -## Side notes +## Side notes / flight rules ### ADS @@ -109,3 +127,13 @@ Try: $ meson setup build -Dcpp_std=c++14 $ make ``` + +### I have multiple PLCs with different roles, where do I put that information? + +Per-PLC configuration goes in [host_vars/](host_vars). +Overall configuration for the "tcbsd_plc" role goes in +[group_vars/tcbsd_plcs/](group_vars/tcbsd_plcs/). + +The host inventory can be restructured to have whatever hierarchy you so choose; +take a look at the [ansible](https://www.ansible.com/) documentation for further +details. diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..560c134 --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,4 @@ +[defaults] +inventory = ./inventory/ +deprecation_warnings = True +role_path = ./roles diff --git a/group_vars/tcbsd_plcs/vars.yml b/group_vars/tcbsd_plcs/vars.yml new file mode 100644 index 0000000..1c8317d --- /dev/null +++ b/group_vars/tcbsd_plcs/vars.yml @@ -0,0 +1,36 @@ +--- +ansible_user: Administrator +ansible_ssh_private_key_file: /Users/klauer/Repos/twincat-bsd-ansible-testing/tcbsd_key_rsa +ansible_become: true +ansible_become_method: doas +ansible_become_password: 1 # TODO: vault +ansible_python_interpreter: /usr/local/bin/python3 + +# This is the default of 32MB. Set to 67108864 for 64MB of router memory. +tc_locked_memory_size_bytes: 33554432 + +# Heap memory size is not specified by default. If you wish to change the +# default, set this to greater than 0 (e.g., 1024). This must be +# greater than the locked memory size for the router, above. +tc_heap_memory_size_mb: 0 +# Install and use bash in place of sh: +tc_use_bash: true +# Install C/C++ development tools (approximately 1.8GB): +tc_install_cpp_dev_tools: true + +# Install these additional packages: +tc_packages_to_install: + - git + - vim + - ripgrep + +# Configure the following static routes (and only those): +# NOTE: if you don't want to run my arbitrary module, use this instead +# of tc_add_missing_static_routes below +tc_set_fixed_static_routes: [] + +# Alternatively, only add missing routes from the list: +tc_add_missing_static_routes: + - name: PC98125 + address: 192.168.2.110 + net_id: 192.168.2.110.1.1 diff --git a/host_inventory.yaml.template b/host_inventory.yaml.template deleted file mode 100644 index 3ff7a4f..0000000 --- a/host_inventory.yaml.template +++ /dev/null @@ -1,43 +0,0 @@ -# vi: syntax=yaml - -plcs: - hosts: - ${PLC_HOSTNAME}: - ansible_host: ${PLC_IP} - tc_ams_net_id: ${PLC_NET_ID} - vars: - ansible_user: Administrator - ansible_ssh_private_key_file: ${SSH_KEY_FILENAME} - ansible_become: true - ansible_become_method: doas - ansible_become_password: 1 # TODO: vault - ansible_python_interpreter: /usr/local/bin/python3 - # This is the default of 32MB. Set to 67108864 for 64MB of router memory. - tc_locked_memory_size_bytes: 33554432 - # Heap memory size is not specified by default. If you wish to change the - # default, set this to greater than 0 (e.g., 1024). This must be - # greater than the locked memory size for the router, above. - tc_heap_memory_size_mb: 0 - # Install and use bash in place of sh: - tc_use_bash: true - # Install C/C++ development tools (approximately 1.8GB): - tc_install_cpp_dev_tools: true - # Install these additional packages: - tc_packages_to_install: - - git - - vim - - ripgrep - # Configure the following static routes (and only those): - # NOTE: if you don't want to run my arbitrary module, use this instead - # of tc_add_missing_static_routes below - tc_set_fixed_static_routes: [] - # Alternatively, only add missing routes from the list: - tc_add_missing_static_routes: - - name: ${OUR_ROUTE_NAME} - address: ${OUR_IP_ADDRESS} - net_id: ${OUR_NET_ID} - - children: - minimal: - hosts: - ${PLC_HOSTNAME}: diff --git a/host_vars/.gitkeep b/host_vars/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/inventory/plcs.yaml b/inventory/plcs.yaml new file mode 100644 index 0000000..a3e2b0a --- /dev/null +++ b/inventory/plcs.yaml @@ -0,0 +1,8 @@ +--- +plcs: + children: + tcbsd_plcs: + +tcbsd_plcs: + hosts: + test-plc-01: diff --git a/tcbsd-bootstrap-playbook.yaml b/tcbsd-bootstrap-playbook.yaml index e1f4fce..4aa5ef9 100644 --- a/tcbsd-bootstrap-playbook.yaml +++ b/tcbsd-bootstrap-playbook.yaml @@ -1,5 +1,5 @@ --- -- hosts: plcs +- hosts: tcbsd_plcs gather_facts: False tasks: diff --git a/tcbsd-plc.yaml.template b/tcbsd-plc.yaml.template new file mode 100644 index 0000000..6f25518 --- /dev/null +++ b/tcbsd-plc.yaml.template @@ -0,0 +1,3 @@ +--- +ansible_host: ${PLC_IP} +tc_ams_net_id: ${PLC_NET_ID} diff --git a/tcbsd-provision-playbook.yaml b/tcbsd-provision-playbook.yaml index fe922a7..666a35b 100644 --- a/tcbsd-provision-playbook.yaml +++ b/tcbsd-provision-playbook.yaml @@ -1,5 +1,5 @@ --- -- hosts: plcs +- hosts: tcbsd_plcs tasks: - name: Verify connectivity with ping