Como integrar API Gateway com s3 em CDK
Os documentos são muito claros ao fazer isso no console, https://docs.aws.amazon.com/apigateway/latest/developerguide/integrating-api-with-aws-services-s3.html, mas replicar em CDK é muito doloroso.
Minha dúvida é como criar uma API Rest apoiada em s3 (sem lambda no meio) no CDK, ou pelo menos como funciona o apigateway.AwsIntegration.
Tentei muitas coisas e percebi que estava programando às cegas. Já fiz várias integrações entre restApi, lambda, sqs, dynamoDB, s3 e todas elas foram muito fáceis. Mas a integração direta do API Gateway com o S3 está prestes a me fazer chorar.
Preciso que uma restAPI armazene a carga útil da solicitação diretamente em um balde S3.
Isso é o que eu já tentei:
Adicione um estatuto de política ao RestApi:
const apiResourcePolicy = new iam.PolicyDocument({
statements: [
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ['s3:Put*'],
resources: [bucket.bucketName],
principals: [new ServicePrincipal('apigateway.amazonaws.com')]
})
]
});
const api = new apigateway.RestApi(this, "dispatch-api", {
restApiName: "my api name",
description: "api description",
policy: apiResourcePolicy
});
Achei que isso deveria ser o suficiente para resolver problemas de permissões, mas quando adicionei a Integração AWS à API, assim:
const getS3Integration = new apigateway.AwsIntegration({
service: "s3",
path: bucket.bucketName,
});
api.root.addMethod("PUT", getS3Integration, {
requestValidator: requestValidator,
requestModels: {"application/json": myModel},
});
Estou entendendo:
1:41:11 PM | CREATE_FAILED | AWS::ApiGateway::Method | XXXXXXXXXXXXXXXX
Role ARN must be specified for AWS integrations (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException; Request ID: xxxxxxxxxxxxxxxxxxxxx; Proxy:
null)
Não sei como especificar esse Role ARN, não encontrei isso nos documentos. Também não sei se adicionar política ao restAPI era necessário. Eu estava tentando replicar o exemplo aqui no CDK.
Respostas
A seguir não está o conjunto completo, mas isso deve lhe dar algumas idéias. Fiz coisas semelhantes no SQS, também chorei naquela época
const bucket = new s3.Bucket(this, 'storage');
const executeRole = new iam.Role(this, "role", {
assumedBy: new iam.ServicePrincipal('apigateway.amazonaws.com'),
path: "/service-role/"
});
bucket.grantReadWrite(executeRole);
const api = new apigateway.RestApi(this, 's3api');
const s3Integration = new apigateway.AwsIntegration({
service: 's3',
integrationHttpMethod: "PUT",
path: "{bucket}",
options : {
credentialsRole: executeRole,
// should have all kind of path mapping..
}
})
api.root.addResource("{folder}").addMethod("PUT", s3Integration, {
methodResponses: [
{
statusCode: "200"
}
]});
}
No documento que você vinculou (https://docs.aws.amazon.com/apigateway/latest/developerguide/integrating-api-with-aws-services-s3.html), seção "Configurar permissões de IAM para a API para invocar ações do Amazon S3", a política que você precisa usar é totalmente diferente da que você codificou.
Sua política, se aplicada a um balde, diria: se a solicitação for do serviço "gateway da API", permita put:*ações. Essa abordagem é para outros casos de uso.
De acordo com a documentação, você precisa de:
- criar uma função
- a função deve conter políticas:
- ações permitidas (
put:*no seu caso) - permitir que o gateway api mude para a função.
- ações permitidas (
- usar a função em
apigateway.RestApi
A política (1) deve ser óbvia, a (2) conforme fornecida na documentação é:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Pela sua descrição, parece-me que você não está fornecendo a função IAM para sua integração. Você está fornecendo uma políticaRestApi somente para a qual é uma política baseada em recursos para sua API. Em outras palavras, não se aplica a suas integrações, mas especifica quem pode executar sua API. Geralmente você não o usa se quiser tornar sua API pública.
Para integração com AWS, você deve fornecer a função IAM com permissões S3 usando IntegrationOptions . Especificamente, por meio da credentialsopção:
Uma função IAM que o API Gateway assume .
Os documentos do CloudFormation, nos quais o CDK mapeia, têm mais detalhes sobre a integração Credentials:
As credenciais necessárias para a integração. Para especificar uma função AWS Identity and Access Management (IAM) que o API Gateway assume, especifique o Amazon Resource Name (ARN) da função. Para exigir que a identidade do chamador seja transmitida a partir da solicitação, especifique arn: aws: iam ::: user / .
Para usar permissões baseadas em recursos na função AWS Lambda (Lambda), não especifique esta propriedade. Use o recurso AWS :: Lambda :: Permission para permitir que o API Gateway chame a função. Para obter mais informações, consulte Permitir que o Amazon API Gateway invoque uma função Lambda no AWS Lambda Developer Guide.