Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

Deploy a Java application on Red Hat OpenShift using JKube

April 13, 2022
Mauro Vocale
Related topics:
ContainersJavaKubernetes
Related products:
Red Hat JBoss Enterprise Application PlatformRed Hat OpenShift Container Platform

Share:

    Enterprise Java applications don't run in a vacuum, but interact with other components such as databases, load balancers, monitoring, and so forth. Eclipse JKube makes it easier to build Java applications and connect them with the resources they need when running as containers under Kubernetes. This article builds on a previous article, Build a bootable JAR for cloud-ready microservices, and shows some advanced uses of JKube. We'll build and deploy a bootable JAR using Red Hat JBoss Enterprise Application Platform (JBoss EAP) and Jakarta EE, and incorporate a PostgreSQL database and MicroProfile capabilities.

    How JKube helps build and deploy Java applications

    The previous article in this series listed all the commands needed to create the application's resources (buildConfig, deployment, service, route, etc.) and the other actors (Prometheus, Grafana, Jaeger, etc.) used to implement some features, like tracing and observability, needed to build a cloud-ready application. However, developers are hoping for a developer-friendly tool that creates Kubernetes and Red Hat OpenShift manifests, making it easier to build and deploy their applications. Is there a way to do this with a solution that can be integrated with the standard build process, and avoid do-it-yourself scripting?

    Eclipse JKube is a collection of plugins and libraries that builds container images, creates the OpenShift manifests at compile time, and gives an easy way to automatically generate the tasks required to make your application cloud-ready—it can create liveness and readiness probes, for instance. JKube provides an OpenShift Maven plugin that extends the features of Maven, giving developers an easy way to configure all the resources needed by an application to run in a PaaS environment.

    In this article, you'll update the source code from the previous article in the series so you can configure and deploy that application on Red Hat OpenShift using JKube. You'll also see how to provision common layers, such as the data source, through the capabilities implemented by Galleon feature packs.

    There are two other useful JKube concepts you'll use in these examples:

    • An enricher is a structured way to add common capabilities, such as security secrets and ConfigMaps, to images.
    • A profile is a group of enrichers and instructions for building instances (generators) that are applied together to an instance.

    Implementation

    Now it's time to move to the source code, available on my GitHub repository, and share my process with you. You'll reuse the source code from the previous article. To preserve the evolution path of my application, I created a new tag, JKube_Galleon_Runtime_EAP_XP_bootable_jar_version, in the repository for this article.

    Environment configuration

    You can follow the example in this article using:

    • An OpenShift installation (I used version 4.8). You can use Red Hat CodeReady Containers if you want to install OpenShift locally.
    • JBoss EAP 7.4
    • JBoss EAP expansion pack (JBoss EAP XP) 3.0
    • Apache Maven 3.8.2
    • OpenJDK 11
    • Git 2.31.1

    You can use the tags to analyze the progress of the journey.

    Environment provisioning

    The first step is to get the source code needed for the demonstration. Open a terminal, select a folder, and clone the Git repository using the following command:

    $ git clone https://github.com/mvocale/JBoss_EAP_cloud_ready.git

    Go to your project folder and switch to the JKube_Galleon_Runtime_EAP_XP_bootable_jar_version tag, where I stored the code for an OpenShift deployment with JKube, using the following command:

    $ git checkout tags/JKube_Galleon_Runtime_EAP_XP_bootable_jar_version

    Now you can see the weather-app-eap-cloud-ready subproject. It contains the source code to use the Jakarta EE 8 and MicroProfile 4 specifications. They run JBoss EAP XP 3, in bootable JAR mode, and use Galleon to incorporate only the required subsystems on top of OpenShift 4.8. The final container image was improved using the runtime version of OpenJDK 11.

    The repository also contains a deploy-openshift.sh file with all the instructions needed to install all the implemented components on OpenShift. If you don't want to perform every single step described here, you can launch the application after establishing a successful connection with CodeReady Containers or a remote OpenShift cluster.

    Now it's time to connect to OpenShift to deploy your application. If you decided to use CodeReady Containers, you need to start it and log in as a developer using the following commands:

    $ crc start
    $ oc login -u developer -p developer https://api.crc.testing:6443

    Otherwise, if you have an available OpenShift environment, log into it as follows, replacing $token and $server_url with your own values:

    $ oc login --token=$token --server=$server_url

    Create the project to host your application:

    $ oc new-project redhat-jboss-eap-cloud-ready-demo --display-name="Red Hat JBoss EAP Cloud Ready Demo"

    Next, using Maven and JKube, you will set all the components needed by the application to run in the final environment. Maven's pom.xml file will become the core of the implementation of the build and deployment process.

    PostgreSQL database

    The application needs a database to store information. We will create a PostgreSQL instance for this purpose using JKube later. In the meantime, I have used a repository called Galleon Feature Pack for integrating datasources into Red Hat JBoss Enterprise Application Platform to configure the data source subsystem. Take a look at the pom.xml file:

    ...
    <properties>
        ...
        <version.eap.datasources.galleon.pack>7.4.0.GA-redhat-00003</version.eap.datasources.galleon.pack>
        <org.jboss.eap.datasources.postgresql.driver.version>42.2.23.redhat-00001</org.jboss.eap.datasources.postgresql.driver.version>
        ...
    </properties>
    ...
    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>properties-maven-plugin</artifactId>
        <version>1.0.0</version>
        <executions>
            <execution>
                <goals>
                    <goal>set-system-properties</goal>
                </goals>
                <configuration>
                    <properties>
                        <property>
                            <name>org.jboss.eap.datasources.postgresql.driver.version</name>
                            <value>${org.jboss.eap.datasources.postgresql.driver.version}</value>
                        </property>
                    </properties>
                </configuration>
            </execution>
        </executions>
    </plugin>
    <plugin>
        <groupId>org.wildfly.plugins</groupId>
        <artifactId>wildfly-jar-maven-plugin</artifactId>
        <version>${bootable.jar.maven.plugin.version}</version>
        <configuration>
            <feature-packs>
                ...
                <feature-pack>
                    <location>org.jboss.eap:eap-datasources-galleon-pack:${version.eap.datasources.galleon.pack}</location>
                </feature-pack>
            </feature-packs>
            <cloud/>
            <layers>
                <layer>jaxrs-server</layer>
                <layer>microprofile-platform</layer>
                <layer>postgresql-datasource</layer>
            </layers>
            ...
            <executions>
                <execution>
                    <goals>
                        <goal>package</goal>
                    </goals>
                </execution>
            </executions>
        </configuration>
    </plugin>
    ...

    Two properties are key:

    • version.eap.datasources.galleon.pack represents the version of the feature pack for JBoss EAP that provides a JDBC driver and a data source for the PostgreSQL database.
    • org.jboss.eap.datasources.postgresql.driver.version sets the versions of the PostgreSQL JDBC drivers.

    The plugin section configures the following plugins:

    • properties-maven-plugin specifies the version of the PostgreSQL JDBC driver.
    • wildfly-jar-maven-plugin employs the org.jboss.eap:eap-datasources-galleon-pack feature pack to automatically provision and configure JBoss EAP to use the JDBC driver and data source subsystem, configured to interact with the PostgreSQL database.

    JKube in action

    Now it's time to focus on JKube to create what you need to deploy and run your application. In my previous article, I deployed my weather application as a bootable JAR employing an OpenShift chained build to use an OpenJDK runtime image. I also created all the applications needed to implement the tracing and observability features (Prometheus, Grafana, Jaeger) and the PostgreSQL database with a long list of commands invoking oc (the OpenShift command line interface). This approach worked well, but it's not suitable for CI/CD. What I needed was a way, possibly using a developer-friendly tool like Maven, to build and deploy all components of my business use case—the application and its dependencies.

    JKube does exactly this job. The OpenShift Maven Plugin integrates JKube with Maven and exploits the build configuration already provided.

    Configuring JKube

    To use the OpenShift Maven plugin, configure JKube in the pom.xml file:

    <properties>
        ...
        <version.jkube.openshift.maven.plugin>1.7.0</version.jkube.openshift.maven.plugin>
        ...
    </properties>
    <plugin>
        <groupId>org.eclipse.jkube</groupId>
        <artifactId>openshift-maven-plugin</artifactId>
        <version>${version.jkube.openshift.maven.plugin}</version>
        <executions>
            <execution>
                <goals>
                    <goal>resource</goal>
                    <goal>build</goal>
                </goals>
            </execution>
        </executions>
        ...
    </plugin>

    I used the 1.7 version of JKube and set two build goals:

    • resource creates OpenShift resources (service, route, etc.) based on conventions defined through the project's code. It also uses XML configurations defined in pom.xml, integrating them with resource fragments defined in the src/main/jkube directory of the project. We will cover those resources later.
    • build generates the final application container image that will be pushed to the registry (in my example, the internal OpenShift registry) and that will be used by the pod that runs the application.

    Creating the application image

    After configuring JKube in pom.xml and defining the build goal, it's time to tell JKube how to create the weather-app application image. Here's the the pom.xml fragment dedicated to this topic:

    ...
    <properties>
        ...
        <jkube.build.strategy>docker</jkube.build.strategy>
        <application.runtime.image>registry.access.redhat.com/ubi8/openjdk-11-runtime:1.11-2.1645811205</application.runtime.image>
        ...
    </properties>
    ...
    <plugin>
        <groupId>org.eclipse.jkube</groupId>
        <artifactId>openshift-maven-plugin</artifactId>
        <version>${version.jkube.openshift.maven.plugin}</version>
        ...
        <configuration combine.self="override">
            <!-- Environment variables needed to configure the runtime image -->
            <images>
                <image>
                    <name>weather-app-eap-cloud-ready</name> 1
                    <build>
                        <from>${application.runtime.image}</from> 2
                        <assembly>
                            <targetDir>/deployments</targetDir> 3
                            <excludeFinalOutputArtifact>true</excludeFinalOutputArtifact>
                            <layers>
                                <layer>
                                    <id>bootable</id>
                                    <files>
                                        <file>
                                            <source>${project.build.directory}/${project.artifactId}-${project.version}-bootable.jar</source> 4
                                            <outputDirectory>.</outputDirectory>
                                        </file>
                                    </files>
                                </layer>
                            </layers>
                        </assembly>
                        <entryPoint>
                            <shell>java -jar /deployments/${project.artifactId}-${project.version}-bootable.jar -Dwildfly.datasources.statistics-enabled=true</shell> 5
                        </entryPoint>
                    </build>
                </image>
            </images>
        </configuration>
    </plugin>

    All the JKube configurations are inside the <configuration> XML tag. The main properties, each highlighted with a number near the XML tag in the example, are:

    1. name: The final application image that is pushed into the internal registry and deployed in OpenShift.
    2. from: The image, created by JKube, that will build the final application image
    3. targetDir: The directory where Maven will put the application artifact (the bootable JAR file) that will be used to execute the weather application
    4. source: The bootable JAR file
    5. shell: The command that will execute the application pod

    The jkube.build.strategy property near the top of the example is important because I used an OpenJDK runtime image (without developer tools such as Maven). The bootable JAR is built outside of OpenShift—specifically, in my example, on my laptop. So I send to OpenShift the binary archive with the executable JAR that will be run inside OpenShift. If I failed to specify this property, JKube would try by default to use a Source-to-Image (S2I) build strategy that uses a builder image to create a new application image from binary build data. This won't work if you want to use an OpenJDK runtime image.

    Service resources

    You need to create a Kubernetes service to expose the application running on a set of pods as a network service. My application needs to expose other ports that are usually provided by the OpenJDK image. For this reason, I configured JKube to create the weather-app-eap-cloud-ready service that will expose all the ports needed by the application, particularly 8080 for the web user interface and APIs and 9990 for the metrics exposed by JBoss EAP XP to implement the Metrics MicroProfile specification. Take a look at the pom.xml file:

    ...
    <plugin>
        <groupId>org.eclipse.jkube</groupId>
        <artifactId>openshift-maven-plugin</artifactId>
        <version>${version.jkube.openshift.maven.plugin}</version>
        ...
        <configuration combine.self="override">
            ...
            <resources>
                <!-- This is the kubernetes service that expose the JBoss EAP service -->
                <services>
                    <service>
                        <name>weather-app-eap-cloud-ready</name>
                        <type>NodePort</type>
                        <expose>true</expose>
                        <ports>
                            <port>
                                <name>health-check</name>
                                <protocol>TCP</protocol>
                                <port>9990</port>
                                <targetPort>9990</targetPort>
                            </port>
                            <port>
                                <name>http</name>
                                <protocol>TCP</protocol>
                                <port>8080</port>
                                <targetPort>8080</targetPort>
                            </port>
                            <port>
                                <name>https</name>
                                <protocol>TCP</protocol>
                                <port>8443</port>
                                <targetPort>8443</targetPort>
                            </port>
                            <port>
                                <name>jolokia</name>
                                <protocol>TCP</protocol>
                                <port>8778</port>
                                <targetPort>8778</targetPort>
                            </port>
                        </ports>
                    </service>
                </services>
            </resources>
          ...
        </configuration>
    </plugin>

    Configuration is pretty simple: Set each service name and type and all the ports that you want to make available.

    OpenShift route resources

    You need to expose the Kubernetes service outside of OpenShift so users can access the application, and also to make available all the cloud-native features implemented using MicroProfile specifications: Metrics, Health, OpenTracing, etc.

    JKube is able to automatically generate an OpenShift route descriptor starting from this Kubernetes service. However, you can't use JKube's solution because weather-app-eap-cloud-ready exposes multiple ports. The solution is to instruct JKube not to directly expose the Kubernetes services, but to use the route descriptors implemented in the source code instead.

    To avoid the automatic route creation, configure the enricher as follows:

    ...
    <plugin>
        <groupId>org.eclipse.jkube</groupId>
        <artifactId>openshift-maven-plugin</artifactId>
        <version>${version.jkube.openshift.maven.plugin}</version>
        ...
        <configuration combine.self="override">
            ...
            <enricher>
                <config>
                    <jkube-openshift-route>
                        <!-- I need to use the fragments approach since my service expose multiple ports and the enricher is not able to automatically generates multiple routes -->
                        <generateRoute>false</generateRoute>
                    </jkube-openshift-route>
                </config>
            </enricher>
        </configuration>
    </plugin>

    Next, you need to create YAML files that define the OpenShift routes inside the src/main/jkube directory.

    JKube will pick up the resources using the YAML resource descriptors, enrich them, and finally combine all the resources in a single openshift.yml file that deploys all the resources into OpenShift.

    The source code structure is shown in Figure 1.

    Diagram showing source code structure.
    Figure 1: Source code structure.

    The following route exposes the application outside of OpenShift:

    kind: Route
    apiVersion: route.openshift.io/v1
    metadata:
      name: weather-app-eap-cloud-ready
      namespace: redhat-jboss-eap-cloud-ready-demo
      labels:
        app: weather-app-eap-cloud-ready
    spec:
      to:
        kind: Service
        name: weather-app-eap-cloud-ready
      port:
        targetPort: 8080
      wildcardPolicy: None

    The file creates the service and the route and defines the runtime image that the application uses.

    Environment variables

    Applications, and the tools that build them, often consult environment variables for important configuration information. JKube makes it easy to define these environment variables. Under the <resources> section of the pom.xml file, the <env> tag specifies the variables' names and values for interacting with the PostgreSQL database and Jaeger:

    ...
    <plugin>
        <groupId>org.eclipse.jkube</groupId>
        <artifactId>openshift-maven-plugin</artifactId>
        <version>${version.jkube.openshift.maven.plugin}</version>
        ...
        <!-- JKube XML Configuration approach -->
        <configuration combine.self="override">
            <resources>
            ...
                <env>
                    <!-- Variables needed with eap datasource galleon pack -->
                    <POSTGRESQL_DATABASE>weather</POSTGRESQL_DATABASE>
                    <POSTGRESQL_USER>mauro</POSTGRESQL_USER>
                    <POSTGRESQL_PASSWORD>secret</POSTGRESQL_PASSWORD>
                    <POSTGRESQL_URL>jdbc:postgresql://${env.WEATHER_POSTGRESQL_SERVICE_HOST}:${env.WEATHER_POSTGRESQL_SERVICE_PORT}/${env.POSTGRESQL_DATABASE}</POSTGRESQL_URL>
                    <POSTGRESQL_DATASOURCE>WeatherDS</POSTGRESQL_DATASOURCE>
                    <POSTGRESQL_ENABLED>true</POSTGRESQL_ENABLED>
                    <POSTGRESQL_VALIDATE_ON_MATCH>false</POSTGRESQL_VALIDATE_ON_MATCH>
                    <POSTGRESQL_BACKGROUND_VALIDATION>true</POSTGRESQL_BACKGROUND_VALIDATION>
                    <POSTGRESQL_BACKGROUND_VALIDATION_MILLIS>60000</POSTGRESQL_BACKGROUND_VALIDATION_MILLIS>
                    <POSTGRESQL_FLUSH_STRATEGY>IdleConnections</POSTGRESQL_FLUSH_STRATEGY>
                    <JAEGER_AGENT_HOST>$(JAEGER_ALL_IN_ONE_RHEL8_SERVICE_HOST)</JAEGER_AGENT_HOST>
                    <JAEGER_AGENT_PORT>$(JAEGER_ALL_IN_ONE_RHEL8_SERVICE_PORT_6831_UDP)</JAEGER_AGENT_PORT>
                    <JAEGER_SAMPLER_PARAM>1</JAEGER_SAMPLER_PARAM>
                    <JAEGER_SAMPLER_TYPE>const</JAEGER_SAMPLER_TYPE>
                    <JAEGER_SERVICE_NAME>weather-app-eap-cloud-ready</JAEGER_SERVICE_NAME>
                    <WILDFLY_TRACING_ENABLED>true</WILDFLY_TRACING_ENABLED>
                </env>
            </resources>
        ...
        </configuration>
    </plugin>

    Application dependencies

    In my previous article, I needed to execute a long list of commands manually or grouped by in the deploy-openshift.sh file. JKube makes these steps easy and automatic. Just group all the resources' YAML descriptors into a directory named src/main/jkube/raw. Why raw? JKube reserves this name for a profile that includes only generators, no enrichers. Figure 2 shows the contents of this directory.

    Diagram showing contents of the raw directory
    Figure 2: Contents of the raw directory
    Figure 2: Contents of the raw directory.

    The following YAML deploys the application's PostgreSQL database:

    kind: Deployment
    apiVersion: apps/v1
    metadata:
      name: weather-postgresql
      namespace: redhat-jboss-eap-cloud-ready-demo
      labels:
        app: weather-postgresql
        app.openshift.io/runtime: postgresql
    spec:
      replicas: 1
      selector:
        matchLabels:
          deployment: weather-postgresql
      template:
        metadata:
          labels:
            deployment: weather-postgresql
        spec:
          containers:
            - name: postgresql-13
              image: >-
                registry.redhat.io/rhel8/postgresql-13:1-31
              ports:
                - containerPort: 5432
                  protocol: TCP
              envFrom:
                - configMapRef:
                    name: postgres-config

    Deploying the application

    Everything is now in place to build all the resources needed by the application and run it in OpenShift. JKube allows simple deployment with a traditional Maven approach:

    $ mvn oc:deploy

    The application is compiled locally. After that, JKube performs all the tasks needed to deploy and execute the application on your OpenShift cluster, together with all components used by the application. In the end, you will see something like Figure 3 in the Topology view of your OpenShift console.

    The weather application is deployed together with a PostgreSQL database and other resources.
    Figure 1. The weather application is deployed together with a PostgreSQL database and other resources.
    Figure 3: The weather application is deployed together with a PostgreSQL database and other resources.

    You can then test the application, using the steps described in another previous article of mine, to verify that it works.

    To delete all the resources and clean up your project, enter:

    $ mvn oc:undeploy

    Conclusion

    This article has shown you how to easily deploy an application and all its dependencies as a single task using JKube and Maven. This approach minimizes the learning curve, letting you create a solution that uses a consolidated approach like the Maven build to give you the power to manage and orchestrate all the components needed to implement a business use case. You can start to implement a Kubernetes deployment strategy using this approach. The impact really is as low as demonstrated in this article.

    So don't stop evolving all of your applications: Continuous improvement is the key to the success of your architecture.

    If you'd like to learn more about how Red Hat is working to improve the state of observability in distributed and cloud-based applications, read "Observability in 2022: Why it matters and how OpenTelemetry can help" on Red Hat Developer.

    Last updated: September 20, 2023

    Recent Posts

    • AI meets containers: My first step into Podman AI Lab

    • Live migrating VMs with OpenShift Virtualization

    • Storage considerations for OpenShift Virtualization

    • Upgrade from OpenShift Service Mesh 2.6 to 3.0 with Kiali

    • EE Builder with Ansible Automation Platform on OpenShift

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2025 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue