How AMCS Group embraced platform engineering with Port

March 7, 2024

How AMCS Group embraced platform engineering with Port

Ready to start?

AMCS Group has improved visibility and eliminated repetitive tasks using self-service actions using an internal developer portal

Summary

As AMCS Group has expanded, the Ops team was challenged with the amount of tickets it received and was unable to focus on other core activities. To combat this, the team split its Ops teams into SRE and platform engineering teams. To achieve its goals of improving visibility with a software catalog and eliminating repetitive tasks by using self-service actions, the organization used Port’s internal developer portal - and the company is already reaping the rewards.

Background

AMCS Group provides expert business management software for the resources, waste, recycling, transportation and utilities industries in more than 80 countries. Its aim is to help its 4,900 clients to increase customer satisfaction, enhance sustainability and boost margins. 

To deliver on behalf of its clients, the company embarked on a DevOps journey, beginning with the setup of a global DevOps team in 2017 and the adoption of Git, CI/CD, IaC, Azure and Azure DevOps. A member of this centrally positioned team, Pavel Pikat, Technical Product Owner at AMCS Group, explained its functions:

“It was a traditional Ops team, where AMCS internal development teams would come to us with a solution they’ve developed asking for it to be deployed into the cloud. The challenge was the company increased from 200 people to 1000 employees as the business grew rapidly, and despite having more services, developers and teams, it was difficult to scale the Ops team together with the rest of the organization” he said.

“We were challenged with the amount of tickets to do small repetitive tasks, raised by our professional services, product and development teams. It got to a point where we had to explain that if someone wanted their service deployed they had to wait in a queue,” he said.  

In fact, this workload impacted on Pikat’s team’s ability to focus on other core activities such as improving processes, quality and standards and implementing new features like a new monitoring stack and driving Kubernetes adoption.

At this stage Pikat realized that something had to change, whether it was the makeup of the team or the way the team worked. 

"Many organizations moved away from traditional Ops teams and adopted DevOps culture. However, the challenge with DevOps teams is the amount of responsibility placed on them. It’s telling developers to go and manage cloud infrastructure, monitor or manage security, and do a lot of the things that create a lot of complexity and cognitive load. And it’s even worse if you have multiple teams in the company who all do things in a different way: different infrastructures, code approaches, naming conventions, security templates - it’s going to be a significant challenge," he said.

Embracing Platform Engineering

It was at this point that Pikat did some research into new approaches for software development and discovered the concept of Platform Engineering. The idea of improving developer experience by using self-service actions was key in persuading Pikat to adopt this approach at AMCS. 

“We wanted to do self-service but not the one where we would give permissions to everyone and they would do their own thing. Instead, we wanted to define templates and standards and offer some abstractions,” he said.

Rather than giving developers direct access to the Azure API, Pikat wanted a way to abstract complexity while adhering to AMCS’s naming conventions, best practice and compliance requirements. Then, his team would provide the developers with guidance on how to perform the action. 

It became clear that to achieve this, AMCS required a dedicated Platform Engineering team and a separate SRE team with different backlogs and processes than they had previously. Therefore, AMCS established a product-oriented Platform Engineering team with its own backlog and roadmap, working within two week iterations. It would incorporate one product owner (Pikat) and four engineers, all of whom are highly skilled with a development background. The team is responsible for enabling developers to build, test, deploy and run their applications in the cloud.

Meanwhile, the separate SRE team has its own TicketOps backlog, and is made up of 15 members with support, DBA and development backgrounds. The team is responsible for production SLA, on-call, monitoring, customer deployments and upgrades. 

In the short-term, the Platform Engineering team wanted to reduce its load by eliminating repetitive tickets coming from development teams with action items such as creating a new git repo, granting temporary access to a development environment, or adding a CI/CD pipeline to a service. 

In addition, Pikat wanted to provide visibility of deployed services, environments, and versions in an automated fashion, and use a software catalog that provides visibility of Git repositories, services, environments and ownership.

It became clear to Pikat that to achieve these goals, AMCS would require an Internal Developer Portal, which would enable developer self-sufficiency through the use of self-service actions with baked-in guardrails. At the same time, the portal would provide an abstraction of AMCS’s software and infrastructure, reducing their cognitive load and enabling them to make sense of anything in the stack and the resulting interdependencies. After a number of proof-of-concepts, AMCS selected Port. 

When asked why Port, Pikat responded: “The concept of Port to build your own data model where it’s highly customizable, where you can define and model your organization as you see fit, was crucial in our decision. It’s not an opinionated way of doing it, there are no limitations,” said Pikat. 

“UX and UI were a big part of the decision too - it felt and looked nice and modern” he added.

Starting with Self-Service Actions

Repetitive Tasks

The priority for AMCS was to implement self-service actions to reduce tickets so that the Platform Engineering team could focus on its own core tasks. AMCS had already been tracking its tickets with a service delivery manager reporting on delivery time, volume of tickets, requesters and the impact of a ticket. The company found the most repetitive and easy-to-automate tickets and focused on creating self-service actions for these. 

Port enabled Pikat and his team to completely customize the self-service form depending on the abstractions the developers needed. The team has since created self-service actions for the following:

  • Whitelist IP
  • Refresh database
  • Create new Git repository
  • Implement CI/CD pipelines
  • Create temporary SQL user for debugging development environment

Pikat believes every action executed in Port is a ticket reduced; he said in one week the team saw 100 actions executed, with this likely to grow.

Self-Service Scaffolding

After focusing on the ‘low hanging fruit’ available for self-service, the Platform Engineering team have now focused their attention on self-service scaffolding. This would allow developers to scaffold new services easily, without having to raise any tickets, or wait for other teams to create CI/CD pipelines and Terraform configurations for them. 

“Today, whenever developers create new services, they come to us asking for a CI/CD pipeline to build and deploy their app. We have it largely automated with Terraform and pipeline templates, but it still requires a human touch to glue different pieces together every time. It would be great to have it all wrapped up in a nice package that developers can consume without being experts.” said Pikat. This is the next area of focus for AMCS. 

Shifting to Kubernetes

AMCS is actively investing in building its next-generation cloud architecture based on Kubernetes, but Pikat said that very few engineers are Kubernetes experts, and this is why AMCS is planning to use Port and Platform Engineering to abstract it away and offer it as a service.

“This approach allows us to standardize and streamline how development teams onboard Kubernetes. We aim to offer them a golden path that makes the transition to containers secure and swift, all while minimizing cognitive load” he said. 

Encouraging Adoption

To really benefit from Platform Engineering, organizations require buy-in from the developers themselves. Pikat and his team are conscious of this, and have made efforts to ensure developers are aware of Port’s functionality and benefits. They are pursuing a product-as-portal approach.

Whenever a developer opens a ticket about an action that can be created in Port, they’re directed to Port straight away. This initially enabled the organization to get 100 out of 300 users signed up to Port without any official launch or communication.

The team built a website dedicated to Port, with instructions and best practices for developers, while AMCS has both engineers and developers that are champions of Port. These are advanced users who are also active in Port’s product community. 

Today, AMCS has over 700 internal users in Port, and the Platform Engineering team is actively working on popularizing the platform through monthly product updates and webinars.

Future Plans 

The team plans on populating its software catalog in Port and creating more self-service actions. Thereafter, they plan on adopting Port as the tool for driving standardization and compliance, using portal scorecards as the tool to realize this. 

“One of our challenges revolves around improving communication between developers who have finished a service and are eager to deploy it, and the SRE team responsible for managing production,” he said.

By implementing a scorecard, both developers and the SRE team can assess whether the service meets the criteria for code quality and production readiness.

In the long-term, the Platform Engineering team intends on building an AMCS Dev Platform, which Pikat says is a unified solution with central services supporting software development lifecycle, with Port playing a big part in abstracting away complexity.

The platform would incorporate extensive and user-friendly documentation and onboarding so that users know where to go and who to ask to perform any action, for example an end-to-end journey for starting a new service and deploying it into production.

The platform would help drive standardization by providing templates with key features such as pipelines, observability and security baked in. This would also help to drive Kubernetes adoption.

Pikat hopes the team will benefit from improved lead time for developers to get their services from idea to production, without the need to raise tickets. In addition, he hopes it will make developers more responsible for CI, allowing them to create new pipelines to build their code while keeping deployment, cloud infrastructure and security hidden and abstracted away. Port will help ensure that the AMCS Dev Platform can provide the benefits that it is designed to enable.

Next Steps

Want to read more about organizations using an Internal Developer Portal to achieve their platform engineering goals?

Find out how CCO used Port to reduce developer platform complexity and enable standardization here, and how TransferGo is revolutionizing developer experience with Port, here.

{{cta_1}}

Check out Port's pre-populated demo and see what it's all about.

Check live demo

No email required

{{cta_2}}

Contact sales for a technical product walkthrough

Let’s start
{{cta_3}}

Open a free Port account. No credit card required

Let’s start
{{cta_4}}

Watch Port live coding videos - setting up an internal developer portal & platform

Let’s start
{{cta_5}}

Check out Port's pre-populated demo and see what it's all about.

(no email required)

Let’s start
{{cta_6}}

Contact sales for a technical product walkthrough

Let’s start
{{cta_7}}

Open a free Port account. No credit card required

Let’s start
{{cta_8}}

Watch Port live coding videos - setting up an internal developer portal & platform

Let’s start
{{cta-demo}}
{{reading-box-backstage-vs-port}}

Example JSON block

{
  "foo": "bar"
}

Order Domain

{
  "properties": {},
  "relations": {},
  "title": "Orders",
  "identifier": "Orders"
}

Cart System

{
  "properties": {},
  "relations": {
    "domain": "Orders"
  },
  "identifier": "Cart",
  "title": "Cart"
}

Products System

{
  "properties": {},
  "relations": {
    "domain": "Orders"
  },
  "identifier": "Products",
  "title": "Products"
}

Cart Resource

{
  "properties": {
    "type": "postgress"
  },
  "relations": {},
  "icon": "GPU",
  "title": "Cart SQL database",
  "identifier": "cart-sql-sb"
}

Cart API

{
 "identifier": "CartAPI",
 "title": "Cart API",
 "blueprint": "API",
 "properties": {
   "type": "Open API"
 },
 "relations": {
   "provider": "CartService"
 },
 "icon": "Link"
}

Core Kafka Library

{
  "properties": {
    "type": "library"
  },
  "relations": {
    "system": "Cart"
  },
  "title": "Core Kafka Library",
  "identifier": "CoreKafkaLibrary"
}

Core Payment Library

{
  "properties": {
    "type": "library"
  },
  "relations": {
    "system": "Cart"
  },
  "title": "Core Payment Library",
  "identifier": "CorePaymentLibrary"
}

Cart Service JSON

{
 "identifier": "CartService",
 "title": "Cart Service",
 "blueprint": "Component",
 "properties": {
   "type": "service"
 },
 "relations": {
   "system": "Cart",
   "resources": [
     "cart-sql-sb"
   ],
   "consumesApi": [],
   "components": [
     "CorePaymentLibrary",
     "CoreKafkaLibrary"
   ]
 },
 "icon": "Cloud"
}

Products Service JSON

{
  "identifier": "ProductsService",
  "title": "Products Service",
  "blueprint": "Component",
  "properties": {
    "type": "service"
  },
  "relations": {
    "system": "Products",
    "consumesApi": [
      "CartAPI"
    ],
    "components": []
  }
}

Component Blueprint

{
 "identifier": "Component",
 "title": "Component",
 "icon": "Cloud",
 "schema": {
   "properties": {
     "type": {
       "enum": [
         "service",
         "library"
       ],
       "icon": "Docs",
       "type": "string",
       "enumColors": {
         "service": "blue",
         "library": "green"
       }
     }
   },
   "required": []
 },
 "mirrorProperties": {},
 "formulaProperties": {},
 "calculationProperties": {},
 "relations": {
   "system": {
     "target": "System",
     "required": false,
     "many": false
   },
   "resources": {
     "target": "Resource",
     "required": false,
     "many": true
   },
   "consumesApi": {
     "target": "API",
     "required": false,
     "many": true
   },
   "components": {
     "target": "Component",
     "required": false,
     "many": true
   },
   "providesApi": {
     "target": "API",
     "required": false,
     "many": false
   }
 }
}

Resource Blueprint

{
 “identifier”: “Resource”,
 “title”: “Resource”,
 “icon”: “DevopsTool”,
 “schema”: {
   “properties”: {
     “type”: {
       “enum”: [
         “postgress”,
         “kafka-topic”,
         “rabbit-queue”,
         “s3-bucket”
       ],
       “icon”: “Docs”,
       “type”: “string”
     }
   },
   “required”: []
 },
 “mirrorProperties”: {},
 “formulaProperties”: {},
 “calculationProperties”: {},
 “relations”: {}
}

API Blueprint

{
 "identifier": "API",
 "title": "API",
 "icon": "Link",
 "schema": {
   "properties": {
     "type": {
       "type": "string",
       "enum": [
         "Open API",
         "grpc"
       ]
     }
   },
   "required": []
 },
 "mirrorProperties": {},
 "formulaProperties": {},
 "calculationProperties": {},
 "relations": {
   "provider": {
     "target": "Component",
     "required": true,
     "many": false
   }
 }
}

Domain Blueprint

{
 "identifier": "Domain",
 "title": "Domain",
 "icon": "Server",
 "schema": {
   "properties": {},
   "required": []
 },
 "mirrorProperties": {},
 "formulaProperties": {},
 "calculationProperties": {},
 "relations": {}
}

System Blueprint

{
 "identifier": "System",
 "title": "System",
 "icon": "DevopsTool",
 "schema": {
   "properties": {},
   "required": []
 },
 "mirrorProperties": {},
 "formulaProperties": {},
 "calculationProperties": {},
 "relations": {
   "domain": {
     "target": "Domain",
     "required": true,
     "many": false
   }
 }
}
{{tabel-1}}

Microservices SDLC

  • Scaffold a new microservice

  • Deploy (canary or blue-green)

  • Feature flagging

  • Revert

  • Lock deployments

  • Add Secret

  • Force merge pull request (skip tests on crises)

  • Add environment variable to service

  • Add IaC to the service

  • Upgrade package version

Development environments

  • Spin up a developer environment for 5 days

  • ETL mock data to environment

  • Invite developer to the environment

  • Extend TTL by 3 days

Cloud resources

  • Provision a cloud resource

  • Modify a cloud resource

  • Get permissions to access cloud resource

SRE actions

  • Update pod count

  • Update auto-scaling group

  • Execute incident response runbook automation

Data Engineering

  • Add / Remove / Update Column to table

  • Run Airflow DAG

  • Duplicate table

Backoffice

  • Change customer configuration

  • Update customer software version

  • Upgrade - Downgrade plan tier

  • Create - Delete customer

Machine learning actions

  • Train model

  • Pre-process dataset

  • Deploy

  • A/B testing traffic route

  • Revert

  • Spin up remote Jupyter notebook

{{tabel-2}}

Engineering tools

  • Observability

  • Tasks management

  • CI/CD

  • On-Call management

  • Troubleshooting tools

  • DevSecOps

  • Runbooks

Infrastructure

  • Cloud Resources

  • K8S

  • Containers & Serverless

  • IaC

  • Databases

  • Environments

  • Regions

Software and more

  • Microservices

  • Docker Images

  • Docs

  • APIs

  • 3rd parties

  • Runbooks

  • Cron jobs

Starting with Port is simple, fast and free.

Let’s start