Comment intégrer API Gateway avec s3 dans CDK
Les documents sont très clairs en faisant cela dans la console, https://docs.aws.amazon.com/apigateway/latest/developerguide/integrating-api-with-aws-services-s3.html, mais répliquer dans CDK est vraiment douloureux.
Ma question est de savoir comment créer une API Rest soutenue avec s3 (pas de lambda au milieu) dans CDK, ou du moins comment fonctionne apigateway.AwsIntegration.
J'ai essayé beaucoup de choses et j'ai réalisé que je codais à l'aveugle. J'ai déjà fait plusieurs intégrations entre restApi, lambda, sqs, dynamoDB, s3 et toutes étaient si faciles. Mais intégrer directement API Gateway à S3 est sur le point de me faire pleurer.
J'ai besoin qu'un restAPI stocke la charge utile de la demande directement dans un compartiment S3.
C'est ce que j'ai déjà essayé:
Ajoutez un stament de politique à 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
});
Je pensais que cela devrait être suffisant pour résoudre les problèmes d'autorisations, mais lorsque j'ai ajouté l'intégration AWS à l'API, comme ceci:
const getS3Integration = new apigateway.AwsIntegration({
service: "s3",
path: bucket.bucketName,
});
api.root.addMethod("PUT", getS3Integration, {
requestValidator: requestValidator,
requestModels: {"application/json": myModel},
});
Je suis en train:
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)
Je ne sais pas comment spécifier cet ARN de rôle, je ne l'ai pas trouvé dans la documentation. Je ne sais pas non plus si l'ajout d'une stratégie à restAPI était nécessaire. J'essayais de reproduire l'exemple ici dans CDK.
Réponses
La suite n'est pas l'ensemble complet, mais cela devrait vous donner quelques idées. J'ai fait des choses similaires sur SQS, j'ai trop pleuré à l'époque
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"
}
]});
}
Dans le document que vous avez lié (https://docs.aws.amazon.com/apigateway/latest/developerguide/integrating-api-with-aws-services-s3.html), section "Configurer les autorisations IAM pour que l'API appelle des actions Amazon S3", la stratégie que vous devez utiliser est totalement différente de celle que vous avez encodée.
Votre politique, si elle est appliquée à un bucket, dirait: si la demande provient du service "api gateway", autorisez les put:*actions. Cette approche est pour d'autres cas d'utilisation.
Selon la documentation, vous avez besoin de:
- créer un rôle
- le rôle doit contenir des politiques:
- actions autorisées (
put:*dans votre cas) - autoriser la passerelle API à basculer vers le rôle.
- actions autorisées (
- utiliser le rôle dans
apigateway.RestApi
La politique (1) doit être évidente, le (2) tel qu'indiqué dans la documentation est:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
D'après votre description, il me semble que vous ne fournissez pas de rôle IAM pour votre intégration. Vous ne fournissez une stratégie que pour RestApilaquelle est une stratégie basée sur les ressources pour votre API. En d'autres termes, cela ne s'applique pas à vos intégrations, mais spécifie plutôt qui peut exécuter votre API. En règle générale, vous ne l'utilisez pas si vous souhaitez rendre votre API publique.
Pour l'intégration AWS, vous devez fournir un rôle IAM avec des autorisations S3 à l' aide de IntegrationOptions . Plus précisément, via l' credentialsoption:
Un rôle IAM assumé par API Gateway .
La documentation CloudFormation, dans laquelle CDK mappe, contient plus de détails sur l'intégration Credentials:
Les informations d'identification requises pour l'intégration. Pour spécifier un rôle AWS Identity and Access Management (IAM) pris en charge par API Gateway, spécifiez le nom de ressource Amazon (ARN) du rôle. Pour exiger que l'identité de l'appelant soit transmise à partir de la requête, spécifiez arn: aws: iam ::: user / .
Pour utiliser des autorisations basées sur les ressources sur la fonction AWS Lambda (Lambda), ne spécifiez pas cette propriété. Utilisez la ressource AWS :: Lambda :: Permission pour permettre à API Gateway d'appeler la fonction. Pour plus d'informations, consultez Autoriser Amazon API Gateway à appeler une fonction Lambda dans le AWS Lambda Developer Guide.