GitOps
Port's GitHub integration makes it possible to manage Port entities with a GitOps approach, making your code repositories the source of truth for the various infrastructure assets you want to manage.
Some common use cases include:
- Use GitHub as the source-of-truth for your microservices, packages, libraries and other software catalog assets.
- Allow developers to keep the catalog up-to-date, by making updates to files in their Git repositories.
- Create a standardized way to document software catalog assets in your organization.
Port offers two ways to manage entities using GitOps:
- Using a dedicated
port.yml
file in your repository. - Using the GitHub integration mapping in your portal.
Option 1: Use a port.yml
fileโ
This approach requires adding a port.yml
file to the default branch (usually main
) of your repository.
Note that the port.yml
file is not the same as the port-app-config.yml
file used to configure the GitHub integration, and does not replace it.
The port.yml
file can specify one or more Port entities that will be ingested to Port, and any change made to the port.yml
file will also be reflected inside Port.
To manage entities using GitOps and the port.yml
file, Port's Github app must be installed, as it listens to push
events sent from Github.
This means that if the port.yml
file exists in the repository before installing the app, it will not be picked up automatically. You will need to make some update to the port.yml
file and push it to the repository in order for the Git app to properly track and ingest the entity information.
The port.yml
file is how you specify your Port entities that are managed using GitOps and whose data is ingested from your Git repositories.
Here are examples for valid port.yml
files:
- Single entity
- Multiple entities
identifier: myEntity
title: My Entity
blueprint: myBlueprint
properties:
myStringProp: myValue
myNumberProp: 5
myUrlProp: https://example.com
relations:
mySingleRelation: myTargetEntity
myManyRelation:
- myTargetEntity1
- myTargetEntity2
- identifier: myEntity1
title: My Entity1
blueprint: myFirstBlueprint
properties:
myStringProp: myValue
myNumberProp: 5
myUrlProp: https://example.com
relations:
mySingleRelation: myTargetEntity
myManyRelation:
- myTargetEntity1
- myTargetEntity2
- identifier: myEntity
title: My Entity2
blueprint: mySecondBlueprint
properties:
myStringProp: myValue
myNumberProp: 5
myUrlProp: https://example.com
Since both of the valid port.yml
formats follow the same structure, the following section will explain the format based on the single entity example.
port.yml
structureโ
Here is an example port.yml
file:
identifier: myEntity
title: My Entity
blueprint: myBlueprint
properties:
myStringProp: myValue
myNumberProp: 5
myUrlProp: https://example.com
relations:
mySingleRelation: myTargetEntity
myManyRelation:
- myTargetEntity1
- myTargetEntity2
-
The
identifier
key is used to specify the identifier of the entity that the app will create and keep up-to-date when changes occur:identifier: myEntity
title: My Entity
... -
The
title
key is used to specify the title of the entity:identifier: myEntity
title: My Entity
... -
The
blueprint
key is used to specify the identifier of the blueprint to create this entity from:...
title: My Entity
blueprint: myBlueprint
... -
The
properties
key is used to map the values to the different properties of the entity:...
title: My Entity
blueprint: myBlueprint
properties:
myStringProp: myValue
myNumberProp: 5
myUrlProp: https://example.com
... -
The
relations
key is used to map target entities to the different relations of the entity:- Single relation
- Many relation
...
properties:
myStringProp: myValue
myNumberProp: 5
myUrlProp: https://example.com
relations:
mySingleRelation: myTargetEntity...
properties:
myStringProp: myValue
myNumberProp: 5
myUrlProp: https://example.com
relations:
myManyRelation:
- myTargetEntity1
- myTargetEntity2
Setting null propertiesโ
When you want to clear a property's value in Port, you can explicitly set it to null
in your port.yml
file.
For example:
identifier: myEntity
title: My Entity
blueprint: myBlueprint
properties:
description: null
owner: null
When you omit a property entirely from the port.yml
, Port will keep its existing value. Setting a property to null
explicitly tells Port to clear that property's value.
Ingesting repository file contentsโ
It is possible to use the contents of files in the repository as the value for entity properties using a simple reference.
The following example will read the string contents of ~/module1/README.md
and upload it to myStringProp
of the specified entity.
Repository folder structure used for the example:
root
|
+- port.yml
|
+-+ module1
| |
| +- README.md
| |
| +-+ src
...
port.yml
file:
blueprint: code_module
title: Module 1
identifier: module_1_entity
properties:
myStringProp: file://module1/README.md
Using relative pathsโ
It is also possible to use paths relative to the location of the port.yml
spec file.
For example: file://./
is used to reference a file in the same directory as the port.yml
file. file://../
is used to reference a file that is one directory above and so on.
The following example reads README.md
and module1/requirements.txt
using paths relative to port.yml
Repository folder structure used for the example:
root
|
+-+ meta
| |
| +-- port.yml
| |
| +-+ README.md
|
+-+ module1
| |
| +- requirements.txt
| |
| +-+ src
...
port.yml
file:
blueprint: code_module
title: Module 1
identifier: module_1_entity
properties:
readme: file://./README.md
module1Requirements: file://../module1/requirements.txt
Option 2: Use the integration mappingโ
Every integration in Port has a dedicated mapping configuration that allows you to specify which resources to ingest from the integration into Port.
In the case of the GitHub integration, one of the supported resources is the file
resource, which allows you to ingest file contents from a repository into your portal.
To use this approach, you will need to edit your GitHub integration mapping and add a file
block that specifies which files to ingest.
To edit a mapping configuration:
- Go to the data sources page of your portal.
- Under
Exporters
, find the GitHub data source and click on it. - Scroll down to the
Mapping
section and add afile
block to theresources
array.
For example, say you want to ingest a package.json
file form your repository. You can add the following to your GitHub integration mapping:
resources:
...
- kind: file
selector:
query: 'true'
files:
- path: package.json
port:
entity:
mappings:
identifier: .file.name
blueprint: '"file"'
properties:
content: .file.content
The selector.files.path
key also supports glob patterns, so you can ingest multiple files by matching against a pattern and create an entity in Port for each one, for example:
- kind: file
selector:
query: 'true'
files:
- path: 'resources/*.yml'
Advantagesโ
-
Resync support: Since this approach uses the integration mapping, a resync of the integration will update the entities in Port with the latest file contents.
-
Data manipulation: Since this approach uses the integration mapping,
jq
is supported and can be used to transform the file contents before ingestion.
Examplesโ
Check out the example repository for a microservice blueprint and a matching port.yml
file which specifies a microservice entity.
Capabilitiesโ
Port.yml ingestion patternโ
The port.yml
ingestion pattern allows you to configure the GitHub integration to ingest port.yml
files as part of the resync process. This approach is particularly useful when you want to maintain data integrity and ensure that your port.yml
files are properly synchronized with Port.
port.yml
files operate in the GitOps methodology, meaning they are ingested into Port whenever a commit to the main branch of the repository is detected.
Here's how to configure the integration to parse and ingest port.yml
files:
enableMergeEntity: true
resources:
- kind: file
selector:
query: "true"
files:
- path: "**/port.yml"
port:
entity:
mappings:
identifier: .file.content.identifier
title: .file.content.title
blueprint: .file.content.blueprint
properties:
property_a: .file.content.properties.property_a
property_b: .file.content.properties.property_b
relations:
relation_a: .file.content.relations.relation_a
relation_b: .file.content.relations.relation_b
For multiple entities in a single port.yml
file, use the itemsToParse
key:
enableMergeEntity: true
resources:
- kind: file
selector:
query: "true"
files:
- path: "**/port.yml"
port:
itemsToParse: .file.content
entity:
mappings:
identifier: .item.identifier
title: .item.title
blueprint: .item.blueprint
properties:
property_a: .item.properties.property_a
property_b: .item.properties.property_b
relations:
relation_a: .item.relations.relation_a
relation_b: .item.relations.relation_b
Advancedโ
Refer to the advanced page for advanced use cases and configurations.