AI 资讯
# 🚀 I Built a Jenkins CI/CD Pipeline From Scratch — Here's Every Bug I Hit (and How I Fixed Them)
A learning-in-public story about Flask, Jenkins, AWS EC2, systemd, and finally shipping a live demo on Vercel. 🎯 TL;DR I built PyPulse, a tiny Flask app, and wired it up to a full CI/CD pipeline: push to GitHub → Jenkins builds → tests → deploys to AWS EC2 → auto-triggered via webhook → managed by systemd. Along the way I broke almost every piece of it at least once, and fixed each one. I also deployed a permanent live demo on Vercel, since my EC2 instance is running on the AWS free trial and won't live forever. 🔗 Live demo: pypulse-pi.vercel.app 🔗 Live demo (health check): pypulse-pi.vercel.app/health If you're learning DevOps and want to see what the real, messy version of "just set up a CI/CD pipeline" looks like — not the polished tutorial version — this is that. 🧰 The Stack Piece Tool Job App Flask + pytest + gunicorn The actual web app and its tests CI/CD Jenkins (on EC2, Ubuntu 22.04) Build → Test → Deploy automation Source control GitHub Single source of truth Trigger GitHub Webhook Auto-runs the pipeline on every push Process management systemd Keeps the app alive on reboot/crash Permanent demo Vercel Live URL that survives EC2 termination 🏗️ The App: PyPulse Nothing fancy on purpose — the whole point of this project was the pipeline, not the app. python app.py from flask import Flask, jsonify from datetime import datetime, timezone app = Flask( name ) @app.route("/") def home(): return jsonify({ "message": "Hello from PyPulse", "time": datetime.now(timezone.utc).isoformat() }) @app.route("/health") def health(): return jsonify({"status": "ok"}), 200 if name == " main ": app.run(host="0.0.0.0", port=5000) Two routes. Two tests. That's it. Small enough that when something broke, I knew it wasn't the app — it was the plumbing around it. That turned out to be the right call, because the plumbing broke a lot. 😅 ⚙️ The Pipeline: Build → Test → Deploy Here's the mental model I ended up with for a Jenkinsfile: Each stage is a gate. If Build fails, Test never runs.
AI 资讯
992 Findings in SadCloud: What Compound Analysis Sees That Scanners Don't
✓ Human-authored analysis; AI used for formatting and proofreading. SadCloud is an open-source Terraform project by NCC Group that deploys misconfigured AWS resources. Security teams use it to test their tooling: if your scanner can't find the misconfigurations in SadCloud, it can't find them in production. We pointed Stave at SadCloud. Then at BishopFox's IAM Vulnerable. A lab focused on IAM privilege escalation paths. The numbers tell a story about what happens when you move from per-resource scanning to compound attack path analysis. The raw numbers Metric SadCloud (NCC Group) IAM Vulnerable (BishopFox) Assets evaluated 36 31 Atomic violations 992 837 Compound chains firing 84 instances (13 unique) 70 instances (6 unique) Near-miss chains 785 instances (40 unique) — A per-resource scanner (Prowler, ScoutSuite, Checkov) would show 992 findings for SadCloud. Each finding stands alone: this bucket is public, this role is overpermissioned, this trail isn't logging. The operator opens a dashboard with 992 items sorted by severity and starts scrolling. Stave's compound-only default output shows 84 findings across 13 named attack paths. Same underlying data. Different composition. The 992 atomic violations still evaluated. They're the detection infrastructure. The 84 compound chains are the findings that reach the operator. That's a 12x reduction by composition. Compound chains Each compound chain fires when multiple controls fail simultaneously on related assets, matching a named attack pattern: Chain Severity Instances What it means iam_escalation_undetected critical 36 IAM roles can escalate privileges and no detective control monitors the escalation path iam_boundary_governance_failure critical 36 No permission boundary constrains IAM principals in the account — any role can reach any resource iam_session_opacity high 2 IAM session activity isn't logged at the detail level needed to detect credential abuse s3_ssec_ransomware_path critical 1 S3 bucket is vulnerable t
AI 资讯
Kubernetes and Docker
Docker and Kubernetes are two of the most consequential infrastructure technologies of the last decade. They changed how software is built, packaged, and deployed. They are also two technologies that most engineers use before they understand, which creates gaps in knowledge that show up at the worst times: a production outage, a security incident, a performance problem you cannot diagnose. This guide builds understanding from the ground up. Every concept is introduced with the problem it solves. You will understand why containers exist before you understand what they are. You will understand why Kubernetes exists before you understand how it works. By the end, you will know not just how to run these technologies but how to reason about them. Table of Contents The Problem Containers Solve - Why Docker Exists Docker Internals - What a Container Actually Is Images - Building Portable Application Packages Dockerfile - Writing Reproducible Builds Docker Networking - Container Communication Docker Volumes - Managing State Docker Compose - Multi-Container Applications The Problem Kubernetes Solves - Why Orchestration Exists Kubernetes Architecture - The Control Plane and Data Plane Core Kubernetes Objects - Pods, Deployments, Services, ConfigMaps, Secrets Namespaces and RBAC - Multi-Tenancy and Access Control Storage in Kubernetes - Persistent Volumes Ingress - Routing External Traffic Helm - Package Management for Kubernetes Service Mesh - Istio and Advanced Traffic Management AWS Container Services - ECS and EKS Real Architecture Patterns The Problem Containers Solve - Why Docker Exists The Classic Failure Mode A developer builds an application on their MacBook. It works. They hand it to the QA team. It does not work. They hand it to the operations team to deploy to production. It works differently than in QA. "It works on my machine" is not a joke. It is a description of a real, chronic infrastructure problem. The application depends on: A specific version of Python, No
AI 资讯
How I Removed AWS Access Keys from GitLab CI/CD with OIDC
When I first connected my GitLab CI/CD pipelines to AWS, I used the simplest solution: an IAM user with an Access Key and Secret Access Key stored as GitLab CI/CD variables. It worked. But there was one problem: those credentials were permanent. They had to be stored, protected and eventually rotated. If they were accidentally exposed in logs or compromised, they could remain valid until manually revoked. I wanted a cleaner solution. So I replaced permanent AWS credentials with OIDC federation between GitLab and AWS . The result is simple: GitLab pipelines can access AWS without storing any permanent AWS credentials. In this post, I'll explain how I implemented it, how the authentication flow works, and one important issue I faced when using it with EKS and Terraform. The architecture The authentication flow looks like this: ┌──────────────┐ │ GitLab CI │ └──────┬───────┘ │ │ OIDC token ▼ ┌──────────────┐ │ AWS STS │ └──────┬───────┘ │ │ Temporary credentials ▼ ┌──────────────┐ │ IAM Role │ └──────┬───────┘ │ ├──────────► Terraform │ ├──────────► ECR │ └──────────► EKS Instead of GitLab storing an AWS Access Key, it proves its identity to AWS using a short-lived OIDC token. AWS verifies the token and returns temporary credentials. How does OIDC authentication work? The process can be summarized in five steps: GitLab creates an OIDC token for the CI/CD job. The pipeline sends this token to AWS. AWS verifies that the token really comes from GitLab. AWS checks that the project is allowed to assume the requested IAM role. AWS STS returns temporary credentials. These credentials expire automatically. So there is nothing permanent to store or rotate inside GitLab. Step 1 — Register GitLab as an OIDC provider AWS first needs to trust GitLab as an identity provider. I configured the OIDC provider using Terraform: data "tls_certificate" "gitlab" { url = "${var.gitlab_url}/.well-known/openid-configuration" } resource "aws_iam_openid_connect_provider" "gitlab" { url = var . gi
AI 资讯
Why Isn't the AWS Blocks Agent Built on AgentCore? What the Repository Reveals About What's Next
Since AWS Blocks entered public preview in June 2026, I have been making small contributions to the open-source project. AWS Blocks on GitHub In my previous post on AWS Blocks, Amplify, and App Studio , I looked at how these tools differ and what each is trying to achieve. While revisiting the Agent Block, one detail caught my attention: The AWS Blocks Agent is not currently running on Amazon Bedrock AgentCore. At a glance, it is easy to assume the relationship looks like this: AWS Blocks └─ Agent └─ Amazon Bedrock AgentCore But that is not how the current implementation works—at least not on main as of August 12, 2026. Then the story gets interesting. When I wondered whether an agent should simply use AgentCore directly, I found a fairly concrete set of pull requests that proposes moving the Agent Block's execution model to AgentCore Runtime. I contribute to AWS Blocks, but this is not an AWS statement or a roadmap. It is my reading of the public documentation and the open-source repository, from the perspective of both a user and a contributor. TL;DR The Agent Block on the current main branch does not run on AgentCore Runtime. It combines the Strands Agents SDK with AsyncJob , Realtime , FileBucket , and DistributedTable . A five-PR stack proposes migrating the Agent Block's execution model to AgentCore Runtime. As of August 12, 2026, all five migration PRs are still draft and unmerged. They are not an official roadmap. A separate open PR proposes Blocks for AgentCore Memory, Gateway, and Identity. So the most accurate conclusion today is this: AWS Blocks Agent is not AgentCore today, but the repository contains concrete proposals for bringing the two together. The Agent Block today is not AgentCore Let's start with the implementation on main . The Agent Block uses the Strands Agents SDK . But it is not a standalone agent runtime; it composes several Blocks to handle execution, streaming, and persistence. At a high level, the structure looks like this: Agent ├─ St
开发者
Meta can't stop states' $1.4 trillion lawsuit from going to trial
Judges tell Meta that Section 230 provides a defense, not immunity from lawsuits.
产品设计
Now Rippling is counter-suing tiny startup Runlayer
This lawsuit follows one filed last month by Runlayer that accused Rippling of stealing its product ideas. It's a seller- and buyer-beware market warning.
AI 资讯
Your terragrunt (or terraform) plan is 4,000 lines. Only two of them matter.
You know the ritual. terragrunt run --all -- plan Then you scroll. Past forty units of Refreshing state… . Past the ninth identical count instance. Past a tags_all.LastModified that changes on every single run because your CI stamps a timestamp into it. Somewhere in there are the two lines you actually needed to see — probably the # forces replacement on a database. You scroll back up. You lose it. You pipe it to a file and grep for must be replaced . You approve anyway, because it's 6pm. I got tired of that, so I wrote tgsieve . What it does It runs the plan for you, reads the structured output instead of the prose, throws away the noise you declared as noise, collapses everything that repeats, and prints what's left. DESTROY / REPLACE (1) envs/prod/a ± aws_db_instance.main engine_version "14.7" → "15.3" forces replacement UPDATE (5) 5 units envs/dev/a, envs/dev/b, envs/prod/a, +2 more ~ null_resource.pin triggers.region "eu-central-1" → "us-west-2" SUMMARY ±1 replace ~5 update severity: 1 high, 5 medium hid 214 attributes across 3 rules (--explain to see them) That's five units of a real terragrunt plan — the same run terraform prints as several hundred lines. The report nests three deep — where , then what , then which fields : UPDATE (5) envs/prod/c ← the unit, said once ~ aws_s3_bucket.this ← the resource tags_all.entity "tgb" → "tgc" ← the attributes that changed A change that's identical across units replaces the directory with the set it covers, so the first column always answers the same question: where . It doesn't scrape text This matters, because the obvious implementation is fragile garbage. You might reach for terragrunt run --all -- plan -json . It doesn't work: terragrunt forwards terraform's own NDJSON straight through, so lines from units running in parallel interleave with no way to tell them apart. So tgsieve asks terragrunt for machine-readable artifacts and reads those: What Flag it passes What it gets per-unit plans --json-out-dir one tfplan.j
AI 资讯
Stop Waiting 10 Minutes to Fail: How CDK Comprehensive Validation Catches Misconfigurations Before Deploy
The 10-Minute Tax For many years, as a CDK developer, I'd run cdk synth , then cdk deploy , and then cross my fingers — either it deployed cleanly, or it failed somewhere in the middle of a CloudFormation run that had already been going for ten minutes: ❌ MyStack failed: UPDATE_ROLLBACK_COMPLETE Resource handler returned message: "The runtime parameter of nodejs16.x is no longer supported" (HandlerErrorCode: InvalidRequest) Ten minutes. For something CDK could have told you before it ever talked to CloudFormation. These days I let AI agents write a good chunk of my CDK code, which made this even worse — an agent can't iterate when every failed attempt costs it ten minutes. 🤖 AI Agent development loop: Attempt 1: cdk deploy → ⏱️ 10 min → ❌ deprecated runtime Attempt 2: cdk deploy → ⏱️ 10 min → ❌ invalid memory size Attempt 3: cdk deploy → ⏱️ 10 min → ❌ security group rule conflict Attempt 4: cdk deploy → ⏱️ 10 min → ✅ finally works Total time wasted: 30 minutes on things that were knowable at synth time. And if you're deploying something heavy like an Amazon EKS cluster, the penalty stretches to 25-30 minutes per failed attempt. What if the CDK could catch all of those on cdk synth — in seconds? The CDK Lifecycle: Where Validation Fits Before I show off the new validation, it helps to see where it plugs into the lifecycle every cdk deploy goes through: Stage What Happens Executed By 1. Construction Execute main.ts , call new Stack() , build the construct tree in memory CDK App (local) 2. Synth app.synth() traverses the tree, produces CloudFormation template to cdk.out/ CDK App (local) 3. Template Validation 🆕 Post-synth offline validation — default rule set + registered policy plugins CDK App (aws-cdk-lib, local) 4. Create Change Set 🆕 CloudFormation pre-deployment validation — 6 types of online checks against real account state CloudFormation (AWS) 5. Execute Change Set CloudFormation provisions/updates/deletes actual AWS resources CloudFormation (AWS) The gap was a
开发者
Aptoide becomes the first rival app store to return to Google Play in the US
Aptoide has brought its games store back to Google Play after more than a decade, as court-ordered changes open Android to competing app stores.
AI 资讯
How Pinterest Secures AWS Infrastructure at Scale with a Centralized Terraform Pipeline
Pinterest has revealed the Resource Provisioner Pipeline (RPP), its own Terraform execution engine. It ensures least-privilege access and needs dual-control reviews. This is important for the company’s AWS infrastructure, as it adds strict guardrails to the GitHub Actions workflows. By Claudio Masolo
AI 资讯
S3 Access Denied Troubleshooting: Every Cause and How to Fix It (2026)
If you are staring at An error occurred (AccessDenied) when calling the GetObject operation: Access Denied , this guide walks through every cause in the order you should check them, with the exact fix for each. I am a cloud associate and I debug this error often enough that I keep a mental checklist. Here it is, written down. Quick answer: the 8 most common causes of S3 Access Denied In Amazon S3, "Access Denied" means the request was authenticated but not authorized, or an explicit deny blocked it. In practice it is almost always one of these, roughly in order of frequency: The IAM identity (user or role) is missing the required s3: permission. The bucket policy does not allow the action, or explicitly denies it. S3 Block Public Access is on and you expected public/anonymous access. SSE-KMS : you have S3 permission but not kms:Decrypt on the encryption key. Missing s3:ListBucket , which turns a "key not found" into a 403. Cross-account access where only one side grants permission. An explicit Deny somewhere wins (SCP, permissions boundary, VPC endpoint policy, or bucket policy). Object ownership / ACLs after a cross-account upload. If you only remember one thing: an explicit Deny anywhere in the chain always beats an Allow . Start by finding a deny, then work down the list. Step 0: Confirm which identity is actually making the request Before touching any policy, confirm who you are. Most "but I have admin" cases are the wrong principal. aws sts get-caller-identity Check the Arn in the output. If it is a role you did not expect (an EC2 instance profile, a CI role, an assumed role), you have been debugging the wrong identity's permissions the whole time. This single command saves more time than any other step. Step 1: Does the IAM identity policy allow the action? S3 needs the specific action for the specific resource. The two resource types trip people up: Bucket-level actions ( s3:ListBucket , s3:GetBucketLocation ) target the bucket ARN: arn:aws:s3:::my-bucket Obj
AI 资讯
CPU utilization lies: autoscaling a single-threaded service
The service was slow. Not down, just slow: p95 latency climbing well past where users notice, requests piling up, the kind of degradation that generates support tickets instead of alerts. And the autoscaler, the whole point of which is to add capacity when a service is under strain, sat there doing nothing. The metric it was watching said everything was fine. Average CPU utilization on the tasks was hovering around 30 percent, nowhere near the scale-out threshold. The dashboard was calm. The users were not. Both were right, and the gap between them is one of the most common autoscaling traps on a container platform. This is the first article in a series on running a multi-tenant SaaS on AWS at team scale. It is about a metric that lies, quietly, by design. Why 30 percent CPU meant 100 percent busy The service was a single-threaded application. A Node.js API, in this case, but the same is true of any process that does its real work on one thread: a classic Python or Ruby worker, most single-process runtimes. A single-threaded process can, by definition, saturate exactly one CPU core. The task it was running on had four vCPUs. So the arithmetic that matters is brutally simple: one core fully pegged / four vCPUs on the task = ~25% task-average CPU At full saturation, the busiest that process can ever make the task look is about 25 percent. Add a little async I/O overhead spread across the runtime and you land around 30 percent. That is not a service with headroom. That is a service redlining on the only core it can use, while three cores sit idle and drag the average down to a number that reads as "barely working." The autoscaling policy was tracking average CPU across the task's cores. For a workload that can only ever use one of them, that average is not a measure of load. It is a measure of load divided by four. The metric was answering a different question This is the real lesson, and it is not specific to AWS or ECS. Average CPU utilization answers "how much of th
AI 资讯
Stale infrastructure context is worse than none
The bug that isn't a bug On Tuesday you attach a dead-letter queue to orders-queue . On Wednesday a batch of messages disappears and you ask Claude Code what happened. It answers immediately: orders-queue has no DLQ configured, so failed messages are dropped after the maximum receive count. That answer is wrong, and it is also not a hallucination. The assistant read a real snapshot of your AWS account. The snapshot was taken Monday. This is the failure mode that shows up once you give an AI assistant deterministic infrastructure context instead of letting it guess. Guessing produces answers that feel uncertain, and you treat them accordingly. A stale snapshot produces answers that feel authoritative, with real table names, real queue names, real ARNs. Nothing in the response signals that the underlying facts expired. Infrawise extracts your DynamoDB tables, Lambda configs, queue settings, database schemas, and code-to-table access patterns into a graph, then serves that graph to AI editors over MCP. Everything below is about the part nobody asks for in a feature list: what happens to that graph when it gets old. Why the context has to be cached at all The obvious fix is to never cache. Answer every question from a live account read. That does not survive contact with an actual session. A full infrawise analyze walks every enabled service, paginating through DynamoDB DescribeTable , Lambda configurations and their event source mappings, SQS queue attributes, SNS subscriptions and filter policies, Secrets Manager rotation state, S3 versioning and public-access configuration, ElastiCache clusters, CloudWatch log groups, plus schema introspection against Postgres, MySQL, or MongoDB, plus a local IaC parse, plus an AST scan of the repository. Every extractor is dispatched through a single Promise.all , so wall-clock time is bounded by the slowest one rather than their sum, but it is still seconds, not milliseconds. An assistant calls get_infra_overview at the start of a
AI 资讯
AWS Route 53 — DNS Fundamentals, Hosted Zones, Routing Policies & Resolvers
Part of my AWS learning journey — transitioning from Systems Engineer to Cloud/DevOps. Route 53 is where networking meets the internet — how domain names reach your applications, how traffic gets distributed intelligently, and how AWS and on-premises networks resolve each other's names. 📋 Topics Covered # Topic Type 1 DNS Pre-Requisites — How DNS Works Concept 2 Complete DNS Resolution Flow Concept + Interview 3 What is Route 53 Concept 4 Hosted Zones — Public vs Private Concept + Lab 5 Hosted Zone ID Concept + DevOps 6 DNS Record Types and Use Cases Concept + Cert 7 NS and SOA Records — Auto-Created, Never Delete Concept + Interview 8 Alias Record — AWS-Specific Concept + Cert 9 Landing Zone — Brief Context Concept 10 Route 53 Routing Policies — All 8 Concept + Cert 11 Route 53 Traffic Policies Concept + DevOps 12 Route 53 Resolvers Concept + Interview 13 Inbound vs Outbound Resolver Endpoints Concept + Interview 14 Route 53 Forwarders Concept + Interview 15 Split-Horizon DNS Concept + Interview 16 Interview Questions Interview 17 Practice Tasks Practice DNS Pre-Requisites — How DNS Works DNS is the reason you type google.com instead of 142.250.195.46 . Before understanding Route 53, these fundamentals must be solid. Core Vocabulary Term What it means Domain Human-readable name — google.com , tejascloud.in IP Address Machine address — 54.21.11.90 — what computers actually use DNS The translation system — converts domain names → IP addresses TLD Top-Level Domain — the last part after the final dot TTL Time To Live — how long a DNS response is cached before re-querying Recursive Resolver Finds the answer for the client by querying other DNS servers, caches the result Authoritative DNS Server Stores the official DNS records for a domain — returns the definitive answer Common TLDs: .com → commercial · .org → organizations · .net → network · .in → India · .uk → United Kingdom · .edu → education · .gov → government The Complete DNS Resolution Flow This is the full journe
AI 资讯
AWS Aurora, ElastiCache Patterns & DynamoDB — The Complete Data Layer
Part of my AWS learning journey — transitioning from Systems Engineer to Cloud/DevOps. This session completes the database picture — Aurora's read/write architecture, ElastiCache caching strategies, and DynamoDB from table creation to production-ready query patterns. 📋 Topics Covered # Topic Type 1 Aurora Endpoints — Writer vs Reader Concept + Interview 2 What Happens When the Aurora Writer Fails Concept + Cert 3 ElastiCache Caching Patterns — Lazy Loading, Write Through, Session Store Concept + Interview 4 Cache Invalidation Concept + Interview 5 DynamoDB — What It Is and When to Use It Concept + Interview 6 DynamoDB Table Creation — Keys and Settings Concept + Lab 7 Table Classes — Standard vs Standard-IA Concept + Cert 8 Capacity Modes — On-Demand vs Provisioned Concept + Cert 9 Warm Throughput Concept + Cert 10 DynamoDB Items & Attributes — CRUD Operations Concept + Lab 11 Query vs Scan — The Critical Difference Concept + Interview 12 Local Secondary Index (LSI) vs Global Secondary Index (GSI) Concept + Cert 13 Bonus Concepts — Streams, DAX, Consistency, Transactions Concept + Interview 14 Interview Questions Interview 15 Practice Tasks Practice Aurora Endpoints — Writer vs Reader Aurora doesn't give you just one database endpoint — it gives you two, each serving a different purpose and routing to different parts of the cluster. Writer Endpoint (Primary Endpoint): Always points to the current primary/writer instance. All write operations (INSERT, UPDATE, DELETE) go here. If a failover happens and a replica is promoted, Aurora automatically redirects this endpoint to the new writer — your application's configuration never needs to change. Reader Endpoint: A load-balanced endpoint that distributes read-only queries (SELECT) across all available Aurora Replicas. You don't manage which replica serves each query — Aurora handles the routing, spreading read traffic evenly across however many replicas exist. Why this architecture matters: In a typical application, read
开发者
My Terraform Drift Pipeline Fixed the Change, Then Forgot It
My Terraform drift pipeline could detect a manual EC2 tag change, classify it as LOW, and run Terraform to remove it. Then the pipeline moved on. The evidence existed, but it was spread across CodeBuild output, Lambda logs, and an SNS message. If I wanted to know what changed, how it was classified, and whether remediation started, I had to reconstruct the event from multiple AWS services. The pipeline could act on drift. It could not remember drift. Phase 4 added that memory: a durable DynamoDB record, a read only API, and a small dashboard that turns the event history into something I can inspect without opening three AWS consoles. The Stack Terraform drift event ↓ SNS ↓ Severity Lambda ├── classifies HIGH / MEDIUM / LOW ├── starts remediation for eligible LOW drift └── writes the audit event to DynamoDB ↓ API Gateway HTTP API ↓ Read only Lambda ↓ DynamoDB Query ↓ CloudFront → static dashboard ↑ private S3 bucket The browser receives static HTML, CSS, and JavaScript from CloudFront. JavaScript calls API Gateway, the API Lambda queries DynamoDB, and the returned JSON becomes the live dashboard. There is no EC2 web server and no application process running continuously. Step 1: Store Every Classified Event I created a DynamoDB table with a composite key: resource "aws_dynamodb_table" "drift_events" { name = "terraform-drift-events" billing_mode = "PAY_PER_REQUEST" hash_key = "project" range_key = "timestamp" attribute { name = "project" type = "S" } attribute { name = "timestamp" type = "S" } } project groups the history for one Terraform project. The ISO 8601 timestamp orders its events. DynamoDB only requires attribute definitions for keys and indexes. Fields such as high_count , changes , and status still belong in each item, but they do not belong in the table schema block. I passed the table name into the existing severity Lambda instead of putting it directly in the code: environment { variables = { DRIFT_EVENTS_TABLE = aws_dynamodb_table . drift_events . name
开发者
RAG Powered Apps with Amazon Bedrock, Part 2: Automating the RAG Pipeline with Terraform
Before you start: This picks up where Part 1 left off. From part 1, you would've learned how to setup a Bedrock Knowledge Base in the console. In addition to that, you should have a general understanding of how the ingestion and query pipeline works. Introduction & Motivation I started this project with a singular goal: to build a comprehensive Terraform module that allows developers to deploy the entire infrastructure for a "Chat with PDF" application faster. When Amazon Bedrock was first unveiled in April 2023 , I jumped in immediately. Like many of you, I built several proof-of-concepts (PoCs) through the AWS Console. The UI is amazing for building quick pocs, but once I moved into experimentation, I realized it would be best to quickly setup and tear down the infra. An example use case was testing if there were any cost savings in using S3 Vectors vs OpenSearch and how much cost savings exactly. None of the Terraform modules I found on GitHub ( at the time ) seemed to cover the end-to-end pipeline I was looking for, so I decided to build mine. I'm also big on learning so why not. What Are We Building? A couple of terraform modules to automate everything we clicked through manually in Part 1. One terraform apply brings up the full stack: S3 Bucket : your document store. Encrypted at rest, versioning on, zero public access. OpenSearch Serverless : the vector database. Stores the embeddings Bedrock generates during ingestion. Bedrock Knowledge Base : orchestrates the chunking, embedding, and storage of documents, and retrieval at query time. Ingestion Lambda : triggered automatically when you upload a file to S3. Starts a Bedrock ingestion job so documents are chunked, embedded, and indexed without ClickOps. Query Lambda : accepts a natural language question, calls RetrieveAndGenerate , and returns an answer with source citations. Full source code + ReadMe: Bedrock Project . If you run into issues or want to extend the module, feel free to open an issue. Architectu
AI 资讯
OpenAI says Apple’s own security practices undermine its trade secrets case
Newly filed court exhibits show OpenAI’s legal strategy in Apple’s trade secrets lawsuit: argue that Apple’s own security and offboarding practices — including allowing an Apple manager to access a former engineer’s iCloud account after he left the company —undermine its claims that the allegedly stolen information was properly protected.
AI 资讯
The image agents — prompt to PNG
Post 4 of 8 in the game-factory series. Icons are what people look at You can theme fonts, colors, win messages, and sound effects. Change all of it and the game still reads like the original with a skin on it. Swap the icons — the actual symbols spinning in the reels — and it reads like a different game. The casino template I built by hand uses cloud service logos. Replace those with golden scarabs and ankhs and it becomes an Egyptian game. Keep the logos and give it an Egyptian color scheme and it doesn't. A full theme has around thirty symbols. Each needs to be small enough to read at reel size, distinctive enough to tell apart mid-spin, and consistent enough that they look like they came from the same place. Getting that by hand for every theme is exactly what I wanted to avoid. So two agents handle the visual layer: Image-Gen and Background-Gen. They're the shortest story in the pipeline — almost identical code, real results, and one failure mode I still haven't fully solved. Two agents, one loop The Designer's spec carries everything the image agents need. Each symbol entry has an icon_prompt — a short text description the Designer wrote to describe that symbol's appearance. The spec also carries a single background_prompt for the full-page background. Image-Gen reads the spec, loops through every symbol, and for each one calls Stable Image Core on Bedrock with the symbol's prompt. It gets a PNG back, resizes it to 256×256 (the size the reels expect), and writes it into the app's public/images folder. After the icons are approved, it seeds DynamoDB — putting each symbol into a table the game queries at runtime to know which icons to load. Background-Gen does the same process exactly once, for the background image. That's the scope. I grouped them in one post because splitting them into two would mean writing the same agent story twice. They share the same architecture, the same failure modes, and the same lessons. The only thing different is the count of outpu