I gave this presentation at the ChiNOG 11 conference, May 11th, 2023. https://chinog.org/
Author: mytechgnome
Automated ThousandEyes Raspberry Pi image customization
If you haven’t caught this yet, I am a huge fan of ThousandEyes! I was working on a project where we were planning to deploy ThousandEyes agents to hundreds of sites, and to keep costs down we were going to use the Raspberry Pi 4 Model B. Having to image hundreds of SD cards was going to be a nightmare, so I wanted to automate the ThousandEyes Raspberry Pi agent image customization process to simplify the deployment.
Full disclosure: I started this project just as the supply chain issues were hitting the Pi market, and I left that job a few months later. I was never able to run this at scale, but I was able to use this for the few units I was able to get my hands on.
I also have a series on getting ThousandEyes deployed in a lab environment if you want to read more on getting ThousandEyes running: https://www.mytechgnome.com/2022/03/28/thousandeyes-walkthrough-part-1-what/
Hardware/Software required
- Raspberry Pi 4 Model B – 4GB+ RAM
- (Optional) Second Raspberry Pi (doesn’t need to be a 4, but needs a USB port and Ubuntu desktop support)
- 2x 32GB micro SD card (the following are recommended by ThousandEyes)
- Samsung EVO Plus (32GB minimum required)
- SanDisk Extreme (32 GB minimum required)
- Ubuntu Desktop OS image https://ubuntu.com/download/raspberry-pi/thank-you?version=22.04.2&architecture=desktop-arm64+raspi
- ThousandEyes account – you can sign up for trial here: https://www.thousandeyes.com/signup/
- USB microSD card adapter
Configure Pi for imaging
I used a Raspberry Pi as the system for building the images. I found it makes the process much easier, but this isn’t a hard requirement. The main thing is you will need to be able to mount a Linux file system, and it seemed to work much better using a native Ubuntu instance instead of trying to map an SD card to a VM or WSL instance.
- Using your preferred tool, flash the Ubuntu image onto one of the microSD cards – these are both good options:
- Boot a Pi using the newly flashed Ubuntu image and complete the setup
Automated and Manual Processes
I have an automated process available at my GitHub page: https://github.com/mytechgnome/TE-Imaging
The automation uses a JSON file with the device-specific information. You could automate the process of filling out the hostname and IP info if you have that info in an IPAM or similar platform.
How to use the vars.json file:
- Token Value – Group token from ThousandEyes portal
- Image name – Shouldn’t need to do anything with this, unless ThousandEyes changes the image file name
- SSH key – Leave blank if you aren’t adding a key, otherwise paste in the contents of the public key file
- Devices – Duplicate the device objects as needed
- Hostname – The name of the specific agent
- IP – Assign static IP or for DHCP, leave it blank- “”
- Subnet mask and gateway – self explanatory
- DNS – Also self explanatory. If you’re only using one DNS server, leave DNS2 blank- “”

Below is the manual process. The overall process is the same as the automated script, but with less automated goodness. If you want to understand how the automated process works, you can read through the manual process to get a better understanding.
Mount the ThousandEyes image
Before we can customize the image we need to mount it. Run the following steps from a terminal on the imaging Pi created previously.
- Download the ThousandEyes image
wget https://app.thousandeyes.com/install/downloads/appliance/thousandeyes-appliance.rpi4.img.xz
- Note: The download path might change. The download link can be accessed from the ThousandEyes Add New Enterprise Agent page: https://app.thousandeyes.com/settings/agents/enterprise/?section=agents&add-agent
- Decompress the image
unxz -k thousandeyes-appliance.rpi4.img.xz
- Create a mount directory
mkdir /tmp/temount
- Mount the image
sudo mount -o loop,offset=269484032 thousandeyes-appliance.rpi4.img /tmp/temount
- Note: Because there are two partitions, we need to mount the second partition
- If this doesn’t work it could be caused by a change in the partition layout, use these steps to get the correct offset
fdisk -l thousandeyes-appliance.rpi4.img
- Here’s an example output:
Disk thousandeyes-appliance.rpi4.img: 4.07 GiB, 4367262720 bytes, 8529810 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x354db354
Device Boot Start End Sectors Size Id Type
thousandeyes-appliance.rpi4.img1 * 2048 526335 524288 256M c W95 FAT32 (LBA)
thousandeyes-appliance.rpi4.img2 526336 8529809 8003474 3.8G 83 Linux - Multiply the sector size (512) by the start block (526336) and use that value in the offset.
- If this doesn’t work it could be caused by a change in the partition layout, use these steps to get the correct offset
- Note: Because there are two partitions, we need to mount the second partition
- Verify the image mounted
ls /tmp/temount/
- There should be several folders listed. If not, check the offset mentioned in step 4.
Customize the image
There are three files that need to be modified to get the image ready.
- Apply the ThousandEyes Account Token
sudo sed -i 's/<account-token>/$TOKEN/g' /tmp/temount/etc/te-agent.cfg
- Note: replace $TOKEN with your token value.
- Follow these steps to get your account token:
- Open a web browser and navigate to https://www.thousandeyes.com/
- Log into your account
- Click the Hamburger icon in the top left
- Expand Cloud & Enterprise Agents
- Click Agent Settings
- Click the Add New Enterprise Agent button
- Click the eye button to show the token, or the copy button to store it on the clipboard
- Set the hostname
sudo sed -i 's/tepi/$HOSTNAME/g' /tmp/temount/etc/hostname
- Replace $HOSTNAME with your desired hostname
- Configure a static IP (Optional – by default the appliance will use DHCP)
sudo sed -i 's/dhcp/static/g' /tmp/temount/etc/network/interfaces
sudo echo address $IP >> /tmp/temount/etc/network/interfaces
sudo echo netmask $MASK >> /tmp/temount/etc/network/interfaces
sudo echo broadcast $BROADCAST >> /tmp/temount/etc/network/interfaces
sudo echo gateway $GW >> /tmp/temount/etc/network/interfacessudo sed -i 's/#DNS=/DNS= $DNS/g' /tmp/temount/etc/systemd/resolved.conf
- These values will need to be updated accordingly: $IP $MASK $BROADCAST $GW $DNS
- A second DNS server can be added by simply adding both addresses with a space between them
- Add an SSH key (Optional)
sudo echo $SSH >> /tmp/temount/etc/ssh/keys/thousandeyes/authorized_keys
- You can generate an SSH key with the following command:
ssh-keygen -b 2048 -t rsa
- Copy the contents of the key file and put it in place of $SSH
- You can generate an SSH key with the following command:
- Unmount the image
sudo umount /tmp/temount
Flash the image to a microSD card
This is the easiest part, but also the most time consuming. After plugging in the SD card, find the device path for it by running this:
sudo fdisk -l | grep sd
If the SD card is already has partitions on it the output will show each partition, so if you see /dev/sda1 and /dev/sda2 that’s showing the partitions. The image file contains its own partitions, so it needs to be written directly to the card, not into an existing partition. To do that just ignore the numbers shown, so the destination would be /dev/sda.
To start writing the SD card run this command with the correct destination location.
dd if=thousandeyes-appliance.rpi4.img of=/dev/sda status=progress
Make sure the correct destination is selected, otherwise you might overwrite something you don’t want to lose. It usually takes about 10 minutes to write the SD card. When it’s finished, try booting a Pi using the SD card and it should come up with the correct hostname, IP, and account token.
All set!
After booting the Pi you’ll want to log in and change the local admin username and password
Default username: admin
Default password: welcome
After that, you can double check the setup wizard to make sure everything is good to go. The ThousandEyes agent will reach out to their registration servers and it will use the account token to get assigned to your account. The agent should be online in the portal within a few minutes.
BONUS Fun!
I’m not going to go through all the possible code examples of what you can do with this, but I thought I’d throw out a few things to think about.
- Make API calls into an IPAM to get the site name and IP info, then populate the vars.json file automatically with that data.
- Flip the script – this process builds the site-specific data into the image. Another option would be to use a generic image (still embedding the token and SSH key) and use DHCP addressing. Then, query the ThousandEyes API to find new agents named “tepi” and then remotely update the IP and hostname that way
- A unique SSH key can be added to each image by moving the SSH key value under the devices in the vars.json and moving the SSH section of the script under the per device section, along with changing the variable to use the correct location from vars.json.
- Similarly, you could also create new, unique SSH keys by including the keygen process in the script. Just make sure you keep a copy of the keys somewhere safe!
That’s it! Overall, the process is pretty easy, and far easier than finding Raspberry Pi 4s in stock anywhere… If you use this process to automate the ThousandEyes Raspberry Pi agent image customization, I’d love to hear how it worked for you and what, if any, changes you made to the process. You can add a comment here,
Cisco Press Giveaway 2023! –Concluded–
To show my appreciation for the community, and the constant learning that goes into being an IT professional I thought I’d Cisco Press Giveaway!
The Prize
A free Cisco Press eBook or Video Resource!
You can browse the Cisco Press catalog here: https://www.ciscopress.com/
How to enter:
Entry is simple. Do any of the following (each one counts as an entry)
- Comment on this post with what book or video you’re interested in (make sure to include contact info so I can reach you if you win)
- Like, share/retweet my Tweet or LinkedIn post
- Comment on my Giveaway Tweet or LinkedIn post with the book or video you’re interested in.
- Share a link to this blog post
- Follow me on LinkedIn or Twitter
- Twitter: https://twitter.com/Ipswitch
- LinkedIn: https://www.linkedin.com/in/dkelcher/
Any of the above activities between 10pm GMT February 15th and 10pm GMT February 22nd, 2023 will be entered. I’ll randomly select one entry and contact the winner to arrange delivery.
That’s it. Pretty simple.
Shout outs!
First off, I want to thank the Cisco Insider Advocates program! This prize offered is a reward I’d earned through that program, and since I already own over 30 Cisco Press books I thought it’d be great to pass along the opportunity to someone that’s looking to pick up some new skills.
I also have to say thank you to community programs like Cisco Insider Champions, VMware vExpert, Tech Field Day, and so many others. Being part of these communities has been far more benefitial than I’d ever imagined. Through them I’ve had the opportunity to meet some awesome people, and improve myself both professionally and personally.
Last, but certainly not least, is you! The IT community member that’s working to learn new skills. I know I wouldn’t be for the community. I’ve learned a huge amount from blogs, books, videos, forums, etc., and I appreciate anyone that’s actively working to learn and share their knowledge!
The Drawing!
Before announcing the winner, I wanted to provide some transparency in how the winner was selected. I compiled a list of all blog post comments, as well as Twitter and LinkedIn interactions in a spreadsheet. I then used Random.org to generate a randomized set of numbers that were assigned to each entry, similar to a raffle ticket number. Finally, I used Random.org to generate a number from the total range of entries, with the winner being the whoever had the matching number assigned to their entry.
And the winner is…
<Drum roll>
Sainty Thomas! Congrats!
https://twitter.com/SaintyT https://www.linkedin.com/in/sainty-thomas-20140921
CCDE Journey (Take 2)
Back in 2020 I was planning to take the CCDE exam, but those plans were derailed by a little thing called a global pandemic. With test centers closed for an unknown period, I decided to wait until things calmed down before I started to really dig into it. Then, in 2021 it was announced that the CCDE was moving to version 3.0. I didn’t want to get end up in a race against the sunset of the v2 exam, which meant waiting until the release of v3. Add in some travel, a new job, and a handful of other events that distracted from my CCDE plan, and here I am, ready to give this another go.
I’m planning to continually add content as I’m learning new things, both as a way to help me remember what I’m covering, and hopefully in a way that might help others that are either working towards the CCDE or just looking to pick up bits of information along the way.
Study Materials
I have a handful of material that I’ll be using for the CCDE prep.
Primary resources:
- CCDE Study Guide: https://www.ciscopress.com/store/ccde-study-guide-9781587144615
- CCDE v3 Practice Labs: https://www.ciscopress.com/store/ccde-v3-practice-labs-preparing-for-the-cisco-certified-9780137499854
- In-Depth CCDE https://orhanergun.net/ebook/ccde-in-depth-book
- CCDE v3 Training: https://orhanergun.net/courses/self-paced-ccde-course
Additional resources:
- CCDE v3 Learning Matrix: https://learningnetwork.cisco.com/s/ccde-design-expert?tabset-6020b=601f6
- There are tabs with reading suggestions for each topic area.
- This is the list of books, articles, blogs, and whitepapers in the matrix:
- Cisco Design Guide: Network Security Baseline
- Cisco Docs: Cisco SD-WAN Security Configuration Guide, Configure Geolocation-Based Firewall Rules for Network Access
- Cisco Docs: FMC – Understanding Traffic Decryption
- Cisco Guide: A Cisco Guide to Defending Against Distributed Denial of Service Attacks
- Cisco Learning Network Blog: Optical Fiber Explained and Demystified
- Cisco Press: CCIE Routing and Switching v5.0 Official Cert Guide, Volume 1, 5th Edition
- Cisco Press: CCIE WIreless v3 Study Guide Cisco Press: CCNP and CCIE Enterprise Core ENCOR 350-401 Official Cert Guide
- Cisco Press: CCNP and CCIE Security Core SCOR 350-701 Official Cert Guide
- Cisco Press: CCNP Enterprise Advanced Routing ENARSI 300-410 Official Cert Guide
- Cisco Press: CCNP Enterprise Wireless Design ENWLSD 300-425 and Implementation ENWLSI 300-430 Official Cert Guide: Designing & Implementing Cisco Enterprise Wireless Networks
- Cisco Press: CCNP Security Identity Management SISE 300-715 Official Cert Guide Cisco Press: Cisco ISE for BYOD and Secure Unified Access, 2nd Edition
- Cisco Press: Cisco Software-Defined Wide Area Networks: Designing, Deploying and Securing Your Next Generation WAN with Cisco SD-WAN
- Cisco Press: Definitive MPLS Network Designs
- Cisco Press: Designing Cisco Network Service Architectures (ARCH) Foundation Learning Guide: (CCDP ARCH 642-874), 3rd Edition
- Cisco Press: Designing for Cisco Network Service Architectures (ARCH) Foundation Learning Guide: CCDP ARCH 300-320, 4th Edition
- Cisco Press: End-to-End QoS Network Design, 2nd Edition
- Cisco Press: IP Multicast, Volume 1: Cisco IP Multicast Networking
- Cisco Press: IPv6 Fundamentals: A Straightforward Approach to Understanding IPv6, 2nd Edition
- Cisco Press: Layer 2 VPN Architectures Cisco Press: MPLS Fundamentals
- Cisco Press: Network Management Fundamentals Cisco Press: Network Security Architectures
- Cisco Press: Network Security Technologies and Solutions (CCIE Professional Development Series)
- Cisco Press: Optimal Routing Design Cisco Press: Routing TCP/IP, Volume 1, 2nd Edition
- Cisco Press: Routing TCP/IP, Volume II: CCIE Professional Development, 2nd Edition
- Cisco Press: The Art of Network Architecture: Business-Driven Design
- Cisco Press: Top-Down Network Design, 3rd Edition
- Cisco Whitepaper: Network Configuration Management
- DevNet: Intro to Coding Fundamentals
- DevNet: Learn Network Prgrammability Basics
- DevNet: Model Driven Programmability
- DevNet: Zero-Touch Provisioning
The CCDE covers a massive range of topics. It will be a fun process working my way through all of it!