

Ceci est le guide du développeur du AWS CDK v2. L'ancien CDK v1 est entré en maintenance le 1er juin 2022 et a pris fin le 1er juin 2023.

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Définissez les autorisations pour les constructions L2 avec le CDK AWS
<a name="define-iam-l2"></a>

Définissez les rôles et les politiques de gestion des AWS identités et des accès (IAM) pour les constructions L2 lors de l'utilisation du Cloud Development Kit AWS (CDK).AWS 

## Utiliser des méthodes d'octroi pour définir les autorisations
<a name="define-iam-l2-grant"></a>

Lorsque vous définissez votre infrastructure à l'aide des constructions L2 de la bibliothèque AWS de constructions, vous pouvez utiliser les *méthodes d'octroi* fournies pour spécifier les autorisations dont vos ressources auront besoin. Le AWS CDK créera automatiquement les rôles IAM nécessaires pour toutes les AWS ressources qui en ont besoin.

**Astuce**  
Les méthodes Grant fonctionnent également avec les constructions L1 via les classes Grants. Pour plus d'informations, consultez la section [Façades](facades.md).

L'exemple suivant définit les autorisations entre une fonction AWS Lambda et un bucket Amazon Simple Storage Service (Amazon S3). Ici, la `grants.read` méthode de la construction Bucket L2 est utilisée pour définir ces autorisations :

**Example**  

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as kms from 'aws-cdk-lib/aws-kms';

export class CdkDemoStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const key = new kms.Key(this, 'BucketKey');
    const bucket = new s3.Bucket(this, 'Bucket', {
      encryptionKey: key,
    });
    const handler = new lambda.Function(this, 'Handler', {
      runtime: lambda.Runtime.NODEJS_20_X,
      handler: 'index.handler',
      code: lambda.Code.fromAsset('lambda'),
    });

    // Define permissions between function and S3 bucket using the read method from BucketGrants
    bucket.grants.read(handler);

  }
}
```

```
const { Stack, Duration } = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');
const lambda = require('aws-cdk-lib/aws-lambda');
const kms = require('aws-cdk-lib/aws-kms');

class CdkDemoStack extends Stack {

  constructor(scope, id, props) {
    super(scope, id, props);

    const key = new kms.Key(this, 'BucketKey');
    const bucket = new s3.Bucket(this, 'Bucket', {
      encryptionKey: key,
    });
    const handler = new lambda.Function(this, 'Handler', {
      runtime: lambda.Runtime.NODEJS_20_X,
      handler: 'index.handler',
      code: lambda.Code.fromAsset('lambda'),
    });

    // Define permissions between function and S3 bucket using read method from BucketGrants
    bucket.grants.read(handler);

  }
}

// ...
```

```
from aws_cdk import (
    Stack,
    aws_s3 as s3,
    aws_lambda as _lambda,
    aws_kms as kms,
)
from constructs import Construct

class CdkDemoStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        key = kms.Key(self, 'BucketKey')
        bucket = s3.Bucket(self, 'Bucket')
        handler = _lambda.Function(
            self,
            'Handler',
            runtime = _lambda.Runtime.NODEJS_20_X,
            handler = 'index.handler',
            code = _lambda.Code.from_asset('lambda'),
        )

        # Define permissions between function and S3 bucket using the read method from BucketGrants
        bucket.grants.read(handler)
```

```
package com.myorg;

import software.amazon.awscdk.core.App;
import software.amazon.awscdk.core.Stack;
import software.amazon.awscdk.core.StackProps;
import software.amazon.awscdk.services.kms.Key;
import software.amazon.awscdk.services.kms.KeyProps;
import software.amazon.awscdk.services.s3.Bucket;
import software.amazon.awscdk.services.s3.BucketProps;
import software.amazon.awscdk.services.lambda.Function;
import software.amazon.awscdk.services.lambda.FunctionProps;
import software.amazon.awscdk.services.lambda.Runtime;
import software.amazon.awscdk.services.lambda.Code;
import software.constructs.Construct;

public class CdkDemoStack extends Stack {
    public CdkDemoStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkDemoStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        Key key = new Key(this, "BucketKey", KeyProps.builder().build());

        Bucket bucket = new Bucket(this, "Bucket", BucketProps.builder()
            .encryptionKey(key)
            .build());

        Function handler = new Function(this, "Handler", FunctionProps.builder()
            .runtime(Runtime.NODEJS_20_X)
            .handler("index.handler")
            .code(Code.fromAsset("lambda"))
            .build());

        // Define permissions between function and S3 bucket using the read method from BucketGrants
        bucket.getGrants().read(handler);
    }

    public static void main(final String[] args) {
        App app = new App();

        new CdkDemoStack(app, "CdkDemoStack");

        app.synth();
    }
}
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.KMS;
using Amazon.CDK.AWS.S3;
using Amazon.CDK.AWS.Lambda;

namespace CdkDemo
{
    public class CdkDemoStack : Stack
    {
        internal CdkDemoStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            var key = new Key(this, "BucketKey");

            var bucket = new Bucket(this, "Bucket", new BucketProps
            {
                EncryptionKey = key
            });

            var handler = new Function(this, "Handler", new FunctionProps
            {
                Runtime = Runtime.NODEJS_20_X,
                Handler = "index.handler",
                Code = Code.FromAsset("lambda")
            });

            // Define permissions between function and S3 bucket using the Read method from BucketGrants
            bucket.Grants.Read(handler);
        }
    }
}
```

```
package main
import (
    "github.com/aws/aws-cdk-go/awscdk/v2"
    "github.com/aws/aws-cdk-go/awscdk/v2/awskms"
    "github.com/aws/aws-cdk-go/awscdk/v2/awss3"
    "github.com/aws/aws-cdk-go/awscdk/v2/awslambda"
    "github.com/aws/constructs-go/constructs/v10"
    "github.com/aws/jsii-runtime-go"
)
// ...
func NewCdkDemoStack(scope constructs.Construct, id string, props *CdkDemoStackProps) awscdk.Stack {
    stack := awscdk.NewStack(scope, &id, &props.StackProps)
    key := awskms.NewKey(stack, jsii.String("BucketKey"), nil)
    bucket := awss3.NewBucket(stack, jsii.String("Bucket"), &awss3.BucketProps{
        EncryptionKey: key,
    })
    handler := awslambda.NewFunction(stack, jsii.String("Handler"), &awslambda.FunctionProps{
        Runtime: awslambda.Runtime_NODEJS_20_X(),
        Handler: jsii.String("index.handler"),
        Code:    awslambda.Code_FromAsset(jsii.String("lambda"), &awss3assets.AssetOptions{}),
    })
    bucket.Grants().Read(handler)
    return stack
}
// ...
```

Lorsque vous utilisez les méthodes d'attribution des constructions L2 pour définir des autorisations entre les ressources, le AWS CDK crée des rôles avec des politiques de moindre privilège en fonction de la méthode que vous spécifiez. Pour des raisons de sécurité, nous vous recommandons d'utiliser la méthode qui applique uniquement les autorisations dont vous avez besoin. Par exemple, si vous devez uniquement accorder des autorisations pour qu'une fonction Lambda puisse lire depuis un compartiment Amazon S3, utilisez la `grants.read` méthode au lieu de. `grants.readWrite`

Pour chaque méthode que vous utilisez, le CDK crée un rôle IAM unique pour les ressources spécifiées. Si nécessaire, vous pouvez également modifier directement la politique qui sera attachée au rôle. Voici un exemple :

**Example**  

```
import { aws_iam as iam } from 'aws-cdk-lib';

handler.addToRolePolicy(new iam.PolicyStatement({
  actions: ['s3:GetObject', 's3:List*'],
  resources: [
    bucket.bucketArn,
    bucket.arnForObjects('*'),
  ]
}));
```

```
const iam = require('aws-cdk-lib/aws-iam');

handler.addToRolePolicy(new iam.PolicyStatement({
  actions: ['s3:GetObject', 's3:List*'],
  resources: [
    bucket.bucketArn,
    bucket.arnForObjects('*'),
  ]
}));
```

```
from aws_cdk import aws_iam as iam

handler.add_to_role_policy(iam.PolicyStatement(
    actions=['s3:GetObject', 's3:List*'],
    resources=[
        bucket.bucket_arn,
        bucket.arn_for_objects('*'),
    ]
))
```

```
import software.amazon.awscdk.services.iam.PolicyStatement;
import software.amazon.awscdk.services.iam.PolicyStatementProps;

handler.addToRolePolicy(PolicyStatement.Builder.create()
    .actions(Arrays.asList("s3:GetObject", "s3:List*"))
    .resources(Arrays.asList(
        bucket.getBucketArn(),
        bucket.arnForObjects("*")
    ))
    .build());
```

```
using Amazon.CDK.AWS.IAM;
using Amazon.CDK.AWS.S3;
using Amazon.CDK.AWS.Lambda;

handler.AddToRolePolicy(new PolicyStatement(new PolicyStatementProps
{
    Actions = new[] { "s3:GetObject", "s3:List*" },
    Resources = new[] { bucket.BucketArn, bucket.ArnForObjects("*") }
}));
```

```
package main

import (
	// ...
	"github.com/aws/aws-cdk-go/awscdk/v2/awsiam"
	// ...
)

// ...

func NewCdkDemoStack(scope constructs.Construct, id string, props *CdkDemoStackProps) awscdk.Stack {
	// ...

	handler.AddToRolePolicy(awsiam.NewPolicyStatement(&awsiam.PolicyStatementProps{
		Actions:   jsii.Strings("s3:GetObject", "s3:List*"),
		Resources: jsii.Strings(bucket.BucketArn(), bucket.ArnForObjects("*")),
	}))

	// ...
}
```

Toutefois, nous vous recommandons d'utiliser les méthodes de la `grants` propriété lorsqu'elles sont disponibles.

## Création et utilisation manuelles de rôles IAM
<a name="define-iam-l2-manual"></a>

Si vous préférez ne pas utiliser les `grant` méthodes CDK pour créer et gérer les autorisations, vous devez les créer et les configurer manuellement. Vous pouvez créer des rôles IAM à l'aide de la console AWS de gestion, de la AWS CLI ou AWS SDKs. Ensuite, vous pouvez les transmettre manuellement à votre application CDK ou utiliser la fonctionnalité de *personnalisation des rôles*.

### Référencez et gérez manuellement tous les rôles
<a name="define-iam-l2-manual-role"></a>

Les constructions qui nécessitent un rôle possèdent une `role` propriété facultative que vous pouvez utiliser pour transmettre un objet de rôle.

 **Pour référencer un rôle manuellement**   

1. `Role.fromRoleName()`À utiliser pour faire référence à votre rôle préexistant. Voici un exemple :

   ```
   const existingRole = Role.fromRoleName(stack, 'Role', 'my-pre-existing-role', {
     mutable: false // Prevent CDK from attempting to add policies to this role
   })
   ```

1. Transmettez le rôle préexistant lors de la définition de votre ressource. Voici un exemple :

   ```
   const handler = new lambda.Function(stack, 'Handler', { runtime: lambda.Runtime.NODEJS_20_XZ, handler:
            'index.handler', code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')), // Pass in pre-existing role
            role: existingRole, });
   ```

### Utiliser la fonctionnalité de personnalisation des rôles
<a name="define-iam-l2-manual-customization"></a>

La fonctionnalité de *personnalisation des rôles AWS * CDK génère un rapport sur les rôles et les politiques de votre application CDK. Vous pouvez utiliser cette fonctionnalité pour générer un rapport. Vous pouvez ensuite leur substituer des rôles précréés.

 **Pour utiliser la fonctionnalité de personnalisation des rôles**   

1. Ajoutez `Role.customizeRoles()` quelque part en haut de votre application CDK. Voici un exemple :

   ```
   const stack = new Stack(app, 'LambdaStack');
   
   // Add this to use the role customization feature
   iam.Role.customizeRoles(stack);
   
   // Define your resources using L2 constructs
   const key = new kms.Key(stack, 'BucketKey');
   const bucket = new s3.Bucket(stack, 'Bucket', {
     encryptionKey: key,
   });
   const handler = new lambda.Function(stack, 'Handler', {
     runtime: lambda.Runtime.NODEJS_16_X,
     handler: 'index.handler',
     code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')),
   });
   
   // The grants.read() is still important. Even though it actually doesn't mutate
   // any policies, it indicates the need for them.
   bucket.grants.read(handler);
   ```

1. Lorsque vous synthétisez votre application, le CDK génère une erreur indiquant que vous devez fournir le nom de rôle précréé à. `Role.customizeRoles()` Voici un exemple du rapport généré :

   ```
   <missing role> (LambdaStack/Handler/ServiceRole)
   
   AssumeRole Policy:
   [
     {
       "Action": "sts:AssumeRole",
       "Effect": "Allow",
       "Principal": {
         "Service": "lambda.amazonaws.com"
       }
     }
   ]
   
   Managed Policy ARNs:
   [
     "arn:(PARTITION):iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
   ]
   
   Managed Policies Statements:
   NONE
   
   Identity Policy Statements:
   [
     {
       "Action": [
         "s3:GetObject*",
         "s3:GetBucket*",
         "s3:List*"
       ],
       "Effect": "Allow",
       "Resource": [
         "(LambdaStack/Bucket/Resource.Arn)",
         "(LambdaStack/Bucket/Resource.Arn)/*"
       ]
     }
   ]
   ```

1. Une fois le rôle créé, vous pouvez le transmettre à votre application pour la ressource à laquelle il s'applique. Par exemple, si le nom du rôle créé pour `LambdaStack/Handler/ServiceRole` est`lambda-service-role`, vous devez mettre à jour votre application CDK comme suit :

   ```
   const stack = new Stack(app, 'LambdaStack');
   
   // Add this to pass in the role
   iam.Role.customizeRoles(stack, {
     usePrecreatedRoles: {
       'LambdaStack/Handler/ServiceRole': 'lambda-service-role',
     },
   });
   ```

   Le CDK utilisera désormais le nom de rôle précréé partout où le rôle est référencé dans l'application CDK. Il continuera également à générer le rapport afin que toute future modification de politique puisse être référencée.

   Vous remarquerez que la référence à l'ARN du compartiment Amazon S3 dans le rapport est rendue sous la forme (`LambdaStack/Bucket/Resource.Arn`) au lieu de l'ARN réel du compartiment. Cela est dû au fait que l'ARN du bucket est une valeur temporelle de déploiement inconnue lors de la synthèse (le bucket n'a pas encore été créé). C'est un autre exemple de la raison pour laquelle nous recommandons d'autoriser CDK à gérer les rôles et les autorisations IAM en utilisant les méthodes fournies`grant`. Afin de créer le rôle avec la politique initiale, l'administrateur devra créer la politique avec des autorisations plus larges (par exemple,`arn:aws:s3:::*`).