feat: support connector MCP target configuration for GatewayTarget - #40
feat: support connector MCP target configuration for GatewayTarget#40AlJohri wants to merge 4 commits into
Conversation
Adds the managed `connector` MCP target type to GatewayTarget, enabling declarative provisioning of AWS-managed gateway connectors (e.g. the web search tool). Previously the only `mcp` target types exposed were apiGateway, lambda, mcpServer, openAPISchema and smithyModel, because the Connector shape introduced in aws_service_sdk_version v1.47.0 was ignored. The connector's per-tool `parameterValues` is a smithy document (arbitrary JSON) with no direct CRD representation, so it is exposed as a JSON string and marshaled/unmarshaled in hooks -- mirroring how the lambda tool schema InputSchema/OutputSchema fields are handled. The API requires parameterValues on every connector configuration (an omitted value is rejected with "Connector configurations must not be empty"), so it cannot be dropped. - generator.yaml: un-ignore McpTargetConfiguration.Connector; ignore the document-typed ConnectorConfiguration.ParameterValues and re-add it as a JSON string; mark the Configurations slice compare-ignored and preserve it from Spec across create/update responses. - hooks: marshal the ParameterValues JSON string to a document on create/update input, unmarshal it back on read, and compare configurations semantically (ignoring key ordering / whitespace) in delta_pre_compare. - e2e: add a web search connector GatewayTarget test and grant the gateway bootstrap role BedrockAgentCoreFullAccess so it can invoke the connector. - unit tests for the ParameterValues round trip and semantic comparison. Signed-off-by: Al Johri <al.johri@gmail.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: AlJohri The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Hi @AlJohri. Thanks for your PR. I'm waiting for a aws-controllers-k8s member to verify that this patch is reasonable to test. If it is, they should reply with Tip We noticed you've done this a few times! Consider joining the org to skip this step and gain Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
CreateGatewayTarget requires ParameterValues on every connector configuration
and rejects a missing/empty document with:
ValidationException: Connector configurations must not be empty
setConnectorParameterValuesOnInput previously passed the CR's ParameterValues
straight through stringToDocument, which returns a nil document for an omitted
or empty string. The nil then reached the API and failed create, even though
delta_pre_compare already treats an absent value and "{}" as equal — so the
read/diff path tolerated empty while the create path broke on it.
Default a nil (omitted/empty) ParameterValues to an empty JSON object on the
create/update input so a connector target that needs no parameters can be
declared without spelling out `parameterValues: "{}"`, keeping the input path
consistent with the comparison logic. stringToDocument stays pure (still returns
nil for nil/empty) so the JSON round-trip semantics are unchanged.
…ough The connector target this PR enables is reached through a Gateway that carries a GATEWAY_IAM_ROLE service role. Creating that Gateway requires the controller to iam:PassRole the service role to bedrock-agentcore.amazonaws.com (and to iam:GetRole it), neither of which is covered by the recommended managed policy (arn:aws:iam::aws:policy/BedrockAgentCoreFullAccess). Without them, CreateGateway fails with an AccessDenied on iam:PassRole. This is not caught by the e2e suite because the test controller runs with a broad CI identity that already allows PassRole; a real deployment attaching only the recommended managed policy does not, so the connector flow is unusable out of the box. Add a recommended inline policy (attached alongside the managed policy) granting iam:GetRole and iam:PassRole, the latter scoped by the iam:PassedToService condition to bedrock-agentcore.amazonaws.com so the role can only be handed to the AgentCore service. Operators can further restrict Resource to their gateway service-role path (e.g. arn:aws:iam::<account>:role/ack/*).
Capture the operational details that are easy to get wrong when provisioning the
managed web-search connector, none of which are obvious from the CRD alone:
- us-east-1 only (both Gateway and GatewayTarget).
- the controller needs iam:PassRole/GetRole for the gateway service role
(config/iam/recommended-inline-policy), on top of BedrockAgentCoreFullAccess.
- parameterValues is optional and defaults to "{}".
- the caller's role must grant bedrock-agentcore:InvokeWebSearch on
arn:aws:bedrock-agentcore:us-east-1:aws:tool/web-search.v1 via an INLINE
policy — the "aws" literal in the account-id field trips IAM's managed-policy
legacy parser ("MalformedPolicyDocument: failed legacy parsing").
Adds the repo's first examples/ manifest so this guidance lives next to a
ready-to-adapt resource.
Issue #, if available: aws-controllers-k8s/community#2958
Description of changes
Adds the managed
connectorMCP target type toGatewayTarget, soAWS-managed gateway connectors — notably the web search tool — can be
provisioned declaratively. Until now the only
mcptarget types exposed wereapiGateway,lambda,mcpServer,openAPISchemaandsmithyModel; theConnectorshape introduced inaws_service_sdk_versionv1.47.0 was ignored.parameterValuesis a document type — and it's requiredConnectorConfiguration.ParameterValuesis a smithy document (arbitrary JSON)with no direct CRD representation. It cannot simply be dropped: the API
requires it on every connector configuration — omitting it fails with
ValidationException: Connector configurations must not be empty.So it is exposed as a JSON string and marshaled/unmarshaled in hooks,
mirroring how the lambda tool-schema
InputSchema/OutputSchemadocumentfields are already handled in this controller:
generator.yaml: un-ignoreMcpTargetConfiguration.Connector; ignore thedocument-typed
ConnectorConfiguration.ParameterValuesand re-add it as astring; mark theConfigurationsslicecompare: is_ignoredand preserveit from
Specacross create/update responses (set: ignore from+ a*_post_set_outputrestore) so the user's JSON string is not stripped.parameterValuesJSON string to a document oncreate/update input (
document.NewLazyDocument), serialize it back on read(
MarshalSmithyDocument), and compare configurations semantically (ignoringkey ordering / whitespace, treating omitted-vs-
{}as equal) indelta_pre_compare.parameterValuesround trip and semantic comparison.GatewayTargettest (create +parameterValuesupdate), and
BedrockAgentCoreFullAccessadded to the bootstrap gateway roleso it can invoke the connector. The managed web search connector is
us-east-1 only.
Validation
Regenerated with code-generator/runtime v0.61.0 (baseline reproduces v1.11.0
byte-for-byte aside from the metadata build block).
go build ./...,go test ./..., andgo vetpass.Validated end-to-end against live AWS on a kind cluster: a web-search connector
GatewayTargetreconciles toACK.ResourceSynced=Truewith the AWS targetREADY; theparameterValuesJSON string round-trips ontoSpec(notstripped); reconciliation is stable (no update loop); and patching
parameterValuesto a{"domainFilter":{"exclude":[...]}}denylist updatescleanly and is reflected in AWS.
By submitting this pull request, I confirm that my contribution is made under
the terms of the Apache 2.0 license.