Simplifying JCL Jobs with Jinja
In this blog we’ll be taking a look at how we can use Jinja templates alongside the submit command on OMVS to simplify the creation and…
Simplifying JCL Jobs with Jinja
In this blog we’ll be taking a look at how we can use Jinja templates alongside the submit command on OMVS to simplify the creation and submission of JCL jobs.
On the mainframe, JCL is still often the lingua franca of system programmers. However, many JCL jobs contain large amounts of boilerplate with only a small number of changing parts.
Let’s take for example this JCL job to create a ZFS filesystem in a dataset:
//ZFSCRT JOB ‘TEST’,CLASS=A, // REGION=4M, // MSGCLASS=B, // MSGLEVEL=(1,1), // NOTIFY=&SYSUID // // Licensed Materials — Property of IBM // 5655-ZOS // Copyright IBM Corp. 2025 // // // JCL to create a new ZFS filesystem in a VSAM // dataset // //* // // This step defines the ZFS dataset. // // //DEFINE EXEC PGM=IDCAMS //SYSPRINT DD SYSOUT= //AMSDUMP DD SYSOUT= //DASD0 DD DISP=OLD,UNIT=3390,VOL=SER=MYVOL1 //SYSIN DD DEFINE CLUSTER( — NAME(MY.ZFS.DATASET) — VOLUMES(MYVOL1) — LINEAR CYL(5 5) SHAREOPTIONS(3)) / //* // // This step creates the ZFS filesystem. // // //CREATE EXEC PGM=IOEAGFMT,REGION=0M,COND=(4,LE), // PARM=(‘-aggregate MY.ZFS.DATASET’) //SYSPRINT DD SYSOUT= //STDOUT DD SYSOUT= //STDERR DD SYSOUT= // *** // // * END OF JCL **
As written, this JCL allocates the MY.ZFS.DATASET dataset on the volume MYVOL1, then creates a ZFS filesystem on that dataset. If we wanted to modify this JCL to use a different dataset, or a different volume, those two values are really the only parts of the job that we would need to change.
This makes JCL a prime candidate for Jinja templates. Using Jinja templates allows us to define which values inside of a larger file may need to be modified, and supply those values later when rendering the final result. For example, we could create the following template out of the above job:
//ZFSCRT JOB ‘TEST’,CLASS=A, // REGION=4M, // MSGCLASS=B, // MSGLEVEL=(1,1), // NOTIFY=&SYSUID // // Licensed Materials — Property of IBM // 5655-ZOS // Copyright IBM Corp. 2025 // // // JCL to create a new ZFS filesystem in a VSAM // dataset // //* // // This step defines the ZFS dataset. // // //DEFINE EXEC PGM=IDCAMS //SYSPRINT DD SYSOUT= //AMSDUMP DD SYSOUT= //DASD0 DD DISP=OLD,UNIT=3390,VOL=SER={{ volume }} //SYSIN DD DEFINE CLUSTER( — NAME({{ zfs_dataset }}) — VOLUMES({{ volume }}) — LINEAR CYL(5 5) SHAREOPTIONS(3)) / //* // // This step creates the ZFS filesystem. // // //CREATE EXEC PGM=IOEAGFMT,REGION=0M,COND=(4,LE), // PARM=(‘-aggregate {{ zfs_dataset }}’) //SYSPRINT DD SYSOUT= //STDOUT DD SYSOUT= //STDERR DD SYSOUT= // *** // // * END OF JCL **
This template can then be rendered to produce the same results as the original job by supplying MY.ZFS.DATASET as the value for zfs_dataset and MYVOL1 as the value for volume.
There are many ways to use Jinja for rendering templates. Ansible has extensive support for this, while Python can accomplish it programmatically through a library. Python also provides a PyPi module, jinja-cli, which provides the functionality through a simple CLI interface. This makes quick, easy Jinja rendering available on the mainframe OMVS environment, thanks to ZOAU.
Using the jinja-cli utility, we can render our template and save the result to a JCL file like so:
jinja -D zfs_dataset “MY.ZFS.DATA” \ -D volume “MYVOL1” \ ./zfscreat.j2 > ./zfscreat.jcl
Once we have our JCL, we can then submit it from OMVS using the submit command:
submit ./zfscreat.jcl
Alternatively, submit also support reading from standard input, allowing us to combine these two steps into one like so:
jinja -D zfs_dataset “MY.ZFS.DATA” \ -D volume “MYVOL1” \ ./zfscreat.j2 > ./zfscreat.jcl | \ submit -
메타데이터
- post_id
- a2da23cdd7e6
- slug
- simplifying-jcl-jobs-with-jinja-a2da23cdd7e6
- url
- https://medium.com/@john.e.craig.jr/simplifying-jcl-jobs-with-jinja-a2da23cdd7e6
- canonical_url
- https://medium.com/@john.e.craig.jr/simplifying-jcl-jobs-with-jinja-a2da23cdd7e6
- author_url
- https://medium.com/@john.e.craig.jr
- status
- ok
- fetched_at
- 2026-06-24 11:06:28