Skip to content

Commit a8e531f

Browse files
committed
✨ Introduce new Bedrock AI pages and sitemap
- Added Advanced.razor and Index.razor for Bedrock AI. - Updated sitemap.xml to reflect new content structure. - Enhanced navigation for improved user experience. Generated by Copilot
1 parent 9720a80 commit a8e531f

File tree

4 files changed

+224
-146
lines changed

4 files changed

+224
-146
lines changed
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
2+
@page "/blog/ai/bedrock/advanced"
3+
@using TestArena.Blog.Common
4+
@using TestArena.Blog
5+
@using System.Linq
6+
@using TestArena.Blog.Common.NavigationUtils
7+
8+
@code{
9+
PageInfo currentPage = SiteMap.Pages.FirstOrDefault(x => x.RelativePath == "/blog/ai/bedrock/advanced")!;
10+
}
11+
12+
<BlogContainer>
13+
<Header Title="@currentPage.Header"
14+
Image="@currentPage.ArticleImage"
15+
PublishedOn="@currentPage.PublishedOn"
16+
Authors="Ajay Kumar"
17+
isOlderThumbnailFormat="@currentPage.IsOlderThumbnailFormat">
18+
</Header>
19+
20+
<CalloutBox Type="info" Title="Looking for the basics?">
21+
<p>Start with <a href="/blog/ai/bedrock">Getting Started with AWS Bedrock in .NET</a> for the simplest setup and usage.</p>
22+
</CalloutBox>
23+
24+
<Section Heading="Advanced Authentication & Production Setup" Level="4">
25+
<Section Heading="Session Credentials (Local Development)" Level="5">
26+
<p>Use this for quick local testing with temporary credentials (e.g., from AWS STS or temporary session tokens).</p>
27+
<CodeSnippet Language="csharp" Number="2">
28+
SessionAWSCredentials GetCredentials()
29+
{
30+
// ⚠️ NEVER hardcode credentials in production!
31+
string accessKey = "&lt;your-access-key&gt;";
32+
string secretKey = "&lt;your-secret-key&gt;";
33+
string sessionToken = "&lt;your-session-token&gt;";
34+
return new SessionAWSCredentials(accessKey, secretKey, sessionToken);
35+
}
36+
</CodeSnippet>
37+
<CalloutBox Type="warning" Title="Security Warning">
38+
<p>Session credentials are temporary and should never be hardcoded. Use them only during development with test accounts.</p>
39+
</CalloutBox>
40+
</Section>
41+
42+
<Section Heading="IAM User Credentials (Not Recommended for Production)" Level="5">
43+
<p>Use static IAM user credentials for simple scenarios, but this method is less secure for production.</p>
44+
<CodeSnippet Language="csharp" Number="3">
45+
BasicAWSCredentials GetBasicCredentials()
46+
{
47+
string accessKey = Environment.GetEnvironmentVariable("AWS_ACCESS_KEY_ID");
48+
string secretKey = Environment.GetEnvironmentVariable("AWS_SECRET_ACCESS_KEY");
49+
50+
if (string.IsNullOrWhiteSpace(accessKey) || string.IsNullOrWhiteSpace(secretKey))
51+
throw new InvalidOperationException("AWS credentials not found in environment variables.");
52+
53+
return new BasicAWSCredentials(accessKey, secretKey);
54+
}
55+
</CodeSnippet>
56+
<CalloutBox Type="tip" Title="Environment Variables">
57+
<p>Store credentials in environment variables, not in appsettings files or source code. Use <code>AWS_ACCESS_KEY_ID</code> and <code>AWS_SECRET_ACCESS_KEY</code>.</p>
58+
</CalloutBox>
59+
</Section>
60+
61+
<Section Heading="EC2 Instance Profile Role (Production on EC2)" Level="5">
62+
<p>
63+
This is the <b>recommended approach for production applications running on EC2</b>. The SDK automatically retrieves credentials from the instance metadata without any code changes.
64+
</p>
65+
<CodeSnippet Language="csharp" Number="4">
66+
// No credentials needed! The SDK automatically uses the EC2 instance role.
67+
var bedrockClient = new AmazonBedrockClient(RegionEndpoint.USEast1);
68+
var runtimeClient = new AmazonBedrockRuntimeClient(RegionEndpoint.USEast1);
69+
</CodeSnippet>
70+
</Section>
71+
72+
<Section Heading="Creating the EC2 Instance Profile Role" Level="5">
73+
<p>
74+
To create an EC2 instance profile role with the minimal permissions needed to list models and invoke them:
75+
</p>
76+
<p><b>Step 1: Create an IAM Role</b></p>
77+
<ol>
78+
<li>Go to IAM console → Roles → Create Role</li>
79+
<li>Select "AWS service" → "EC2" as the trusted entity</li>
80+
<li>Click "Create Role"</li>
81+
</ol>
82+
<p><b>Step 2: Add Inline Policy with Required Permissions</b></p>
83+
<p>Once the role is created, add this inline policy to grant Bedrock permissions:</p>
84+
<CodeSnippet Language="json" Number="7">
85+
{
86+
"Version": "2012-10-17",
87+
"Statement": [
88+
{
89+
"Effect": "Allow",
90+
"Action": [
91+
"bedrock:ListFoundationModels",
92+
"bedrock:GetFoundationModel"
93+
],
94+
"Resource": "*"
95+
},
96+
{
97+
"Effect": "Allow",
98+
"Action": [
99+
"bedrock:InvokeModel",
100+
"bedrock:InvokeModelWithResponseStream"
101+
],
102+
"Resource": "arn:aws:bedrock:*:*:foundation-model/*"
103+
}
104+
]
105+
}
106+
</CodeSnippet>
107+
<p><b>Step 3: Attach the Role to Your EC2 Instance</b></p>
108+
<ol>
109+
<li>Go to EC2 console → Instances → Select your instance</li>
110+
<li>Right-click → Security → Modify IAM role</li>
111+
<li>Select the role you created</li>
112+
<li>Click "Update IAM role"</li>
113+
</ol>
114+
<p><b>Step 4: Use in Your .NET Code</b></p>
115+
<p>No code changes needed! The SDK automatically picks up the EC2 instance role:</p>
116+
<CodeSnippet Language="csharp" Number="8">
117+
var bedrockClient = new AmazonBedrockClient(RegionEndpoint.USEast1);
118+
var runtimeClient = new AmazonBedrockRuntimeClient(RegionEndpoint.USEast1);
119+
</CodeSnippet>
120+
</Section>
121+
122+
<Section Heading="Troubleshooting Authentication Issues" Level="5">
123+
<p>If you're getting permission errors, check these common issues:</p>
124+
<ul>
125+
<li><b>UnauthorizedException or AccessDeniedException:</b> Your credentials don't have Bedrock permissions. Double-check the IAM policy above is attached to your role/user.</li>
126+
<li><b>InvalidUserID or SignatureDoesNotMatch:</b> Your AWS credentials are incorrect or expired. Re-verify your access key and secret key.</li>
127+
<li><b>EC2 instance can't access Bedrock:</b> The instance profile role isn't attached, or the IAM policy is missing. Check the instance details in AWS console.</li>
128+
<li><b>Region issues:</b> Ensure Bedrock is available in your region. Not all AWS regions support Bedrock yet.</li>
129+
</ul>
130+
<p><b>Debug tip:</b> Use the AWS CLI to test credentials before using them in your .NET app:</p>
131+
<CodeSnippet Language="bash" Number="9">
132+
aws bedrock list-foundation-models --region us-east-1
133+
</CodeSnippet>
134+
<p style="margin-top: 1em;"><i>Note: The same IAM permissions can also be set up using CloudFormation or AWS CDK if you prefer infrastructure-as-code approaches.</i></p>
135+
</Section>
136+
</Section>
137+
138+
<Section Heading="Prompt Engineering & Response Parsing" Level="4">
139+
<p>For reliable parsing, craft your prompts to instruct the model to return strict JSON. Here’s a helper for formatting/parsing the response:</p>
140+
<CodeSnippet Language="csharp">
141+
private string FormatJsonString(string input)
142+
{
143+
if (string.IsNullOrWhiteSpace(input)) return input;
144+
// Try to extract the first JSON array or object from the string
145+
var match = System.Text.RegularExpressions.Regex.Match(input,
146+
"(\\{[\\s\\S]*\\}|\\[[\\s\\S]*\\])");
147+
if (!match.Success)
148+
return input;
149+
var jsonContent = match.Value;
150+
try
151+
{
152+
using var doc = System.Text.Json.JsonDocument.Parse(jsonContent);
153+
return System.Text.Json.JsonSerializer.Serialize(doc.RootElement,
154+
new System.Text.Json.JsonSerializerOptions { WriteIndented = true });
155+
}
156+
catch
157+
{
158+
// If not valid JSON, return as-is
159+
return jsonContent;
160+
}
161+
}
162+
</CodeSnippet>
163+
<CalloutBox Type="tip" Title="Prompt Engineering">
164+
<p>Always instruct the model to return a strict JSON array/object and nothing else for easier parsing.</p>
165+
</CalloutBox>
166+
</Section>
167+
168+
<Section Heading="Summary & Best Practices" Level="4">
169+
<ul>
170+
<li><b>Advanced authentication</b> enables secure, scalable, and production-ready AWS Bedrock integration in .NET.</li>
171+
<li><b>Use EC2 instance roles</b> for production workloads—never hardcode credentials.</li>
172+
<li><b>Prompt engineering</b> and response parsing are key for reliable GenAI workflows.</li>
173+
<li>Refer to AWS documentation for the latest best practices and SDK updates.</li>
174+
</ul>
175+
<p>
176+
For most users, the shared credentials file is sufficient. Move to advanced setups only when your deployment or security needs require it.
177+
</p>
178+
</Section>
179+
180+
<EndNotes RepositoryLink="https://github.com/ajaysskumar/ai-playground" />
181+
</BlogContainer>

0 commit comments

Comments
 (0)