X as a Code — close your engineering strategy gaps today

Lesia Topol
7 min readSep 2, 2023

Autonomous software development sounds so futuristic and distant in future. Or could it be attributed to a lack of assessment of the current state? Have you ever explored what steps you can take today to initiate the transition of your engineering strategy towards a new phase characterized by autonomous approaches? If not, this article is here to guide you on where to commence and what actions you can take today as a proactive engineering leader to bridge the gaps.

Autonomous software development is lead by human, executed by code. So as you see two main personas — “Human” and “Code”. “Human” involvement will remain crucial to provide real-world inputs, maintain user centric aspects, address edge cases and unpredictable scenarios, apply domain expertise, control reliability of AI training data and continue to innovate. And the first transition step is to make “Human” input machine readable — e.g. Coded. And this contributes to intermediate state automation. Tech word evolves and new and new tools are proposed to use AI and Machine Learning features. And you as a tech team leader should provide a guidance on a path of “Evolution now” rather then “Revolution later”.

Let’s look a simple Engineering strategy:

Engineering high level strategy

The majority of project delivery strategies will typically suggest prioritizing the automation of both backend and frontend layers. And yet it’s just a drop is the ocean of opportunities available for approaching your delivery model in a modern and innovative manner:

Transition from current to desired state

The initial question you might ponder is, “Where should I begin?”. My suggestion is to consider taking an iterative approach since there are numerous aspects to address:

Strategy improvement model
  • Start with assessment what is the current team approach, what are the challenges. Discuss and set the goals, identify the desire improvement in speed, quality, and reliability.
  • Culture and mindset is one of the crucial aspect to focus — foster a culture of automation and collaboration across team members, help team to understand how it will change day to day operations.
  • Identify automation opportunities and priority to address, choose areas that produce immediate impact, make sure tools are enabled to achieve the goals.
  • Collect metrics that indicate what went well and what still needs an improvement, iterate on the automation strategy.

In the present market, a variety of tools are available to help you attain your desired state — maximum conversion to “Code”. Below I provided an examples of open-source solutions designed to address the problem statement and suggested subject matter experts who can code. However please keep in mind this is not an exhaustive list of options. If below tools do not exactly align with your project needs please explore and utilize any other that are better fit. The following list comprehensively covers every aspect of the engineering strategy for enabling “X as a Code”:

“Requirements as Code” (RaC) refers to the practice of managing project requirements using code and automation tools. This approach helps maintain consistency, version control, collaboration, and traceability in requirements management. Equip your Product Owner or Business Analyst to stay one step ahead and include requirements in the code repository (e.g., by documenting them in GIT) as follows:

@REQ_ID_01 @Business_rule_005
Feature: Default Translate functionality

Scenario Outline: Support translate text from English to Spanish by default
Given the User enters English text "<EnglishText>"
When the User clicks translate
Then Spanish text is displayed to the User "<SpanishText>"
Examples:
|EnglishText|SpanishText|
|Hello |Hola |
|Bye |Adiós |

Please refer to “Cucumber” documentation as an example of BDD approach.

“Compliance as Code” (CaC) is a concept that involves using code and automation to ensure that an organization’s systems, applications, and processes adhere to regulatory and security compliance standards. This approach combines the principles of DevSecOps, where code is treated as infrastructure, with the requirements of compliance. Here’s an example policy that forbids pods with a specific label named unauthorized using “Open Policy Agent”:

package k8s.pod_policy

violation[msg] {
input.review.object.kind == "Pod"
input.review.object.metadata.labels["unauthorized"]
msg = "Pods with 'unauthorized' label are not allowed"
}

“Configuration as Code” (CaC) is an approach where configuration settings for various software, services, and systems are managed and maintained using code and version control systems. This approach treats configuration settings just like code, enabling automation, versioning, consistency, and collaboration. This can be covered by DevOps experts involved into project. Here is an example of Ansible code how to describe web server configuration:

  name: Configure Web Server
hosts: web_servers
become: yes # This indicates that we need sudo (root) privileges to execute the tasks

tasks:
- name: Update package cache
apt:
update_cache: yes
when: ansible_os_family == 'Debian'

- name: Install Nginx
apt:
name: nginx
state: present
when: ansible_os_family == 'Debian'

- name: Ensure Nginx service is started and enabled
systemd:
name: nginx
state: started
enabled: yes

- name: Create a basic HTML file
template:
src: /path/to/index.html.j2
dest: /var/www/html/index.html
notify: Restart Nginx

handlers:
- name: Restart Nginx
service:
name: nginx
state: restarted

“Infrastructure as Code” (IaC) is a approach for managing and provisioning computing infrastructure components as code (e.g., servers, networks, databases etc.), enabling them to be versioned, tested, and managed like software applications. Such code can be executed in automated way. IaC is a fundamental concept in modern DevOps practices and cloud computing. Here some example of “Terraform” code:

# Specify the provider (in this case, AWS)
provider "aws" {
region = "us-east-1" # Choose your desired AWS region
}

# Define the AWS EC2 instance resource
resource "aws_instance" "example_instance" {
ami = "ami-0c55b159cbfafe1f0" # Amazon Linux 2 AMI ID (replace with your desired AMI)
instance_type = "t2.micro" # EC2 instance type (choose according to your needs)

tags = {
Name = "ExampleInstance" # Tags for identifying the instance
}
}

“Backend layer automation” typically refers to automating the functional and non-functional aspects of application requirements (API, databases, queues, storage, cloud services etc.) and other infrastructure components. This automation aims to improve efficiency, reduce manual intervention, and enhance the reliability of backend systems and services. You can find numerous solutions, tools and approaches as backend automation is the most popular as it’s easy to maintain, fast in execution and cost effective. Development team very often uses Test Driven Development to cover the scope, Quality Engineers apply various techniques including BDD to cover application functional aspects. Below is just an basic example of RestAssured how to cover basic API validation:

@Test
public void testGetUser() {
// Define the base URL for the API
RestAssured.baseURI = "https://reqres.in/api";

// Perform a GET request to retrieve user data (user with id 1)
given()
.when()
.get("/users/1")
.then()
.statusCode(200) // Check if the response status code is 200 (OK)
.body("data.id", equalTo(1)) // Check if the 'id' field in the response body is 1
.body("data.first_name", equalTo("George")); // Check if the 'first_name' field is "George"
}

“Frontend layer automation” refers to the practice of automating tasks and processes related to the development and testing of the user interface (UI) or frontend of a software application. This automation can involve automating UI testing, building and bundling frontend assets, and streamlining the development workflow. Again this is popular and commonly used approach, many and may solutions exists. Just for an idea here is example of Cypress code:

describe('E-commerce Website Tests', () => {
beforeEach(() => {
// Visit the website URL before each test
cy.visit('https://example-ecommerce-website.com'); // Replace with your website URL
});

it('should navigate to a product page and add an item to the cart', () => {
// Find and click on a product link
cy.contains('Product Name').click();

// Make assertions on the product page
cy.url().should('include', '/product/');
cy.get('.product-title').should('contain', 'Product Name');

// Add the product to the cart
cy.get('.add-to-cart-button').click();

// Verify that the cart icon shows the item count
cy.get('.cart-icon').should('contain', '1');
});
});

“Security as Code” (SaC) is an approach that integrates security practices and controls into the software development and deployment process by treating security policies, configurations, and best practices as code. This approach aims to automate security processes, making them more efficient, consistent, and adaptable. For example you can integrate Veracode scans into your CI/CD pipeline. Below is a simplified example using a popular CI/CD tool, Jenkins:

pipeline {
agent any

stages {
stage('Build') {
steps {
// Your build steps here
}
}

stage('Static Analysis') {
steps {
script {
// Run Veracode static analysis
sh 'veracode-scanner --scan-type static'
}
}
}

stage('Dynamic Analysis') {
steps {
script {
// Run Veracode dynamic analysis
sh 'veracode-scanner --scan-type dynamic'
}
}
}

stage('Deploy') {
steps {
// Deploy your application
}
}
}
}

The current variety of tools provides the capability for any project to encapsulate all aspects as code. Once coded, these aspects should be integrated into the CI/CD pipeline to not only execute the code but also generate test reports and deliver feedback on overall quality. Maximizing your engineering team’s code delivery plays a significant role in harnessing AI and ML across various domains. Embrace this readiness today to ensure a smooth transition into more efficient and automated development practices, setting the stage for the future. Autonomous software development is an evolving field that aims to streamline and enhance software development processes by reducing manual intervention, improving reliability, and increasing agility. While complete autonomy may not be achievable today in all scenarios, these practices and technologies can significantly advance the automation and efficiency of software development and operations for future needs.

--

--

Lesia Topol

When your work becomes your passion, it's time to share it with others. This blog is about reawakening job satisfaction.