
In this blog post, we’ll explore how to use Pulumi and the Terraform Nexus Provider to configure and manage Sonatype Nexus, a powerful tool for managing and governing the flow of software components throughout the development lifecycle. We’ll take a step-by-step approach, covering everything from installing and configuring Pulumi to defining and deploying Nexus resources. By the end of this post, you’ll have a solid understanding of how to leverage Infrastructure as Code (IaC) to automate your Nexus configuration.
Tools
Terraform Nexus Provider:
The first commit of the Synvert Datadrivers Nexus Provider for Terraform was pushed on January, 10th 2020. What was meant to be a purely internal project is now used by many individuals globally, expecting to reach two million downloads in 2025. The provider is a plugin which enables us to describe the desired configuration of our Nexus in Terraform’s native language called Hashicorp Configuration Language (HCL). Without it, Terraform would not know how to map Create, Read, Update and Delete operations (CRUD) to the Nexus API.
Terraform / OpenTofu:
For quite some time, Terraform was seen as the de facto industry standard for declarative configuration and infrastructure management.
OpenTofu is a community project based on the original Terraform codebase that was forked prior to Hashicorps announcement to adopt the BSL license.
Pulumi:
Like Terraform, Pulumi is a Software to describe and manage IaC. What’s unique to Pulumi, is that you can choose the programming language of your choice for this task and not have to bother with HCL.
Pulumi’s Any Terraform Provider:
In August 2024 Pulumi announced a new feature which enables it’s users to use any Terraform or OpenTofu Provider without the necessity to bridge a Terraform Provider to Pulumi in order to make use of it.
How To
Setup Nexus
If you don’t have a running Nexus installation at hand, which you can use to go through the next steps, you can use our development setup from this link.
This will setup Nexus in your Docker environment, thus you need to have Docker and Docker Compose running and configured.
git clone https://github.com/datadrivers/terraform-provider-nexus.git
cd terraform-provider-nexus/scripts
source .env
./start-services.sh
# It might take a minute or two to setup Nexus
# Use curl to check if the setup is completed
curl localhost:8081

Install Pulumi
Pulumi is available for Linux, macOS and Windows and can be installed by downloading the respective binary from the Pulumi website or by using your favorite package manager. If you are on macOS and have brew installed, installing Pulumi is as simple as:
brew install pulumi
Create a working directory and setup a Pulumi project
Once you have Pulumi installed, open a terminal and execute the following commands to setup the basic scaffold:
mkdir nexus-pulumi
cd nexus-pulumi
pulumi new python -g
- mkdir creates a new directory and cd switches into it,
- The new subcommand instructs Pulumi to setup a new project in the current working directory supporting the Python programming language and the -g flag tells Pulumi to only generate the scaffold, without a Pulumi stack or the installation of any dependencies, as this will be done in the following steps. The command prompts for three inputs:
- Project name,
- Project description and
- Toolchain for the dependency management. (Select pip in case you are unsure)

Configure Pulumi to use the Any Terraform Provider with the Nexus Provider
pulumi package add terraform-provider datadrivers/nexus
pulumi install
pulumi login --local
pulumi stack init
pulumi config set nexus:url "http://127.0.0.1:8081"
This is where the magic happens. The first command does a couple things: First it instructs Pulumi to set up a new virtualenv for Python and then it downloads the Any Terraform Provider from the Pulumi Registry. This Provider is then configured to be used with the Terraform Nexus Provider. This Configuration results in a Nexus SDK which is located underneath the “sdks” folder in the current working directory.
In order to create Resources in your Nexus installation you need to point the Nexus Provider to correct URL, this can be achieved using the config subcommand as shown in the last command above.
Create Nexus Resources using Pulumi
Depending on the language that has been selected with the pulumi new command, Pulumi also creates a main source file on your behalf. In case of Python it is called __main__.py. This file can be further modified to create a Nexus Blobstore and a Yum Repository like so:
"""A Python Pulumi program"""
import pulumi
import pulumi_nexus as nexus
yum_blob_store = nexus.BlobstoreFile(
"yum_blob_store",
path="/yum_blob_store",
)
yum_repo = nexus.RepositoryYumHosted(
"yum_repo",
name="YumRepository",
storage={
"blob_store_name": yum_blob_store.name,
"strict_content_type_validation": True
},
)
We can break this file up into two parts.
- Dependency Management:
import pulumi
import pulumi_nexus as nexus
The first line imports general Pulumi dependencies and the second line creates a new Python object named nexus that holds all the methods that we programmed into the Nexus Terraform Provider.
2. Nexus Configuration:
yum_blob_store = nexus.BlobstoreFile(
"yum_blob_store",
path="/yum_blob_store",
)
yum_repo = nexus.RepositoryYumHosted(
"yum_repo",
name="YumRepository",
storage={
"blob_store_name": yum_blob_store.name,
"strict_content_type_validation": True
},
)
Among others the nexus object contains two methods:
- BlobstoreFile and
- RepositoryYumHosted
Using this methods, we first define a Blobstore named “yum_blob_store” and then a Yum Repository named “YumRepository”.
You can now save this file and execute the command:
pulumi up
You should get an output similar to the following:

If you select yes, Pulumi checks your code and creates the described Resources respecting the configured order. What that means, is that the blobstore is created before the Yum Repository. You should see something similar to this:

Finally, looking at the Nexus Web-UI (http://127.0.0.1:8081), we can see that a new Repository has been created.

Final words of caution
At the time of writing (February, 21st 2025) the Any Terraform Provider is still in public beta.
A complete lifecycle management of resources should also include the destruction of such resources. This is what the pulumi destroy command is for. But for unknown reasons the destruction of the resources fails:

This exception does not occur when using the Nexus Terraform Provider with Terraform, thus I suspect it to be somehow related to the Any Terraform Provider by Pulumi and the way it is bridging the CRUD operations from Python to Golang. This is a known issue, which should have been resolved with v0.7.0. But I still run in to this behavior.
Nevertheless, this looks like a very promising feature as it enables development teams to setup their own infrastructure using the programming languages they are most familiar with.