[[YAML_Configuration_file]]
= YAML Configuration file

ifdef::env-github[]
:tip-caption: :bulb:
:note-caption: :information_source:
:important-caption: :heavy_exclamation_mark:
:caution-caption: :fire:
:warning-caption: :warning:
endif::[]

A common way to manage WildFly installations over time is to start with a standard configuration file (e.g. the out-of-the-box `standalone.xml` file that comes with each WildFly release) and then apply installation specific customizations to it (e.g. add datasource resources and Elytron security realm resources to integrate with the company's own services). As the standard configuration file evolves over time (with new releases) the goal is to efficiently re-apply the installation specific customizations. Users have several ways to apply their customizations: edit the XML manually or with XML manipulation tools (neither of which is recommended), create jboss-cli scripts that you can run on each upgrade, or use WildFly's YAML configuration file feature.

With the YAML configuration file approach, you provide one or more YAML files that specify the resources that you want WildFly to add to its running configuration, along with any configuration attribute values that should differ from what's in standalone.xml. Using YAML files has advantages over using CLI scripts:

* CLI scripts can be tricky to write as they usually aren't idempotent. If you run a script that adds a datasource, that datasource is now in the standalone.xml file, so if you run the script again, it will fail due to attempting to add an existing resource. This can be worked around by using the `--read-ony-server-config` command line flag instead of the usual `-c` / `--server-config`. Or you can write more complex CLI scripts that check whether resources already exist before attempting to add them. Both of these approaches can work, but they can be tricky to do correctly. The YAML configuration file approach is idempotent. The WildFly server reads the YAML at boot and updates its running configuration, but it does not update the standalone.xml file, so the same thing can be done repeatedly.
* Applying a CLI script usually involves launching a separate Java process (the WildFly CLI). Needing to do this can be a poor fit for configuration customization workflows. With the YAML configuration file approach, the WildFly server process itself process the YAML as part of boot.

[[starting_with_yaml_files]]
== Starting with YAML files

Using the `--yaml` or `-y` argument you can pass a list of YAML files. Each path needs to be separated by the `File.pathSeparator`.  It is a semicolon (;) on Windows and colon (:) on Mac and Unix-based operating systems.
Paths can be absolute, relative to the current execution directory or relative to the standalone configuration directory.

[source,options="nowrap"]
----
./standalone.sh -y=/home/ehsavoie/dev/wildfly/config2.yml:config.yml -c standalone-full.xml
----

[[what_is_in_yaml]]
== What is in the YAML

The YAML root node must be *wildfly-configuration*, then you can follow the model tree to add or update resources.

Sample YAML file to define a new PostGresql datasource:
[source,options="nowrap"]
----
wildfly-configuration:
  subsystem:
    datasources:
      jdbc-driver:
        postgresql:
          driver-name: postgresql
          driver-xa-datasource-class-name: org.postgresql.xa.PGXADataSource
          driver-module-name: org.postgresql.jdbc
      data-source:
        PostgreSQLDS:
          enabled: true
          exception-sorter-class-name: org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLExceptionSorter
          jndi-name: java:jboss/datasources/PostgreSQLDS
          jta: true
          max-pool-size: 20
          min-pool-size: 0
          connection-url: "jdbc:postgresql://localhost:5432}/demo"
          driver-name: postgresql
          user-name: postgres
          password: postgres
          validate-on-match: true
          background-validation: false
          background-validation-millis: 10000
          flush-strategy: FailingConnectionOnly
          statistics-enable: false
          stale-connection-checker-class-name: org.jboss.jca.adapters.jdbc.extensions.novendor.NullStaleConnectionChecker
          valid-connection-checker-class-name: org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLValidConnectionChecker
          transaction-isolation: TRANSACTION_READ_COMMITTED
----

We also provide three operations using tags:

* *!undefine*: to undefine an attribute

Sample YAML file to undefine the CONSOLE logger level:
[source,options="nowrap"]
----
wildfly-configuration:
    subsystem:
        logging:
          console-handler:
            CONSOLE:
              level: !undefine
----

* *!remove*: to remove the resource

Sample YAML file to remove the MicroProfile Smallrye JWT subsystem:
[source,options="nowrap"]
----
wildfly-configuration:
    subsystem:
        microprofile-jwt-smallrye: !remove 
----

* *!list-add*: to add an element to a list (with an optionnal index).

Sample YAML file to add a RemoteTransactionPermission to the permissions list at the position 0:
[source,options="nowrap"]
----
wildfly-configuration:
    subsystem:
        elytron:
          permission-set:
           default-permissions: 
             permissions: !list-add 
              - class-name: org.wildfly.transaction.client.RemoteTransactionPermission
                module: org.wildfly.transaction.client
                target-name: "*"
                index: 0
----

You can't configure everything in YAML. Configuring the following resource types is not supported:

 - extension: to add an extension to the server as this might require modules which may be missing.
 - deployment: to add *managed* deployments to the server as this requires more than just some configuration.
 - deployment-overlay: to add deployment-overlays to the server as this requires more than just some configuration.
 - path: since those should already have been defined when the YAML files are parsed.

While *managed* deployments are not supported you can still define *unmanaged* deployments. An unmanaged deployment is one where the server does not make an internal copy of the deployment content for its use; instead it directly uses the configured content. See link:#managed-and-unmanaged-deployments[Managed and Unmanaged Deployments].

IMPORTANT: All your changes using the management API aren't persisted since the server is in *read-only* mode with YAML.

This is a sample to install two deployments but with only one deployed:

[source,options="nowrap"]
----
wildfly-configuration:
  deployment:
    test.jar:
      content:
        -
          path: test.jar
          relative-to: jboss.server.base.dir
          archive: true
      enabled: true
    hello.jar:
      content:
        - 
          path: test.jar
          relative-to: jboss.server.base.dir
          archive: true
----

NOTE: For historical reasons, the `content` attribute is of type LIST so you must add a *-* before defining the archive or the directory of your deployment. The list should only contain a *single* element.