ProgrammingPro #35: Copilot Warnings, PLC Security, GameMaker's Game-Changing Move, and IaC Best Practices
"There was a new programming language that was being created by Dennis Ritchie called C. … it was very interesting to try to develop both algorithms for use in programming language compilers and also looking at new languages to create with which you can solve problems much more readily than with existing languages at the time."
Do you also like exploring new languages and algorithms to solve problems innovatively? Welcome to a brand new issue of ProgrammingPro!
News Highlights: A Microsoft MVP issues a bold warning against so called GitHub Copilot consultants, urging you to demand proof of knowledge before you engage them. Plus, dive into the need for urgent PLC security measures post a Texas ransomware attack, and GameMaker's game-changing move that is shaking up the competition!
And here are my top 5 picks from today’s learning resources:
Track Frontend JavaScript exceptions with Playwright fixtures🕵️♂️
Unleashing MariaDB's Power: Practical Coding with INSERT INTO... RETURNING💪
And, in today’s Expert Insight section, we have an exclusive excerpt from Infrastructure as Code for Beginners covering best practices and troubleshooting tips covering version control, documentation, modularity, CI/CD, security practices, and proactive measures to ensure robust, secure, and maintainable infrastructure development.
Stay awesome!
Divya Anne Selvaraj
Editor-in-Chief
PS: If you would like to request a tutorial for the next time, or give us any feedback, take the survey. If you are looking for Python resources, go to the latest issue of PythonPro
🗞️News, 💡Opinions, and 🔎Analysis
🗞️News
Good luck finding competent Copilot help, warns Microsoft MVP: Loryan Strant challenges claims of extensive Copilot usage citing its quite recent public release and the significant cost involved (a minimum purchase of 300 licenses totaling around $109k). Read to learn why you need to demand proof of knowledge and unique value from consultants before engaging them in today’s AI-driven landscape.
Iranian Cyber Threats and Texas Ransomware Attack on Water Infrastructure Demand Urgent PLC Security Measures: To secure Programmable Logic Controllers (PLCs), CISA recommends immediate changes to default passwords, disconnection from the public internet, and implementation of multi-factor authentication. Read for more insights into the attacks and PLC security practices.
GameMaker offers free version as ‘gift’ to developers: In a surprising move, the 2D game engine now offers free access for non-commercial projects, eliminating the $9.99 monthly subscription fee. Read to learn how this shift responds to discontent with competitors like Unity and Unreal Engine.
PHP 8.0 reaches EOL leaving some websites vulnerable: As of November 26, 2023, PHP 8.0 has reached its end of life, exposing 45.8% of users who still rely on this version to security risks and compatibility issues. Read to learn why it is crucial to upgrade to PHP 8.3 for enhanced security, performance, and more.
Upgrade your Java applications with Amazon Q Code Transformation (preview): This AI-powered solution simplifies the efficient upgrade of Java applications from version 8 and 11 to version 17, with internal testing showcasing significant time savings compared to manual upgrades. The preview version is available to Amazon CodeWhisperer Professional Tier customers.
💡Opinions and Analysis🔎
GitHub Copilot’s Security Filters Don’t Work: GitHub Copilot's touted LLM-based security scanning fails basic tests for detecting SQL injections, path injections, and hardcoded credentials. Read to learn why you should consider dedicated tools like SAST for comprehensive code vulnerability scanning.
C++ needs undefined behavior: This article explores the necessity of undefined behavior for performance optimization, debating its controversial aspects like signed integer overflow. Read to discover a middle ground called "erroneous behavior" for better language design and program behavior stability.
Integer overflow and arithmetic safety in C++: This article explores the persistent issue of integer overflow in C++ and its security implications, citing recent 0-day exploits in Chrome. Read to discover a solution using safe numeric types and gain insight into the ongoing conversation about enhancing C++ safety.
Keynote: Safety and Security: The Future of C and C++ - Robert Seacord. - NDC TechTown 2023: This talk by the new wg14 convener addresses concerns in the C++ community about the impact of organizations like the NSA and the delicate balance between language optimization and security. Watch to learn why he advocates for heightened awareness among programmers to navigate these critical issues.
The Unbearable Weight of Massive JavaScript | Ryan Townsend | performance.now() 2023: This talk highlights the disillusionment with JavaScript frameworks and Single Page Applications over the past decade, emphasizing challenges such as increased website weight, complex debugging, and ineffective shipping. Watch to learn how returning to building fast, maintainable, and user-friendly front-ends can enhance user experiences by simplifying web architecture.
Javascript — What’s new with ECMAScript® 2024 (ES15) — In Depth Guide:
This article delves into upcoming features, from well-formed Unicode strings to decorators and the Realms API. Read for a glimpse into JavaScript's future, promising improved efficiency, readability, and powerful paradigms for developers.
🎓 Tutorials and Guides🤓
Modern C++ Programming Course: This open-access course made up of 22 chapters covers C++11 to C++23. Read for real-world insights and code examples and if you are already familiar with C and object-oriented programming.
Generating C# bindings for native Windows libraries: This comprehensive guide uses Detours as an example and covers steps such as creating Windows metadata, building a wrapping DLL for the static library, and utilizing cswin32 for importing Win32 metadata. Read for practical implementation showcased through an example C# code.
The Advantage of Using Cache to Decouple the Frontend Code: This tutorial delves into optimizing frontend code focusing on a low TTL caching strategy at the infra layer to enhance performance and simplify code complexity. Read to learn how the strategy not only optimizes performance but also simplifies code complexity, promoting a clean architecture aligned with the repository pattern.
Demystifying Static Mocking With Mockito: Using a simple utility class, this tutorial demonstrates the MockedStatic object, guiding you to handle static method invocations in your tests. Read if you are dealing with static method challenges.
The Complete Guide to Cron Jobs: This guide explores the functionality of cron jobs in Unix-like systems, including how they operate, the syntax for scheduling, and common errors such as incorrect syntax and permissions issues. Read for practical examples which emphasize the importance of accurate setup to avoid pitfalls.
Track Frontend JavaScript exceptions with Playwright fixtures: This article explores using Playwright fixtures to automatically fail tests when Frontend JavaScript exceptions occur, providing a safety net for end-to-end testing and synthetic monitoring in JavaScript-heavy applications. Read to enhance your test coverage and identify potential production problems more efficiently.
How to test a Typescript app using vitest and msw: This guide starts with setting up handlers and testing server with msw, then explains how to install and configure vitest. Read to learn how mock HTTP requests, define mocks for environmental variables, and use handlers to intercept and mock responses.
Making Games in Go for Absolute Beginners: This guide utilizes the Ebitengine library to encourage you to explore game development in Go. Read for insights into infinite loops, image manipulation, collisions, UI, animations, and web deployment.
For Python tutorials and resources Go to PythonPro!
🔑 Secret Knowledge: Learning Resources🔬
Unleashing MariaDB's Power: Practical Coding with INSERT INTO... RETURNING: This article delves into the practical applications of MariaDB's "INSERT INTO... RETURNING" SQL statement, showcasing its coding versatility for real-time updates, personalized messages, and more. Read to access real-time solutions and enhance database proficiency.
RISC-V Vector Programming in C with Intrinsics: This article focuses on RVV intrinsics as a high-level alternative to assembly. Read for insights into one-to-one mappings, operand types, vector configurations, and the impact of vector length on instruction execution.
C++ Exceptions, Unwind Tables, and ‘relocation truncated to fit: R_ARM_PREL31’: This article explores the complexities and solutions associated with the error and connects it to C++ exceptions and the Unwind Table. Read if you are an embedded developer working with Cortex-M4 or newer parts and discover solutions ranging between linker manipulations to lying about the hardware memory map.
Web Components Eliminate JavaScript Framework Lock-in: This article explores the flexibility of Web Components in creating a todo app with React, Solid, Svelte, and Vue components coexisting seamlessly. Read for insights into encapsulation, shadow DOM, and shared stores, and to rethink the notion of sticking to a single JavaScript framework.
Explicit Resource Management: Exploring JavaScript's and TypeScript's new feature: This article delves into JavaScript and TypeScript's new explicit resource management feature, exploring its syntax and applications, covering event subscriptions, async file handling, mutexes, and task queues. Read for a practical implementation through a comprehensive example function, fetchCat().
Go Fact: Zero-sized Field at the Rear of a Struct Has Non-zero Size: Exploring the example of a UserName struct, the author explains the discrepancy in size, attributing it to a design choice aimed at preventing potential issues with the garbage collector. Read to discover a solution involving reordering the ZST field within the struct to ensure more efficient memory usage.
Guide to Optimizing PHP for High Traffic Sites: This comprehensive guide offers a decade's worth of insights on optimizing PHP for high-traffic websites, covering crucial topics like transitioning to PHP 8, OPcache utilization, PHP-FPM tuning, hardware considerations, memory management, monitoring, and security. Read if you are a PHP developers or Linux sysadmin seeking scalability and efficiency in high-traffic scenarios.
🧠 Expert Insight 📚
Here’s an exclusive excerpt from “Chapter 8, Common Troubleshooting Tips and Best Practices” in the book Infrastructure as Code for Beginners by Russ McKendrick.
Infrastructure as Code – best practices and troubleshooting
Let us start by discussing some general IaC best practices that can apply to various tools and platforms.
General IaC best practices
There are some common threads that we
have already touched upon here, but it is essential to bring them up again as they are important:
Version control: Make sure you use a version control system such as Git or one of the other available systems such as Mercurial, Subversion, or Azure DevOps Server, which was previously known as Team Foundation Server (TFS), to name a few of the more common ones, to store and manage your infrastructure code.
The odds of you, either personally or within the business, already using version control for your other projects is extremely high if you are taking steps to both define and deploy your infrastructure in and as code. This means that you have experience with version control and access to the tools, processes, and procedures to maintain code using version control.
Employing version control enables collaboration, change tracking, and easy rollback to previous versions if needed.
Documentation: You can approach documentation in several ways, and it doesn’t matter how you do it, just as long as you do it!
My personal approach to documenting my IaC deployments is to try and keep as much of the documentation within the code as possible using both in-comments and making sure that sections, tasks, functions, or variables are as clearly named and descriptive as possible while keeping within any of the constraints of the tool I am using.
Also, depending on the complexity, I will summarise what the code does, attach it as a README file, and commit it to version control.
The reason I do this is that while it is easy to keep track of what is going on while you are working on the project, when it comes to someone else picking it up – or even you revisiting it yourself after a few months of being away from the project – it can sometimes take them a little time to get their bearings.
Your approach may differ, which leads nicely into the next piece of best practice.
Code reviews: I recommend conducting regular code reviews to maintain code quality, ensure compliance with best practices, and share knowledge among team members.
You may already have processes to enforce this across other types of development within the business, such as your applications. It is just as crucial that the same principles govern your IaC projects as you may be asked to demonstrate that your code adheres to any guidelines that your application has to follow for compliance reasons. After all, your IaC project will be deploying and maintaining the resources your application will run upon.
Modularity: When you write your infrastructure code, do it in smaller, reusable modules. This promotes reusability, maintainability, and better organization of your code base. We covered this in Chapter 6, Building upon the Foundations.
Continuous Integration and Continuous Deployment (CI/CD): We discussed this at length in the previous chapter, Chapter 7, Leveraging CI/CD in the Cloud. Even for development purposes, if you have your code in source control, you should ideally be leveraging CI/CD.
Testing: In the perfect world, you should implement automated testing for your infrastructure code to validate its correctness, identify issues early, and increase its overall reliability. If you are using version control and CI/CD, you already have most of the tools to make this process easy. For example, in Chapter 7, Leveraging CI/CD in the Cloud, we had some break-points when running Terraform plan to catch potential issues.
Monitoring and logging: Implement monitoring and logging solutions to track executions and detect issues allowing you to troubleshoot problems promptly. In Chapter 7, Leveraging CI/CD in the Cloud, our CI/CD pipelines kept a log of everything that happened during the execution. In Terraform’s case, we generated and attached a snapshot of the plan file – this level of information can be very valuable when trying to figure out what would happen if something unexpected happened.
The principle of least privilege: Limit access to resources and creation by granting the minimum necessary permissions for your infrastructure code executions to interact with the components they are working with.
Depending on your target infrastructure, this may only sometimes be possible, but most cloud providers allow you to be very granular with the permissions. Also, depending on what you are deploying, this could take a little trial and error – but in the long run, it is worth investing the time in looking at it from a security point of view.
Immutable infrastructure: Rather than updating existing infrastructure, create new infrastructure to replace the old one and reroute requests to it. This reduces the risk of errors due to configuration drift and forces deployments to be more predictable.
This approach depends on your application, and it may only sometimes be practical for you to fully implement this approach. Still, the more your infrastructure components you can make immutable, the easier it will be for you to scale out and back down.
Secure by Design (SBD): As you write your infrastructure code, incorporate security best practices and tools from the beginning, such as encryption, identity management, and network segmentation if possible, and as already mentioned, focus on making these parts of your code as modular as possible so that you can easily reuse them across your projects.
Now that we have established some general best practices, let us move on and discuss some general troubleshooting tips.
General IaC troubleshooting tips
The following are some general troubleshooting tips, tricks, and approaches. As we are talking about general IaC tips, many of them are more preventive than tasks you would do to debug an issue:
Avoid hardcoding sensitive information: Use secret management tools such as Azure Key Vault, HashiCorp Vault, or AWS Secrets Manager to securely store and retrieve sensitive information at runtime or use your infrastructure code to configure your resources to use the secret management tools directly.
While it goes without saying that you shouldn’t hardcode sensitive information such as passwords, private information, or secrets directly within your code (Ansible could be an exception, but more on that in the Ansible – best practices and troubleshooting section), there are advantages to using secret management tools – the biggest one is for things such as certificate management.
Imagine it’s a day or two before your SSL certificate expires, and you are rushing to get all resources that reference it updated. Using your target platform’s secret store may mean that you only have to update the certificate; then all resources that use the certificate are automatically updated.
Keep dependencies up-to-date: Throughout Chapter 4, Deploying to Microsoft Azure, and Chapter 5, Deploying to Amazon Web Services, you will have noticed that our infrastructure code utilized a lot of different tasks and modules.
Regularly updating your dependencies will help you avoid security vulnerabilities and compatibility issues. As your target cloud APIs are updated, you may find that your code has issues or no longer works.
Don’t overcomplicate your infrastructure code: Keep your infrastructure code as simple as possible and avoid unnecessary complexity that may be difficult to maintain and troubleshoot should there be issues.
It may look “cool” to build lots of logic or loops into your IaC. Still, it only takes a slight change as part of a tool or dependency update for it to come tumbling down – the more effort and time needed to code something, the more effort you are likely to put into debugging and refactoring it if and when there are problems.
Trust me, from experience, your future self will thank you for this.
Maintain a clean, well-organized code base: Consistently use naming conventions, follow a directory structure, and remove obsolete code.
Anyone within your team needs to be able to pick up your code and know what is going on without having seen it; you will not always be the only one who looks into any problems with your code.
You want to avoid creating more work for whoever picks it up, as they will likely already be under pressure because someone has reported a problem.
Don’t ignore error or warning messages: Address any messages, especially non-breaking warning messages in your infrastructure code, promptly to prevent future issues.
Most tools will stop execution when there are errors. However, most will also print warnings – these could be just be small things such as letting you know that functionality you are using will be deprecated or changed in future releases, and warnings will not stop execution. Still, they need to be addressed just like any errors you receive; it isn’t every day you get the chance to avoid future errors, so take it.
Finally, and this goes without saying, communicate with your team. Regularly communicate with your team about infrastructure changes, potential issues, and best practices to ensure everyone is on the same page when it comes to your IaC. You do not want to be a single point of failure, nor do you want to set your team up for failure should there be any problems.
Infrastructure as Code for Beginners by Russ McKendrick was published in May 2023. You can read chapter 1 for free and buy the book here.
🛠️ Useful Tools ⚒️
crouton: a C++20 coroutine runtime library, utilizing async/await concurrency, cross-platform support, and asynchronous I/O, providing developers with a safe and efficient alternative to traditional multithreading for Mac, Linux, Windows, and ESP32 microcontrollers.
Peggy: a parser generator for JavaScript, offering a straightforward grammar syntax, integrated lexical and syntactical analysis, superior error reporting, and compatibility for processing intricate data or programming languages, enabling the creation of transformers, interpreters, compilers, and other tools with ease.
htmx-go: a type-safe Go library which elevates Hypermedia-driven app development by simplifying HTMX handling, offering declarative response headers, and enabling precise control over Swap Strategy methods.
Luos: an open-source library for developing scalable edge and embedded software, offering a portable package creation, remote control, multi-SDK monitoring, and reusable services to expedite product development and ensure application robustness.
ollama: a lightweight, extensible framework for building and running language models locally, offering a variety of open-source models, customizable prompts, and integrations with Discord, mobile platforms, and various programming languages.
We have an entire range of newsletters with focused content for tech pros. Subscribe to the ones you find the most useful here. Complete ProgrammingPro archives can be found here. Complete PythonPro archives are here.
📢 If your company is interested in reaching an audience of developers, software engineers, and tech decision makers, you may want to advertise with us.
If you have any comments or feedback, take the survey or leave your thoughts below!