Four Ways to Set Up Developer Self-service in Your Internal Developer Portal

March 22, 2023

Ready to start?

Four Ways to Set Up Developer Self-service in Your Internal Developer Portal

Introduction

Developer self-service actions are what internal developer portals are made for. Through the developer portal, developers can access a product-like user interface that lets them consume software and infrastructure with guardrails and abstractions in place. There is no need for developers to send tickets or deal with complex operations setups.

With Port, developers can provision, terminate and perform day-2 operations on any asset exposed in port’s software catalog. They can provision a development env, request permission for a S3 bucket for limited time or add a secret to a microservice. 

 In general, Port supports three broad types of developer self-service actions:

  • Create - by triggering a provisioning process in your infrastructure, creating a new software catalog entity
  • Day two operations - updating or modifying an existing software catalog entity
  • Delete - triggering delete logic 

How are self-service actions set up?

At the core of Port is the loose coupling of the internal developer portal to the underlying infrastructure. Our belief is that platform engineering is about the creation of reusable elements that enable self-service, and those elements are created with existing tools - from Terraform, through Jenkins, GitHub Workflows and more. The platform team should have the freedom to change platform tooling and configuration, without creating developer confusion, cognitive load or dealing with a need to drive adoption of new tools. As a result, developer self-service actions are set up in the developer portal with a user interface. Once a developer executes an action in the portal, it can be enabled in 4 ways.

4 ways to enable developer self-service actions

Developer self-service actions are defined in the blueprints within the portal. Blueprints are the basic building block in Port and cover all entity types. For instance, in a cloud resource blueprint we can define a self-service action to allow the creation or deletion of such a cloud resource.

When we execute a self-service action, we have 4 options:

1. Webhook: Port triggers webhooks based on a customer provided URL.

In this case, an example flow can be: 

  1. A developer self-service action is made: create an ephemeral dev environment with a TTL of 5 days
  2. The create action is sent to the defined URL;
  3. For example, An AWS Lambda function is triggered;
  4. The Lambda function deploys a new ephemeral dev environment;
  5. When the Lambda is done, it reports back to Port (by sending a REST API request) and the new environment is reflected in the software catalog. The developer gets a message about the success of the action. 
  6. Once the TTL is over, workflow automations remove the ephemeral environment.

You can read more about self-service actions with webhooks here.

2. Kafka self-service actions

Port manages a secure Kafka Topic per customer that publishes the execution run requests. This means that Port doesn’t store any environment credentials and there is no need to open a connection for Port.

You can listen to a Kafka Topic with any code platform you wish to use, and also use it as a trigger for example a serverless function. For example, AWS Lambda. See here.

In this case, an example flow would be:

  1. A developer asks to deploy a new developer environment with a TTL of 5 days;
  2. The create action is sent to the Kafka topic; 
  3. For example, an AWS Lambda function is triggered by this new action message; 
  4. The Lambda function deploys a new developer environment;
  5. When the Lambda is done, it reports back to Port.
  6. When the Lambda is done, it reports back to Port (by sending a REST API request) and the new developer environment is reflected in the software catalog. The developer gets a message about the success of the action. 
  7. Once the TTL is over, workflow automations remove the ephemeral environment.

3. Webhook with Port Execution Agent

This option exists as a secure and convenient way to listen and act when Self-Service actions are invoked or in case of changes to the software catalog. In this case the invocation agent pulls the new invocation event from a secure and dedicated Kafka topic. Just as before, this means that no credentials are stored and no connection needs to be open for Port.

4. Github workflow: GitHub Workflow Self-Service Actions

Port’s GitHub application can trigger a GitHub workflow to invoke the required self-service action.

In this case, an example flow can be:

  1. A developer asks to deploy a new version of an existing microservice;
  2. A message with the developer inputs is sent to the dedicated Kafka topic
  3. Port's GitHub application event handler is triggered by this new action message;
  4. Port's GitHub application triggers the GitHub workflow that deploys a new version of the service;
  5. As part of the workflow, the new microservice Deployment is reported back to Port;
  6. When the workflow is done, Port's GitHub application reports back to Port about the status of the action run, according to workflow's conclusion.

Combine GitOps Operations with Port’s self-service cations

In this case, it is possible to have developers execute self-service actions which are then performed with GitOps. The flow works like this:

  1. Users make a self-service action which is then stored in a Kafka queue. 
  2. Port’s Github app listens to the form submissions and handles Terraform file generation.
  3. When the Terraform file is ready it will be committed, resulting in a pull request. 
  4. When the pull request is merged, the GitOps workflow triggers the CI that drives Terraform apply. This also ensures that the software catalog is updated with the specific IaC action (here’s a link to the Terraform provider), either apply or destroy. 

The above can also be done with Pulumi and GitLab CI, for example.

{{cta_8}}

Conclusion

The point of Internal Developer Portals is that they are loosely coupled with the underlying platform and that they are both flexible yet allow for an accurate reflection of all things software and infrastructure in the software catalog. To support this loose coupling, Port supports many variations of implementing developer self service actions, including allowing for self-service RBAC, TTL and manual approvals.  We’re working on the ability to trigger more pipelines directly, such as Jenkins and GitLab CI. Would you like to add integrations to Port? Send us a message at info@getport.io

{{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

{{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

{{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