Infrastructure as Code for the Agentic Cloud: AWS-First and Multi-Cloud Patterns
Infrastructure as Code for the Agentic Cloud
How infrastructure strategy changes when moving from AWS-first to multi-cloud agent platforms
Infrastructure as Code has traditionally been concerned with relatively predictable things: networks, compute, storage, databases, identity, queues and deployment pipelines.
Agentic systems change the shape of that infrastructure.
An AI agent is not simply another workload running in a container. Production agents increasingly require a collection of capabilities around them: runtime isolation, model access, memory, tool connectivity, workload identity, policy enforcement, evaluation, tracing and sometimes communication with other agents.
Cloud providers are responding by building increasingly complete agent platforms.
AWS has Amazon Bedrock AgentCore. Microsoft has Foundry Agent Service. Google has been evolving its managed agent capabilities around its Gemini and Vertex AI platforms.
This raises an important infrastructure question:
If agents become a significant part of the application architecture, what should Infrastructure as Code look like?
The answer is quite different depending on whether you are committed primarily to AWS or genuinely expect to operate across AWS, Azure and Google Cloud.
Agents Change What We Mean by Infrastructure
Consider a conventional cloud application:
Application
│
├── Compute
├── Database
├── Queue
├── Storage
└── Observability
A production agent increasingly looks more like:
Agent
│
├── Runtime
├── Model
├── Memory
├── Tools
├── Identity
├── Policy
├── Guardrails
├── Evaluation
└── Observability
This means Infrastructure as Code needs to evolve beyond provisioning infrastructure.
For an agent platform, several forms of as code start working together:
Infrastructure as Code
│
├── Runtime
├── Network
├── Storage
└── Compute
Identity & Policy as Code
│
├── IAM
├── Tool permissions
└── Business authorization
Agent as Code
│
├── Orchestration
├── Tools
└── Skills
Prompts as Code
Evaluation as Code
Observability as Code
The infrastructure repository is becoming part of the Agent SDLC.
Scenario One: AWS Is Your Cloud
Suppose AWS is overwhelmingly your strategic cloud platform and you expect to build agents with Strands Agents and Amazon Bedrock AgentCore.
In that situation, I would optimize for AWS rather than prematurely designing for portability.
My preferred stack would look something like:
AWS Organizations
│
AWS Control Tower
│
Enterprise Landing Zone
│
Terraform / OpenTofu
or existing enterprise IaC
│
─────────────────────────
│
AWS CDK + TypeScript
│
Enterprise Constructs
│
Agent Platform Constructs
│
Amazon Bedrock AgentCore
│
Strands Agents
│
Amazon Bedrock
There is an important distinction here.
Terraform may still be the right choice for the enterprise AWS foundation:
Organizations
Accounts
Organizational Units
SCPs
Network foundations
DNS
Security accounts
Logging
Shared services
But for application and agent infrastructure I would seriously favour AWS CDK using TypeScript.
The closer you get to AgentCore, the more valuable AWS-native abstractions become.
AgentCore's deployment tooling itself makes extensive use of AWS CDK, which is an important architectural signal: AWS is treating CDK and CloudFormation as native deployment substrates for these capabilities.
CDK Constructs Become Your Agent Platform API
The most powerful feature of CDK in this environment isn't simply that TypeScript is nicer than YAML.
It is constructs.
Instead of every agent team creating raw resources, a central platform team could expose:
@company/aws-platform
SecureBucket
ServiceApi
EventConsumer
StandardLambda
StandardContainer
and then:
@company/agent-platform
EnterpriseAgent
AgentRuntime
AgentGateway
AgentTool
AgentMemory
AgentIdentity
AgentPolicy
AgentEvaluator
The developer experience could eventually look conceptually like:
new EnterpriseAgent(this, "AccountServicingAgent", {
framework: "strands",
model: {
capability: "reasoning-large"
},
tools: [
accountQuery,
payments,
customerProfile
],
memory: {
enabled: true
},
policy: {
source: "./policies"
},
evaluation: {
source: "./evals"
},
observability: {
enabled: true
}
});
The construct could provision or configure everything required around the agent:
EnterpriseAgent
│
├── AgentCore Runtime
├── Runtime Endpoint
├── Gateway
├── Memory
├── Identity
├── Policy Engine
├── Evaluators
├── IAM
├── KMS
└── Observability
That becomes a powerful internal golden path.
Treat the Tool Boundary as Infrastructure
One of the biggest architectural changes with agents is that the boundary between an agent and its tools becomes critical infrastructure.
An unsafe architecture looks like:
Agent
│
└──────────────► Enterprise systems
broad credentials
A better pattern is:
Agent
│
▼
Agent Gateway
│
├── Identity
├── Authorization
├── Policy
├── Audit
└── Tool contracts
│
▼
Enterprise APIs
AgentCore Gateway can expose tools to agents using MCP, while AgentCore Policy can enforce deterministic authorization at the gateway boundary.
This matters because authorization should not depend on an LLM deciding to follow a prompt.
You don't want this to be your security control:
System prompt:
"Never refund more than $1,000."
You want:
Agent
│
▼
refund($20,000)
│
▼
Policy Engine
│
▼
amount <= $1,000 ?
│
└── NO → DENY
Policy therefore belongs alongside your infrastructure:
agent/
├── src/
├── tools/
├── prompts/
├── skills/
├── policies/
│ ├── accounts.cedar
│ └── payments.cedar
├── evals/
└── infra/
Agent infrastructure is therefore not simply where does my process run?
It defines what the agent is allowed to do.
Evaluation Should Be Part of Deployment
Traditional IaC asks:
Did the infrastructure deploy successfully?
Agent infrastructure needs another question:
Does the agent still behave correctly after the deployment?
A mature pipeline begins to look like:
Commit
│
▼
Static analysis
│
▼
Unit tests
│
▼
CDK synth
│
▼
Policy tests
│
▼
Deploy ephemeral environment
│
▼
Agent evaluations
│
├── task completion
├── tool selection
├── policy compliance
├── safety
└── regression
│
▼
Deploy
Evaluation definitions should increasingly become deployable platform assets just like alarms or dashboards.
Observability Should Be Automatic
Agent observability is richer than conventional application logging.
A useful trace might look like:
agent.run
│
├── model.invoke
│
├── memory.read
│
├── tool.select
│
├── policy.evaluate
│
├── tool.invoke
│
├── model.invoke
│
└── evaluation
AgentCore and Strands both align well with OpenTelemetry-based instrumentation.
An EnterpriseAgent construct should therefore configure
observability automatically.
Developers shouldn't have to remember it.
The AWS-Only Architecture
The resulting AWS architecture might look like:
┌─────────────────────────────────────────────┐
│ Agent Products │
│ │
│ Strands-based applications │
└─────────────────────┬───────────────────────┘
│
┌─────────────────────▼───────────────────────┐
│ Enterprise Agent Constructs │
│ │
│ Runtime │ Tool │ Memory │ Policy │ Eval │
└─────────────────────┬───────────────────────┘
│
┌─────────────────────▼───────────────────────┐
│ Amazon Bedrock AgentCore │
│ │
│ Runtime Gateway Memory │
│ Identity Policy Evaluations │
│ Observability │
└─────────────────────┬───────────────────────┘
│
┌─────────────────────▼───────────────────────┐
│ AWS Platform │
│ │
│ Bedrock │ IAM │ KMS │ S3 │ SQS │ DynamoDB │
│ EventBridge │ Lambda │ VPC │ CloudWatch │
└─────────────────────────────────────────────┘
AWS is the platform. AgentCore is an architectural choice. CDK is a productive mechanism for packaging those capabilities.
Trying to make this portable before you actually need portability adds abstractions without necessarily creating value.
Then Someone Says: “We Also Need Azure and GCP”
This changes the problem significantly.
Suppose AWS remains the dominant provider, but business units may deploy workloads into Azure or Google Cloud.
Perhaps different geographic regions have different cloud strategies. Perhaps you acquire companies with different cloud estates. Perhaps a particular AI model or managed service is attractive on another provider.
Or perhaps avoiding excessive dependence on a single AI platform is itself a strategic objective.
At that point I would not simply extend the AWS CDK model to every cloud.
The architecture needs another layer.
The Multi-Cloud Rule: Abstract Capabilities, Not Resources
A common multi-cloud mistake is attempting to create an imaginary generic cloud:
Generic Cloud
│
┌───────────┴───────────┐
│ │
AWS S3 Azure Blob
│ │
└──── "Storage" ────────┘
Keep repeating this and eventually you end up with a platform exposing only the features that all three clouds have in common.
You have built the lowest common denominator cloud.
Agents make this particularly problematic because the managed platforms are meaningfully different.
| Capability | AWS | Microsoft Azure | Google Cloud |
|---|---|---|---|
| Managed agent platform | Bedrock AgentCore | Foundry Agent Service | Gemini / Vertex AI agent platform |
| Model platform | Bedrock | Foundry Models | Vertex AI / Model Garden |
| Identity | IAM / AgentCore Identity | Entra / Managed Identity | IAM / Workload Identity |
| Secret store | Secrets Manager | Key Vault | Secret Manager |
| Object storage | S3 | Blob Storage | Cloud Storage |
| Messaging | SQS / EventBridge | Service Bus / Event Grid | Pub/Sub / Eventarc |
| Observability | CloudWatch | Azure Monitor / Application Insights | Cloud Observability |
| Native IaC | CDK / CloudFormation | Bicep | Terraform / APIs |
These aren't simply three implementations of the same API.
And that is a good thing.
Terraform Becomes Much More Attractive
Once infrastructure genuinely spans AWS, Azure and GCP, my IaC recommendation changes.
Make Terraform or OpenTofu the enterprise-level declarative infrastructure control plane.
The architecture becomes:
Platform Engineering
│
Terraform / OpenTofu
│
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
AWS Azure GCP
│ │ │
AWS modules Azure modules GCP modules
│ │ │
▼ ▼ ▼
AgentCore Foundry Agent Platform
The benefit isn't that Terraform magically makes cloud services equivalent.
It gives platform engineering teams a common lifecycle, policy and delivery mechanism.
But Don't Ban Native IaC
A multi-cloud Terraform strategy should not become:
Everything must be represented directly in Terraform no matter how awkward it is.
I would allow:
Terraform / OpenTofu
│
├── AWS
│ └── CDK / CloudFormation where appropriate
│
├── Azure
│ └── Bicep / native APIs where appropriate
│
└── GCP
└── native APIs where appropriate
AgentCore is a good example.
Its deployment model has a natural relationship with CDK:
AgentCore tooling
│
▼
AWS CDK
│
▼
CloudFormation
│
▼
AWS
There is little value in fighting that purely in the name of tool standardization.
Bad:
Terraform creates IAM role
CDK modifies IAM role
Terraform creates Gateway
CLI modifies Gateway
someone manually creates Policy
Good:
Terraform owns:
AWS account
network
shared platform
cross-cloud integration
CDK owns:
AgentCore application boundary
Ownership boundaries matter more than having exactly one syntax.
Move the Abstraction Above IaC
This is the most important architectural change when moving to multi-cloud.
In an AWS-only environment:
CDK Constructs
≈
Platform API
In a mature multi-cloud environment:
Agent Platform API
│
├── AWS implementation
├── Azure implementation
└── GCP implementation
becomes the platform API.
Terraform, CDK and Bicep move underneath it.
Developers should increasingly describe intent:
kind: Agent
metadata:
name: account-servicing
spec:
runtime:
provider: aws
model:
capability: reasoning-large
memory:
retention: 30d
tools:
- account-query
- payments
policy:
profile: customer-servicing
evaluation:
profile: production
observability:
profile: standard
The control plane determines how to implement that intent.
Developer
│
▼
Agent Platform API
│
├── createAgent
├── attachTool
├── attachMemory
├── attachPolicy
├── attachModel
└── deploy
│
▼
Platform Control Plane
│
├────────────┬────────────┐
▼ ▼ ▼
AWS Azure GCP
This is the right level of abstraction.
Standardize Protocols Rather Than Cloud Services
Portability becomes much easier if the contracts between components are open.
I would strongly favour an architecture built around:
Agent ↔ Agent A2A
Agent ↔ Tool MCP
Service ↔ Service HTTP / OpenAPI
Identity OAuth2 / OIDC
Telemetry OpenTelemetry
Strands is useful here because it provides an agent framework while supporting model-provider abstraction, MCP, A2A and OpenTelemetry.
That enables architectures such as:
AWS Agent
│
│ A2A
▼
Azure Agent
│
│ MCP
▼
Enterprise Tool
│
│ HTTP
▼
GCP-hosted service
This is real portability.
Making S3 and Azure Blob Storage share an artificial API is far less strategically valuable.
Separate the Agent from the Model
Another important multi-cloud principle is:
Where the agent executes and where the model executes do not necessarily need to be the same decision.
Think:
Agent Runtime
│
▼
Model Gateway
│
├── Bedrock
├── Microsoft Foundry
├── Google Vertex AI
└── other providers
The application might ask for:
reasoning-large
reasoning-fast
vision
embedding
low-cost-classifier
instead of embedding model identifiers everywhere.
The routing layer can then consider:
Quality
Cost
Latency
Region
Data classification
Availability
Capacity
Regulation
Fallback
Notice what we are abstracting here.
We are abstracting model intent.
We are not pretending every model is identical.
Identity Becomes a First-Class Multi-Cloud Capability
Identity is relatively straightforward when everything lives within one AWS boundary:
Agent
│
▼
IAM Role
│
▼
AWS Service
It becomes harder when:
AWS Agent
│
▼
Azure API
Azure Agent
│
▼
GCP Service
GCP Agent
│
▼
AWS Resource
Long-lived credentials should not become the solution.
A mature architecture should build around:
OIDC
OAuth2
Workload identity federation
Short-lived credentials
Per-agent identities
User delegation
The enterprise platform should therefore expose something conceptually like:
AgentIdentity
rather than expecting every product team to invent its own cross-cloud credential strategy.
Policy Must Sit Above Cloud IAM
IAM remains essential.
But AWS IAM, Azure RBAC and Google Cloud IAM are infrastructure authorization systems.
Agent authorization often needs to express a different question:
May this agent perform this business operation on this object, for this user, under these conditions?
For example:
CustomerServiceAgent
readAccount
ALLOW
changeAddress
ALLOW
transferMoney(500)
ALLOW
transferMoney(50,000)
DENY
That policy should ideally behave consistently regardless of whether the agent happens to execute on AWS, Azure or GCP.
Agent
│
▼
Tool Gateway
│
▼
Agent Authorization
│
┌────────┼────────┐
▼ ▼ ▼
AWS Azure GCP
IAM RBAC IAM
Cloud IAM remains the last line of enforcement.
But it shouldn't have to encode every piece of business authorization logic.
Make OpenTelemetry the Observability Contract
Cloud-native observability remains useful.
AWS has CloudWatch. Azure has Azure Monitor and Application Insights. Google has Cloud Observability.
But agent instrumentation should not depend on any one of them.
Agent
│
▼
OpenTelemetry
│
├── CloudWatch
├── Application Insights
├── Google Cloud Observability
└── Enterprise observability platform
Define a common semantic model:
agent.run
model.invoke
tool.select
tool.invoke
agent.delegate
policy.evaluate
memory.read
memory.write
evaluation.run
This is precisely the kind of layer that should be standardized.
Containers Become Another Useful Portability Boundary
There is also a more mundane but powerful portability mechanism:
OCI Container
Containers don't make managed agent platforms equivalent.
They do, however, give you a useful packaging boundary:
Agent source
│
▼
OCI image
│
┌──┼──────────────┐
▼ ▼ ▼
AWS Azure GCP
Combined with Strands, MCP, A2A, OIDC and OpenTelemetry, this provides several practical escape hatches without forcing a lowest-common-denominator platform.
Don't Confuse Portability with Symmetry
A multi-cloud architecture does not require:
AWS capability
=
Azure capability
=
GCP capability
A better model is:
Enterprise Capability
AgentRuntime
│
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
AWS optimized Azure optimized GCP optimized
implementation implementation implementation
The contract says:
Give me a managed agent runtime meeting these enterprise requirements.
The implementation can still use the best available cloud-native capability.
That distinction prevents multi-cloud strategy becoming multi-cloud mediocrity.
The Architecture I Would Build
Putting everything together gives us three major layers.
┌─────────────────────────────────────────────────────────┐
│ Agent Applications │
│ │
│ Strands / other frameworks │
└───────────────────────────┬─────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Enterprise Agent SDK │
│ │
│ Agent │ Tool │ Model │ Memory │ Policy │ Evaluation │
└───────────────────────────┬─────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Agent Platform API │
│ │
│ Deployment Identity Policy │
│ Model routing Registry Evaluation │
│ Observability Secrets Governance │
└───────────────┬──────────────┬──────────────┬───────────┘
│ │ │
▼ ▼ ▼
AWS Adapter Azure Adapter GCP Adapter
│ │ │
▼ ▼ ▼
AgentCore Foundry Agent Platform
───────────────────────────────────────────────────────────
Terraform / OpenTofu Control Plane
───────────────────────────────────────────────────────────
AWS Azure Google Cloud
───────────────────────────────────────────────────────────
Enterprise Landing Zones
Notice where Terraform sits.
It is important.
But it isn't the developer abstraction.
The Agent Platform API is the abstraction.
Terraform, OpenTofu or Pulumi?
For a large enterprise, Terraform remains the conservative default for a multi-cloud control plane because of its provider model, ecosystem and widespread platform-engineering adoption.
OpenTofu deserves consideration where its open-source governance and licensing model better fit organizational strategy.
Pulumi is also interesting for this particular problem because agent platforms increasingly involve sophisticated abstractions, and defining those abstractions in TypeScript, Python or Go can be attractive.
I would therefore think about the decision like this:
Single-cloud AWS
CDK
│
▼
Agent Constructs
│
▼
AgentCore
versus:
Multi-cloud
Agent Platform API
│
Terraform/OpenTofu
│
┌────────┼────────┐
▼ ▼ ▼
AWS Azure GCP
│ │ │
CDK Bicep Native
where where where
useful useful useful
These aren't contradictory architectures.
They are two different levels of abstraction.
What About Agents Managing Infrastructure?
There is one additional consideration that becomes increasingly important as agent adoption grows.
Agents will themselves start writing and modifying Infrastructure as Code.
The wrong pattern is:
Infrastructure Agent
│
▼
cloud administrator credentials
│
▼
Production
The better model is:
Agent
│
▼
Generate IaC change
│
▼
Pull Request
│
▼
Plan / Synth
│
▼
Policy checks
│
▼
Automated tests
│
▼
Risk classification
│
├── low risk ─────► automated approval
│
└── high risk ────► human approval
│
▼
Deploy
This gives you a clean separation between reasoning authority and execution authority.
As agents become more capable, that distinction becomes increasingly important.
Start AWS-Native, but Design the Seams
There is also a pragmatic middle ground.
You may be AWS-only today while recognizing that multi-cloud is possible in the future.
I would not build the entire multi-cloud control plane in anticipation.
Instead, design the seams:
Agent
│
├── Model Provider interface
│
├── MCP tool interface
│
├── A2A agent interface
│
├── OIDC identity boundary
│
├── OpenTelemetry
│
└── OCI packaging
But deploy:
AWS CDK
│
▼
AgentCore
today.
This gives you:
Native optimization now
+
Architectural optionality later
without paying the complexity cost of multi-cloud before it creates business value.
The Principle to Remember
If I had to reduce the architecture to two rules, they would be these.
For an AWS-centric organization
Use AWS-native capabilities aggressively. Treat reusable CDK agent constructs as your internal platform API.
For an organization genuinely operating across clouds
Move the abstraction upward. Standardize agent capabilities, protocols, identity, telemetry and policy — not individual cloud resources.
That gives us the progression:
Stage 1
Infrastructure as Code
│
▼
Cloud resources
Stage 2
Platform as Code
│
▼
Reusable cloud capabilities
Stage 3
Agent Platform as Code
│
▼
Agents
Models
Tools
Identity
Memory
Policy
Evaluation
Observability
And ultimately:
Developer Intent
│
▼
Agent Platform
│
├── AWS
├── Azure
└── GCP
That is where Infrastructure as Code is heading for agentic systems.
Not toward a universal abstraction that pretends every cloud is the same.
But toward an intent-driven agent platform that gives developers a consistent operating model while deliberately preserving the differentiated capabilities of each cloud.
That difference is subtle, but it is the difference between building a multi-cloud platform and merely building another abstraction layer.
Further Reading
- AWS — Amazon Bedrock AgentCore Runtime
- AWS — AgentCore Policy concepts
- AWS — AgentCore Evaluations
- AWS — CDK best practices
- Strands Agents
- Microsoft — Foundry Agent Service
- Microsoft — Terraform and Bicep
- Google Cloud — Agent development platform
- Google Cloud — Terraform on Google Cloud
- OpenTelemetry
- Model Context Protocol
- Agent2Agent Protocol
Comments