Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,11 @@ The `<log-group-name>` and `<region>` configured in the CDK construct will be us
- `<amplify-authenticated-role-name>` and `<amplify-unauthenticated-role-name>` are Amplify roles created as part of Amplify Auth configuration via Amplify CLI.

```ts
import * as path from "node:path"
import * as cdk from "aws-cdk-lib"
import { Construct } from "constructs"
import * as logs from "aws-cdk-lib/aws-logs"
import * as path from "path"
import * as iam from "aws-cdk-lib/aws-iam"
import { Construct } from "constructs"

export class RemoteLoggingConstraintsConstruct extends Construct {
constructor(scope: Construct, id: string, props: RemoteLoggingConstraintProps) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ export function getStaticProps() {
};
}

### Set up the backend

To enable Predictions we need to set up the appropriate IAM policy for Roles in your Cognito Identity Pool in order to use an appropriate feature. Additionally, we need to use the ```addOutput``` method to patch the custom Predictions resource to the expected output configuration.

<Callout informational>
Expand All @@ -38,11 +36,9 @@ To learn more, check the docs of [Amazon Translate](https://docs.aws.amazon.com/


```ts title="amplify/backend.ts"

import { PolicyStatement } from "aws-cdk-lib/aws-iam";
import { defineBackend } from "@aws-amplify/backend";
import { auth } from "./auth/resource";
import { Stack } from "aws-cdk-lib";
import { PolicyStatement } from "aws-cdk-lib/aws-iam";

const backend = defineBackend({
auth,
Expand Down Expand Up @@ -88,24 +84,21 @@ backend.addOutput({
targetLanguage: "es",
},
proxy: false,
region: Stack.of(backend.auth.resources.unauthenticatedUserIamRole)
.region,
region: backend.auth.stack.region,
},
speechGenerator: {
defaults: {
voiceId: "Ivy",
},
proxy: false,
region: Stack.of(backend.auth.resources.unauthenticatedUserIamRole)
.region,
region: backend.auth.stack.region,
},
transcription: {
defaults: {
language: "en-US",
},
proxy: false,
region: Stack.of(backend.auth.resources.unauthenticatedUserIamRole)
.region,
region: backend.auth.stack.region,
},
},
identify: {
Expand All @@ -116,24 +109,21 @@ backend.addOutput({
},
celebrityDetectionEnabled: true,
proxy: false,
region: Stack.of(backend.auth.resources.unauthenticatedUserIamRole)
.region,
region: backend.auth.stack.region,
},
identifyLabels: {
defaults: {
type: "ALL",
},
proxy: false,
region: Stack.of(backend.auth.resources.unauthenticatedUserIamRole)
.region,
region: backend.auth.stack.region,
},
identifyText: {
defaults: {
format: "ALL",
},
proxy: false,
region: Stack.of(backend.auth.resources.unauthenticatedUserIamRole)
.region,
region: backend.auth.stack.region,
},
},
interpret: {
Expand All @@ -142,17 +132,14 @@ backend.addOutput({
type: "ALL",
},
proxy: false,
region: Stack.of(backend.auth.resources.unauthenticatedUserIamRole)
.region,
region: backend.auth.stack.region,
},
},
},
},
});



```

## Install Amplify Libraries

To install the Amplify library to use predictions features, run the following commands in your project's root folder:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,10 @@ export const storage = defineStorage({
To use the Amazon Rekognition service, you need to add Amazon Rekognition as an HTTP Data Source and configure the proper IAM policy for Lambda to effectively utilize the desired feature and grant permission to access the storage. In this case, you can add the `rekognition:DetectText` and `rekognition:DetectLabels` actions to the policy. Update the `amplify/backend.ts` file as shown below.

```ts title= "amplify/backend.ts"

import { PolicyStatement } from 'aws-cdk-lib/aws-iam';
import { defineBackend } from '@aws-amplify/backend';
import { auth } from './auth/resource';
import { data } from './data/resource';
import { Stack } from 'aws-cdk-lib';
import { PolicyStatement } from 'aws-cdk-lib/aws-iam';
import { storage } from './storage/resource';

const backend = defineBackend({
Expand All @@ -89,19 +87,17 @@ const backend = defineBackend({
storage
});

const dataStack = Stack.of(backend.data)

// Set environment variables for the S3 Bucket name
backend.data.resources.cfnResources.cfnGraphqlApi.environmentVariables = {
S3_BUCKET_NAME: backend.storage.resources.bucket.bucketName,
};

const rekognitionDataSource = backend.data.addHttpDataSource(
"RekognitionDataSource",
`https://rekognition.${dataStack.region}.amazonaws.com`,
`https://rekognition.${backend.data.stack.region}.amazonaws.com`,
{
authorizationConfig: {
signingRegion: dataStack.region,
signingRegion: backend.data.stack.region,
signingServiceName: "rekognition",
},
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,24 +60,21 @@ npm add @aws-sdk/client-translate

```ts title="amplify/backend.ts"
import { defineBackend } from '@aws-amplify/backend';
import { auth } from './auth/resource';
import { data } from "./data/resource";
import { Stack } from 'aws-cdk-lib';
import { PolicyStatement } from 'aws-cdk-lib/aws-iam';
import { auth } from './auth/resource';
import { data } from './data/resource';

const backend = defineBackend({
auth,
data
});

const dataStack = Stack.of(backend.data)

const translateDataSource = backend.data.addHttpDataSource(
"TranslateDataSource",
`https://translate.${dataStack.region}.amazonaws.com`,
`https://translate.${backend.data.stack.region}.amazonaws.com`,
{
authorizationConfig: {
signingRegion: dataStack.region,
signingRegion: backend.data.stack.region,
signingServiceName: "translate",
},
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,10 @@ backend.generateHaikuFunction.resources.lambda.addToRolePolicy(
In your `amplify/backend.ts` file, replace the content with the following code to add an HTTP data source for Amazon Bedrock to your API and grant it permissions to invoke a generative AI model:

```ts title="amplify/backend.ts"
import { Effect, PolicyStatement } from "aws-cdk-lib/aws-iam";
import { defineBackend } from "@aws-amplify/backend";
import { auth } from "./auth/resource";
import { data } from "./data/resource";
import { Effect, PolicyStatement } from "aws-cdk-lib/aws-iam";
import { Stack } from "aws-cdk-lib";

export const backend = defineBackend({
auth,
Expand All @@ -103,7 +102,7 @@ const bedrockDataSource = backend.data.addHttpDataSource(
"https://bedrock-runtime.us-east-1.amazonaws.com",
{
authorizationConfig: {
signingRegion: Stack.of(backend.data).region,
signingRegion: backend.data.stack.region,
signingServiceName: "bedrock",
},
}
Expand All @@ -114,7 +113,7 @@ bedrockDataSource.grantPrincipal.addToPrincipalPolicy(
effect: Effect.ALLOW,
actions: ["bedrock:InvokeModel"],
resources: [
`arn:aws:bedrock:${Stack.of(backend.data).region}::foundation-model/${MODEL_ID}`,
`arn:aws:bedrock:${backend.data.stack.region}::foundation-model/${MODEL_ID}`,
],
})
);
Expand Down Expand Up @@ -352,32 +351,31 @@ const { data, errors } = await client.queries.generateHaiku({
Here's an example of a simple UI that prompts a generative AI model to create a haiku based on user input:

```tsx title="App.tsx"
import { FormEvent, useState } from "react";

import { generateClient } from "aws-amplify/api";
import { Schema } from "@/amplify/data/resource";

import { Amplify } from "aws-amplify";
import outputs from "@/amplify_outputs.json";
import type { Schema } from '@/amplify/data/resource';
import type { FormEvent } from 'react';
import { useState } from 'react';
import { Amplify } from 'aws-amplify';
import { generateClient } from 'aws-amplify/api';
import outputs from '@/amplify_outputs.json';

Amplify.configure(outputs);

const client = generateClient<Schema>();

export default function App() {
const [prompt, setPrompt] = useState<string>("");
const [prompt, setPrompt] = useState<string>('');
const [answer, setAnswer] = useState<string | null>(null);

const sendPrompt = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
const sendPrompt = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();

const { data, errors } = await client.queries.generateHaiku({
prompt,
prompt
});

if (!errors) {
setAnswer(data);
setPrompt("");
setPrompt('');
} else {
console.log(errors);
}
Expand All @@ -387,17 +385,15 @@ export default function App() {
<main className="flex min-h-screen flex-col items-center justify-center p-24 dark:text-white">
<div>
<h1 className="text-3xl font-bold text-center mb-4">Haiku Generator</h1>

<form className="mb-4 self-center max-w-[500px]" onSubmit={sendPrompt}>
<input
className="text-black p-2 w-full"
placeholder="Enter a prompt..."
name="prompt"
value={prompt}
onChange={(e) => setPrompt(e.target.value)}
onChange={(event) => setPrompt(event.target.value)}
/>
</form>

<div className="text-center">
<pre>{answer}</pre>
</div>
Expand All @@ -407,7 +403,7 @@ export default function App() {
}
```

![GIF of a webpage titled "Haiku Generator" and input field. "Frank Herbert's Dune" is entered and submitted. Shortly after, a haiku is rendered to the page.](/images/haiku-generator.gif)
![A webpage titled "Haiku Generator" and input field. "Frank Herbert's Dune" is entered and submitted. Shortly after, a haiku is rendered to the page.](/images/haiku-generator.gif)

## Conclusion

Expand Down
Loading