REST API, Repository Provisioning, Security Automation, Pagination, and Infrastructure-as-Code Patterns: Configuration, Design Choices, and Tradeoffs
Design an automation operating model rather than a pile of scripts: decide how desired state is represented, which identity may reconcile it, which fields automation owns, when updates are safe, and how direct REST compares with providers or higher-level tooling.
Learning objectives
- Compare imperative scripts with declarative reconciliation using failure and review criteria.
- Separate bootstrap administration from scoped day-to-day automation identities.
- Choose in-place updates over destructive recreation where state identity/content must survive.
- Define ownership and drift policy for API-managed versus manually managed fields.
- Evaluate direct REST, generated clients, and external providers without assuming feature parity.
Version baseline (26 August 2026). These lessons
use Sonatype Nexus Repository 3.95.2-01 as the
dated self-hosted reference point, verified from Sonatype's public
release repository, with Java 21 as the current runtime requirement.
The mandatory lab assumes a small, disposable, loopback-only
self-hosted Community Edition installation using H2 and a file blob
store. The local instance's own
/service/rest/swagger.json is authoritative for the
exact endpoint schema you are about to call; API fields, repository
recipes, security endpoints, and edition entitlements can change
between releases.
Automation safety boundary. Do not put real passwords, user-token passcodes, Authorization headers, production base URLs, or employer namespaces into source files or lesson evidence. The examples use environment variables, synthetic names, loopback URLs, and disposable resources. User Tokens are a Pro capability in current self-hosted Nexus Repository; Community labs therefore use a disposable local account/password only for bootstrap and immediately reduce privileges for the service identity.
Pagination documentation note. Current Sonatype
pages agree on the continuationToken contract but
currently disagree on the documented default item count for
components/assets. The robust automation rule is independent of page
size: process every returned items array, pass the
returned token unchanged, and stop only when
continuationToken is null.
1. From “script that works” to an operating model
Lesson 2 proved a small script can provision Nexus. Production automation adds harder questions: Who owns desired state? Who reviews changes? Which identity runs it? What happens when an operator changes the UI? How are secrets injected? Can a resource update in place? What happens when Nexus upgrades and a schema changes?
The same REST endpoint can be safe or dangerous depending on ownership, privilege, and reconciliation policy.
2. Imperative script versus declarative reconciliation
| Approach | Strength | Failure risk | Good fit |
|---|---|---|---|
| Imperative sequence | Explicit control flow; easy to prototype | Reruns may duplicate/fail; state assumptions hide in code | Disposable lab or tightly scoped one-off operation |
| Declarative reconciler | Desired state review; reruns converge | Poor normalization can produce perpetual drift | Repeated repository/security provisioning |
| Generated API client | Typed models from OpenAPI | Client version can drift from server version | Larger internal tooling with version pinning/tests |
| Third-party IaC provider/plugin | Planning/state integration | Coverage/release cadence may lag Nexus APIs | Teams already using that IaC ecosystem |
No approach removes the requirement to understand Nexus state. A provider that internally calls REST inherits the same API/version/authorization boundaries.
3. Bootstrap identity versus service identity
A common anti-pattern is putting the admin password
into a CI variable and letting every repository job use it.
Separate:
- Bootstrap authority for rare establishment of administration/security objects.
- Reconciliation authority scoped to resources and operations automation owns.
- Publisher/consumer identity for data-plane access only.
Provisioning security may genuinely require elevated privileges; that does not justify granting them to the package publisher or every CI job.
4. Delete-and-recreate is not a generic update strategy
Repository identity connects to content, clients, privileges, groups, cleanup policies, routing, CI configuration, and audit expectations. Deleting a repository to change one field can trigger much more state change than intended.
| Change | Preferred pattern | Why |
|---|---|---|
| Online flag | Format/type-specific PUT | Configuration changes while identity/content remains |
| Group member order | PUT intended ordered list after diff | Order is behavioral state |
| Repository name | Treat as identity/migration decision | Client URLs and privilege names can depend on it |
| Blob store move | Supported repository/blob movement procedure | Not equivalent to delete/recreate or filesystem copy |
| Destruction | Explicit plan with ownership marker/evidence | Deletion can remove valuable content/state |
5. API-generated configuration versus manual UI ownership
Define each field/resource as enforced, detect-only, human-owned, or ephemeral. A drift report must distinguish server defaults that changed after upgrade from a deliberate human edit. Normalize omitted/default fields carefully instead of producing noisy perpetual plans.
6. Desired state must not become a secret dump
repositories:
- name: learner-api-hosted
format: raw
type: hosted
online: true
storage:
blobStoreName: default
strictContentTypeValidation: true
writePolicy: ALLOW_ONCE
service_accounts:
- userId: svc-learner-api
roles: [learner-api-publisher]
password_from_env: NEXUS_SVC_PASSWORD
The final field points to runtime secret injection; it is not the secret itself.
7. Provider/plugin versus direct REST
Evaluate higher-level tools with four questions: Does the provider model your exact Nexus release and field? How quickly does it support new formats/security APIs? Does its state contain sensitive values? What does it do when a resource is changed manually or cannot update in place?
When coverage is incomplete, direct REST can be clearer than hidden escape hatches. Conversely, a mature provider can offer plan/state/graph behavior your script lacks.
8. Error and retry policy is part of design
Do not retry every error. Timeouts and selected 5xx responses may justify bounded backoff only when the operation can be retried safely. A 400 should fail fast; 403 triggers privilege diagnosis; 409 triggers a fresh GET and conflict analysis. If POST times out, GET the deterministic resource before POSTing again.
9. Concurrency and shared ownership
Two reconcilers can read the same old state and race. Use one automation owner per resource set, external locking or CI concurrency controls where appropriate, and fresh state reads immediately before destructive actions.
10. Worked decision table
| Scenario | Choice | Reason | Evidence |
|---|---|---|---|
| 20 similar internal Raw repos created monthly | Declarative reconciler | Repeated pattern and reviewable diff | No-op rerun + GET verification |
| Emergency one-time disable of a compromised proxy | Controlled imperative API call + incident record | Fast scoped response | Before/after GET + client denial |
| Provider lacks a new 3.95 field | Direct REST for that resource or wait | Avoid silently dropping required field | Swagger schema + integration test |
| Human edits automation-managed retention | Detect-only then reviewed reconciliation | Potentially destructive semantic change | Plan/diff + cleanup preview |
| CI only uploads packages | Scoped repository identity, not admin identity | Least privilege | 403 admin + successful upload |
11. Version lifecycle: schema tests before rollout
Before upgrading Nexus, capture current OpenAPI, run contract tests against the target version, compare used resource models, and test the reconciler on a disposable clone. An API client generated for 3.95.2 is part of the upgrade compatibility surface; Chapter 27 expands the full upgrade process.
12. Knowledge check
Why can delete-and-recreate be unsafe even when the final repository name matches?
Content, privileges, group references, client URLs, policies, and audit/recovery state can be affected.
Who should own a field automation deliberately ignores?
A documented human or another automation owner; otherwise it becomes unmanaged ambiguity.
A POST times out. What is safer than immediate retry?
GET the resource by deterministic identity to determine whether the first request committed.
Why might direct REST beat a provider for a newly added feature?
The provider may not yet model the current endpoint/field; direct REST can follow the local schema explicitly.
13. Summary and next step
Safe IaC is an operating model: explicit ownership, least-privilege identities, in-place updates, deterministic drift handling, bounded retries, version contract tests, and evidence. Lesson 4 deliberately breaks these assumptions so you can diagnose automation failures.
Official references and version notes
- Sonatype: Automation / REST API — OpenAPI/Swagger location, API integration, and Jetty 12 URL-encoding requirements.
- Sonatype: Nexus Repository API Reference — current endpoint catalog and request/response models.
- Sonatype: Repositories API — generic and format/type-specific repository configuration endpoints.
- Sonatype: Components API — component list/get/upload/delete behavior and continuation tokens.
- Sonatype: Pagination — continuation-token iteration contract.
- Sonatype: Security Management API — users, roles, privileges, content selectors, LDAP/SAML/OIDC boundaries.
- Sonatype: Authentication — local/external authentication and automation identity boundaries.
- Sonatype: User Tokens — current self-hosted Pro entitlement and token behavior.
- Sonatype: System Requirements — Java/database/storage baseline.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.