We have the following code in an ECS Fargate container however it is constantly returning an error. When running identical code in a lambda with IAM authentication and the correct role setup, I am able to successfully run this.
Error
Network error: Response not successful: Received status code 403
UnrecognizedClientException
The security token included in the request is invalid.
Code
import 'isomorphic-fetch';
import AWSAppSyncClient, { AUTH_TYPE } from 'aws-appsync';
import AWS from 'aws-sdk';
// Setup variables for client
const graphqlEndpoint = process.env.GRAPHQL_ENDPOINT;
const awsRegion = process.env.AWS_DEFAULT_REGION;
const client = new AWSAppSyncClient({
url: graphqlEndpoint,
region: awsRegion,
auth: {
type: AUTH_TYPE.AWS_IAM,
credentials: AWS.config.credentials,
},
disableOffline: true,
})
Cloudformation
TaskDefinition:
Type: "AWS::ECS::TaskDefinition"
Properties:
ContainerDefinitions:
- Ommitted
Cpu: !FindInMap [CpuMap, !Ref Cpu, Cpu]
ExecutionRoleArn: !GetAtt "TaskExecutionRole.Arn"
Family: !Ref "AWS::StackName"
Memory: !FindInMap [MemoryMap, !Ref Memory, Memory]
NetworkMode: awsvpc
RequiresCompatibilities: [FARGATE]
TaskRoleArn: !GetAtt "TaskRole.Arn"
TaskRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: "ecs-tasks.amazonaws.com"
Action: "sts:AssumeRole"
ManagedPolicyArns:
- "arn:aws:iam::aws:policy/AWSAppSyncInvokeFullAccess" # Invoke Access for AppSync
I eventually discovered that this was a result of AppSyncClient not able to load the credentials in ECS correctly.
As per AWS Docs on IAM roles in ECS, credentials are loaded different to other AWS services. Instead of credentials being populated in env vars, the Amazon ECS agent instead populated the
AWS_CONTAINER_CREDENTIALS_RELATIVE_URIvariable with a path to the credentials. I was able to successfully getAWSAppSyncClientworking withIAMauthenticaiton in anECScontainer by first loading theECScredentials manually and passing it toAWSAppSyncClient. The below example worked.