

Este é o Guia do desenvolvedor do AWS CDK v2. O CDK v1 antigo entrou em manutenção em 1º de junho de 2022 e encerrou o suporte em 1º de junho de 2023.

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Defina permissões para construções L2 com o CDK AWS
<a name="define-iam-l2"></a>

Defina as funções e políticas do AWS Identity and Access Management (IAM) para construções L2 ao usar o Cloud Development AWS Kit (CDK).AWS 

## Usar métodos de concessão para definir permissões
<a name="define-iam-l2-grant"></a>

Ao definir sua infraestrutura usando construções L2 da AWS Construct Library, você pode usar os *métodos de concessão* fornecidos para especificar as permissões que seus recursos exigirão. O AWS CDK criará automaticamente as funções do IAM necessárias para todos os AWS recursos que precisam delas.

**dica**  
Os métodos Grant também funcionam com construções L1 por meio de classes de Grants. Para obter mais informações, consulte [Fachadas](facades.md).

Veja a seguir um exemplo que define permissões entre uma função AWS Lambda e o bucket do Amazon Simple Storage Service (Amazon S3). Aqui, o método `grants.read` do constructo L2 do bucket é usado para definir essas permissões:

**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
}
// ...
```

Quando você usa métodos de concessão de construções L2 para definir permissões entre recursos, o AWS CDK cria funções com políticas de privilégios mínimos com base no método especificado. Como prática recomendada de segurança, use o método que aplica somente as permissões necessárias. Por exemplo, se você só precisa conceder permissões para que uma função do Lambda leia de um bucket do Amazon S3, use o método `grants.read` em vez de `grants.readWrite`.

Para cada método que você usa, o CDK cria um perfil do IAM exclusivo para os recursos especificados. Se necessário, você também pode modificar diretamente a política que será anexada ao perfil. Este é um exemplo:

**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("*")),
	}))

	// ...
}
```

No entanto, recomendamos que você use os métodos na `grants` propriedade quando disponíveis.

## Criar e usar manualmente os perfis do IAM
<a name="define-iam-l2-manual"></a>

Se você preferir não usar os métodos `grant` do CDK para criar e gerenciar permissões, deverá criá-las e configurá-las manualmente. Você pode criar funções do IAM usando o AWS Management Console, a AWS CLI ou. AWS SDKs Em seguida, você pode passá-los para sua aplicação CDK manualmente ou usar o atributo de *personalização de perfis*.

### Referenciar e gerenciar todos os perfis manualmente
<a name="define-iam-l2-manual-role"></a>

Os constructos que exigem um perfil têm uma propriedade `role` opcional que você pode usar para transmitir um objeto de perfil.

 **Para referenciar uma função manualmente**   

1. Use `Role.fromRoleName()` para referenciar seu perfil preexistente. Este é um exemplo:

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

1. Passe o perfil preexistente ao definir seu recurso. Este é um exemplo:

   ```
   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, });
   ```

### Usar o atributo de personalização de perfis
<a name="define-iam-l2-manual-customization"></a>

O recurso de *personalização de funções* do AWS CDK gera um relatório de funções e políticas em seu aplicativo CDK. É possível usar esse atributo para gerar um relatório. Em seguida, você pode substituir perfis pré-criados para eles.

 **Para usar o recurso de personalização de funções**   

1. Adicione `Role.customizeRoles()` a algum lugar na parte superior da sua aplicação CDK. Este é um exemplo:

   ```
   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. Quando você sintetiza sua aplicação, o CDK gera um erro, indicando que você precisa fornecer o nome do perfil pré-criado para `Role.customizeRoles()`. O seguinte é um exemplo do relatório gerado:

   ```
   <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. Depois que o perfil for criado, será possível passá-lo para sua aplicação para o recurso ao qual ele se aplica. Por exemplo, se o nome do perfil criado para `LambdaStack/Handler/ServiceRole` for `lambda-service-role`, você atualizaria sua aplicação do CDK da seguinte forma:

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

   O CDK agora usará o nome do perfil pré-criado em qualquer lugar em que o perfil seja referenciado na aplicação CDK. Também continuará gerando o relatório para que quaisquer mudanças futuras na política possam ser referenciadas.

   Você notará que a referência ao ARN do bucket do Amazon S3 no relatório é renderizada como (`LambdaStack/Bucket/Resource.Arn`) em vez do ARN real do bucket. Isso ocorre porque o ARN do bucket é um valor de tempo de implantação que não é conhecido na síntese (o bucket ainda não foi criado). Esse é outro exemplo de por que recomendamos permitir que o CDK gerencie os perfis e permissões do IAM usando os métodos `grant` fornecidos. Para criar o perfil com a política inicial, o administrador precisará criar a política com permissões mais amplas (por exemplo, `arn:aws:s3:::*`).