Skip to content

WIP: add Spring Boot extension - #10452

Draft
Weidong Xu (weidongxu-microsoft) wants to merge 46 commits into
Azure:mainfrom
weidongxu-microsoft:spring-init
Draft

Weidong Xu (weidongxu-microsoft) wants to merge 46 commits into
Azure:mainfrom
weidongxu-microsoft:spring-init

Conversation

@weidongxu-microsoft

@weidongxu-microsoft Weidong Xu (weidongxu-microsoft) commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Add azure.springboot and azd spring init for trusted, single-module Maven Spring Boot applications without an existing azure.yaml.
  • Infer active Spring profiles, datasource engine, and authentication from application configuration. Supported databases are in-memory, MySQL password, PostgreSQL password, and PostgreSQL managed identity.
  • Generate extension-owned azure.yaml, container build assets, Bicep, and database bootstrap hooks. Core azd is unchanged.
  • Include extension tests and independent Petclinic generation scenarios for MySQL password and PostgreSQL managed identity.

Validation

  • Extension tests, vet, build, initialization, and Bicep compilation passed.
  • Both independent generation scenarios pass locally against the pinned extension commit.
  • H2 and PostgreSQL password deployments passed live write/read and restart checks.
  • The extension-generated PostgreSQL managed-identity flow passed live deployment, Entra-only authentication, exact SQL grant checks, write/read, restart persistence, fresh-session verification, and credential non-disclosure checks. Disposable Azure resources were removed.

Deferred scope

  • MySQL managed identity, restrictive networking, Gradle, and multi-module projects.
  • Live MySQL password deployment validation; generation is covered.
  • Handling credentials already present in application-owned configuration or packaged resources remains under review.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@weidongxu-microsoft

Weidong Xu (weidongxu-microsoft) commented Oct 13, 2026 •

Copy link
Copy Markdown
Member Author

Inherited core behavior and current limitations

This extension reuses the published azd Go module v1.34.2; the links below pin that release's source.

  1. MySQL live provisioning is blocked. Core pins MySQL AVM 0.6.1. Initialization/compilation pass, but the live attempt fails ARM validation: Microsoft.KeyVault/vaults/dummyVault/keys/dummyKey is not defined. This PR does not replace that module or work around the failure.

  2. SQL generation adds Key Vault alongside ACA password secrets. Core already supplies the database password through an ACA secret, but also creates Key Vault to store an additional copy. The app reads the ACA secret-backed environment variable, not Key Vault. This is an inherited scaffold design choice: reusing the generator unchanged does not offer a vault-free MySQL/PostgreSQL configuration.

  3. Managed-identity database authentication is not supported by this init flow. The generated SQL setup uses administrator credentials and password authentication, as shown in the PostgreSQL parameters. Managed-identity database authentication remains follow-up work. Detected passwordless intent is rejected, not silently downgraded.

  4. Database network defaults allow all public IP addresses. The PostgreSQL firewall configuration uses an all-IP rule; MySQL has the same broad default. Restrictive firewall rules and private networking/DNS are separate follow-up work, independent of the database authentication method.

H2 and PostgreSQL passed full live write/read and restart checks; MySQL is not claimed as live-validated.

@github-actions github-actions Bot added the area/extensions Extensions (general) label Oct 13, 2026
Keep Spring Boot development status in the extension README, consistent with other extensions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

External credentials can be embedded in images, MySQL is knowingly undeployable, and configuration analysis has correctness gaps.

6 open findings
What changed in this PR

Adds the azure.springboot extension to initialize single-module Maven Spring Boot applications for azd deployment.

Changes:

  • Adds Spring configuration, profile, Maven, and datasource analysis.
  • Generates azure.yaml, Bicep infrastructure, and container assets.
  • Adds tests, documentation, and CI/release wiring.
File Description
eng/​pipelines/​release-ext-azure-springboot.yml Adds extension release pipeline.
cli/​azd/​extensions/​azure.springboot/​version.txt Sets initial version.
cli/​azd/​extensions/​azure.springboot/​README.md Documents usage, scope, and limitations.
cli/​azd/​extensions/​azure.springboot/​main.go Adds extension entry point.
internal/​spring/​profiles.go Parses Spring profile expressions.
internal/​spring/​profiles_test.go Tests profile expressions.
internal/​spring/​model.go Resolves and validates Maven metadata.
internal/​spring/​generation.go Generates deployment files and infrastructure.
internal/​spring/​generation_test.go Tests generation and safe writes.
internal/​spring/​configuration.go Resolves Spring configuration precedence.
internal/​spring/​analysis.go Infers application and datasource requirements.
internal/​spring/​analysis_test.go Tests application analysis.
internal/​cmd/​version.go Adds version command.
internal/​cmd/​root.go Defines command tree.
internal/​cmd/​metadata.go Adds extension metadata command.
internal/​cmd/​init.go Implements spring init.
internal/​cmd/​init_test.go Tests initialization preflight.
go.sum Records dependency checksums.
go.mod Defines the extension module.
extension.yaml Declares extension metadata.
cspell.yaml Configures extension spelling checks.
ci-test.ps1 Adds CI test script.
ci-build.ps1 Adds CI build script.
CHANGELOG.md Records the initial release.
build.sh Adds Unix cross-platform build script.
build.ps1 Adds PowerShell cross-platform build script.
.golangci.yaml Configures Go linting.
.gitignore Ignores Go build artifacts.
cli/​azd/​.vscode/​cspell.yaml Adds Spring terminology.
.github/​workflows/​lint-ext-azure-springboot.yml Adds GitHub lint workflow.
.github/​CODEOWNERS Assigns extension ownership.

🧠 Review effort: Balanced


💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

if err != nil {
return "", fmt.Errorf("encoding external configuration paths: %w", err)
}
fmt.Fprintf(&external, "COPY --from=build --chown=10001:10001 %s\n", paths)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Core context (azd v1.34.2): init --from-code generates project/tooling assets without rewriting Spring configuration. Core's Maven packaging also copies the built archive to staging without sanitizing embedded application configuration.

That is not a reason to dismiss this finding: our Dockerfile explicitly copies external configuration into the runtime image, and runtime overrides do not remove embedded credentials. Keeping this item open. Any fix should preserve the user's app source and address the generated deployment artifacts; we should not claim the entire application image is automatically sanitized.

Comment thread cli/azd/extensions/azure.springboot/internal/spring/model.go
Comment thread cli/azd/extensions/azure.springboot/internal/spring/analysis.go
Comment thread eng/pipelines/release-ext-azure-springboot.yml
Track the shared PR publishing stage and version-setting script in both main and PR triggers, matching existing extension pipelines.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace core project/scaffold composition with one parameterized template for embedded databases, MySQL password, PostgreSQL password, and PostgreSQL managed identity. Defer MySQL managed identity pending live configuration validation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…yment

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Preserve Spring template guidance alongside the stable account API documentation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread cli/azd/extensions/azure.springboot/internal/spring/analysis.go Outdated
Comment thread cli/azd/extensions/azure.springboot/internal/spring/analysis.go Outdated
Comment thread cli/azd/extensions/azure.springboot/internal/spring/configuration.go Outdated
Comment thread cli/azd/extensions/azure.springboot/internal/spring/configuration.go Outdated
Comment thread cli/azd/extensions/azure.springboot/internal/spring/generation.go
Comment thread cli/azd/extensions/azure.springboot/internal/spring/generation.go
Comment thread cli/azd/extensions/azure.springboot/internal/spring/generation.go Outdated
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep Spring documentation and spelling terms extension-local; revert feature additions under docs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Comment thread cli/azd/extensions/azure.springboot/internal/spring/generation.go Outdated
Comment thread cli/azd/extensions/azure.springboot/internal/spring/model.go Outdated
Comment thread cli/azd/extensions/azure.springboot/internal/spring/analysis.go Outdated
Comment thread cli/azd/extensions/azure.springboot/internal/spring/configuration.go Outdated
Comment thread cli/azd/extensions/azure.springboot/internal/spring/generation.go
@weidongxu-microsoft Weidong Xu (weidongxu-microsoft) changed the title WIP: add Spring Boot initialization extension WIP: add Spring Boot extension Oct 16, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved datasource detection and container binding issues can reject supported applications or produce nonworking deployments.

4 open findings
3 resolved since last review
Previously missed (1)

In code that hasn't changed since last review

Medium severity Check resolved runtime dependencies for JDBC drivers

cli/​azd/​extensions/​azure.springboot/​internal/​spring/​model.go:315

The effective POM lists declared/inherited dependencies, not the resolved transitive runtime graph. An otherwise supported application that receives its JDBC driver through a starter or shared library therefore fails the “no runtime JDBC driver” checks even though Maven packages that driver. Resolve the runtime dependency graph before checking driver availability, and cover a transitively supplied driver.

🧠 Review effort: Balanced

Comment thread cli/azd/extensions/azure.springboot/internal/spring/analysis.go Outdated
Comment thread cli/azd/extensions/azure.springboot/internal/spring/analysis.go
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 16, 2026 10:30
@weidongxu-microsoft

Copy link
Copy Markdown
Member Author

Also addressed the review-body finding about transitive JDBC drivers in 7bdcd71: Maven dependency:list now supplies the resolved compile/runtime graph to driver and packaged-dependency checks, with resolver coverage in 1ec0998.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Compiler selection needs correction, and privileged database bootstrap requires human review while integrated managed-identity validation remains incomplete.

2 open findings
3 resolved since last review

🧠 Review effort: Balanced

Comment thread cli/azd/extensions/azure.springboot/internal/spring/model.go
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 16, 2026 10:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Infrastructure and administrator-run SQL bootstrap need human review, with integrated managed-identity validation incomplete and a dependency-parsing defect unresolved.

1 open finding
1 resolved since last review
Previously missed (1)

In code that hasn't changed since last review

Medium severity Parse Maven dependency coordinates before module annotations

cli/​azd/​extensions/​azure.springboot/​internal/​spring/​model.go:446

Maven dependency:list can append Java module annotations such as :runtime -- module org.postgresql.jdbc [auto], including in its output file. The scope comparison below rejects that entire field, silently dropping the dependency. Applications whose JDBC driver is only transitive can then fail initialization because analysis reports the driver as missing. Parse the coordinate token before whitespace annotations, and add a regression covering module-decorated entries.

🧠 Review effort: Balanced

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 16, 2026 11:25
@weidongxu-microsoft

Copy link
Copy Markdown
Member Author

Addressed the review-body finding about module-decorated Maven dependency output in cbb01a4. The parser now isolates the coordinate token before scope validation, with parser and resolver regressions covering runtime -- module ... [auto] entries.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The generated infrastructure and SQL identity bootstrap need human review because integrated managed-identity deployment validation remains incomplete.

1 open finding
Previously missed (1)

In code that hasn't changed since last review

Low severity Update PR description to reflect templates and managed identity implementation

cli/​azd/​extensions/​azure.springboot/​internal/​spring/​generation.go:46

The PR description still says generation reuses core serialization/Bicep APIs and managed identity is out of scope, but this implementation owns the templates and generates PostgreSQL managed-identity hooks. Its MySQL validation note also describes the replaced core scaffold. Update Summary, Validation, and WIP to match the implementation and README, including the incomplete integrated managed-identity validation, so reviewers see the actual scope.

🧠 Review effort: Balanced

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 16, 2026 17:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Datasource validation and Maven configuration inference still allow incorrect deployment bindings and failing container builds.

4 open findings
Previously missed (1)

In code that hasn't changed since last review

Medium severity Match excluded datasource auto-configuration classes individually

cli/​azd/​extensions/​azure.springboot/​internal/​spring/​analysis.go:280

This substring also matches JndiDataSourceAutoConfiguration and XADataSourceAutoConfiguration. Excluding either leaves ordinary datasource auto-configuration enabled, but a supported app with a JDBC URL is rejected here as invalid. Match individual excluded class names instead, and add regressions for these independent exclusions.

🧠 Review effort: Balanced

Comment thread cli/azd/extensions/azure.springboot/internal/spring/analysis.go
Comment thread cli/azd/extensions/azure.springboot/internal/spring/model.go
Comment thread cli/azd/extensions/azure.springboot/internal/spring/model.go Outdated
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 16, 2026 17:47
@weidongxu-microsoft

Copy link
Copy Markdown
Member Author

Addressed the latest review findings in 3a85a0bd4:

  • Reject DBCP2 URL, username, password, and driver overrides, including explicitly empty values.
  • Skip Maven test compilation and execution in deployment image builds with maven.test.skip=true; a main Java 17/test Java 21 regression confirms the production image remains on Java 17.
  • Honor spring-boot.repackage.skip when plugin and execution settings are unspecified, while preserving explicit plugin/execution precedence.
  • Match only the exact DataSourceAutoConfiguration exclusion, preserving JNDI- and XA-only exclusions.
  • Update the PR description to reflect extension-owned templates and completed PostgreSQL managed-identity live validation.

The application-owned credential-retention thread remains open for a separate scope decision.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

`(?:[^{};@]|@[\w.$]+(?:\s*\([^()]*\))?)*?\b(?:DataSource|ConnectionFactory|HikariDataSource|` +
`DriverManagerDataSource|BasicDataSource|PoolDataSource)\s+[\w$]+\s*\(` +
`|new\s+(?:[\w$]+\.)*(?:HikariDataSource|DriverManagerDataSource|BasicDataSource|PoolDataSource)\s*\(`)
var runtimeActivation = regexp.MustCompile(`\.(?:setAdditionalProfiles|setActiveProfiles|setDefaultProfiles)\s*\(`)
if err != nil {
return nil, err
}
port, err := c.integer("server.port", 8080)
if err != nil {
return nil, err
}
port, err := c.integer("server.port", 8080)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/extensions Extensions (general)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants