So that others don't have to spend time trying to figure out how to automate the process of configuring Beckhoff IPCs (or other industrial PCs), I have created this repository which is an example of how to use the open source Ansible tool to automate the process of deploying a complete IPC configuration from one to many IPCs.
Review roles/common/tasks/main.yml to get a sense for what is possible with this example. You can use this as a starting point for your own configuration.
To run the example you will need to clone this repository onto a Linux PC or into Windows Subsystem for Linux. Then install ansible and some dependencies noted below. On the target IPC you will need to run a few commands from Powershell to enable remote management. Then you can run the following command from the root of the repository:
ansible-playbook -i staging.yml site.yml --ask-vault-pass
And if all goes well you will have a configured IPC. Please read the rest of this document for more information.
Ansible is an open source tool that allows you to automate the configuration of one or more computers. It uses the concept of playbooks to define the configuration of a computer. A playbook is a YAML file that defines a series of tasks to execute on target systems. See the Ansible documentation for more information on playbooks.
While you could use Powershell scripts to manually set up IPCs, it is more efficient to leverage a tool that has great support for automating the configuration of computers.
This repository is provided as an example of how to use Ansible to automate the configuration of IPCs. It is not intended to be a complete solution for configuring IPCs. It is intended to be a starting point for you to create your own solution. You will need to modify the example playbooks to meet your specific needs. Bear in mind that recommended security practices may have not been implemented in this example. You should review the example playbooks to ensure that they meet your security requirements.
See also the license.
To run this example you need to at least have a "control node", which can be your laptop or a server, and a "managed node", which is the IPC you want to configure. The control node is the computer that will run the Ansible playbooks. The managed node is the IPC that will be configured by the Ansible playbooks.
The control node must either be Windows running Windows Subsystem for Linux (WSL), or a Linux computer. This is required for Ansible. On the control node you must install Ansible. See the Ansible documentation for more information on installing Ansible, but the basic steps are:
- Install Python 3
- Clone this repository into a folder on the control node
git clone https://github.com/dfreiberger/beckhoff-ipc-management-ansible.git cd beckhoff-ipc-management-ansible
- Create a virtual environment for Ansible (this is optional but recommended)
# run only once when setting up the virtual environment python3 -m venv venv # run each time you want to use the virtual environment source venv/bin/activate
- Install Ansible and pywinrm using pip, for example:
pip install ansible pywinrm
- If you want to use the OPC-UA setup tasks, you will also need to install the asyncua library:
pip install asyncua
The managed node can be an Windows IPC running Windows 10 or newer, but for this example it is assumed that it is a Beckhoff IPC such as a CX or C series IPC. On each managed node you must run the following commands from Powershell to enable remote management:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
winrm quickconfig
winrm set winrm/config/service '@{AllowUnencrypted="true"}'
winrm set winrm/config/service/auth '@{Basic="true"}'
You may need to run the following to get the interface index and set it to private if the prior winrm commands fail:
Get-NetConnectionProfile
Set-NetConnectionProfile -InterfaceIndex 5 -NetworkCategory Private
This playbook requires access to a private Nuget or Chocolatey feed that can supply the following packages:
Package | Version | Used in Role |
---|---|---|
TwinCAT-XAR | 3.1.4024.20 | common |
TF6100-OPC-UA | 4.4.67 | common |
TF6250-Modbus-TCP | 3.1.4024.0 | machine-variant-a |
You can create a feed in a few ways. One is to create a network share where you place nuget packages. Another, more performant method is to set up a feed using a tool such as ProGet.
You will need to create Nuget packages from the TwinCAT XAR and TF6100 executables in order to place them into the feed. For this there is an example script in the utils/package_creation
directory.
Note: run these commands from a Windows environment, not WSL.
cd package_creation
# create a nuget package for TwinCAT
.\createPackageFromInstaller.ps1 "TwinCAT-XAR" "TC31-XAR-Setup.3.1.4024.20.exe" 3.1.4024.20 "Internal" "Internal Use Only" '/s /v"/qr ALLUSERS=1 REBOOT=ReallySuppress"'
# create a nuget package for TF6100-OPC-UA
.\createPackageFromInstaller.ps1 "TF6100-OPC-UA" "TF6100-OPC-UA.4.4.67.0.exe" 4.4.67.0 "Internal" "Internal Use Only" '/S /v/qn'
To test a package install locally run
$PackageName = "TF6100-OPC-UA"
choco uninstall $PackageName -f
choco install $PackageName -fd -y -s ".\packages"
Publish the package to your feed using the following command:
cpush .\packages\TF6100-OPC-UA.4.4.67.0.nupkg -source <your feed> -apiKey <your api key> --force
To follow best practices for storing passwords, you need to set up a vault that contains a few items.
-
Create a file called
vault
in thegroup_vars/all
directory.ansible-vault create group_vars/all/vault
Set a password for the vault when prompted, and record this somewhere safe.
-
Add the following to the vault file (note that the usernames associated with these passwords are in the
group_vars/all/all.yml
file)):# this is the password for the IPC user (e.g. this would be "1" by default for Beckhoff IPCs) vault_ansible_password: <password> # this is the password for the IPC user with administrative permissions (e.g. this would be "1" by default for Beckhoff IPCs). This is used when a task requires elevated privileges as denoted by adding a "become: true" to a task vault_ansible_become_password: <password> # this is the password to configure the OPC-UA server to use vault_tf6100_opc_ua_password: <password> # it isn't necessary to store this in the vault, I did this so that it is easy to update this repository with a local copy for testing vault_internal_nuget_repo: <repo>
-
Encrypt the vault file by closing the editor
If you need to edit the file later, use ansible-vault edit group_vars/all/vault
and enter the password when prompted.
Note that the above variables are referenced in the group_vars/all/main.yml
file.
If you want to skip all of this, just add the passwords to the group_vars/all/all.yml
. This is not recommended but can get you started more quickly.
To run the playbooks, you need to run the following command from the root of the repository:
ansible-playbook -i staging.yml site.yml --ask-vault-pass
In this repository I've defined a few roles that can be used to configure an IPC. The roles are defined in the roles
directory. The common
role is applied to all hosts. The machine-variant-a
and machine-variant-b
roles are applied to hosts that are in the machine-variant-a
and machine-variant-b
groups respectively. The machine-variant-a
and machine-variant-b
groups are defined in the staging.yml
file.
This project is set up per the recommendations from Ansible. The common role defines all common tasks to apply across all hosts. A couple of example secondary roles have been created, these could be different variants of machines on a factory floor.
To create new roles use the following command:
ansible-galaxy init <role name>
To assign roles to a particular group of hosts, edit the site.yml file and add the role to the list of roles for the group. e.g. if you added a new role machine-variant-b
and you wanted to apply it to the host group with the same name of machine-variant-b
you would add the role to the list of roles for that group:
- hosts: machine-variant-b
roles:
- common
- machine-variant-b
This project does not deploy the actual PLC code, although this would be easy to add. A couple of methods of doing this include:
- Copy the pre-built build files over with the
win_copy
module toC:\TwinCAT\3.1\Boot
- Use the TwinCAT 3 Automation Interface to build and push the projects from a build server
The reason I did not add this is that typically (in a fully automated environment) you would deploy PLC code from a build server utilizing a CI/CD pipeline. This is currently outside the scope of this example.
If you would like to contribute to this project, please fork the repository and submit a pull request. I will review the pull request and merge it if it meets the requirements of the project. Examples of good contributions:
- Adding a new role that configures a specific IPC
- Adding a new role that configures a specific software package related to Beckhoff or IPCs, for example adding new TF function installers
- Adding a new role that configures a specific Windows setting