모듈 4: 다른 AWS 서비스와 호환
학습 모듈
다른 AWS 서비스를 함께 사용하는 방법은 몇 가지가 있습니다.
액세스하려는 서비스가 SQL Server, Postgres와 같은 AWS RDS Database인 경우, 자체 컴퓨터 또는 데이터 센터에서 데이터베이스를 호스팅할 때와 동일한 라이브러리를 사용합니다. 사용자 이름과 암호가 포함된 연결 문자열이나 직접 선택한 다른 인증 형식이 필요합니다. 데이터베이스의 일상적인 사용 방법과 다를 것은 없습니다. 데이터베이스 서버에 액세스하기 위한 추가 권한은 필요하지 않습니다. 유일한 주의 사항이 있다면 데이터베이스에 공개적으로 액세스할 수 없는 경우에는 Lambda를 VPC에 연결해야 한다는 것입니다(이 프로세스에는 추가 권한이 필요함).
Lambda 함수가 S3, DynamoDB, Kinesis 등을 사용하는 경우 AWS SDK를 사용하여 해당 서비스와 상호 작용합니다. Lambda 함수가 실행되는 역할에는 각 서비스와 상호 작용하기 위한 적절한 권한이 필요합니다. 예를 들어, S3 버킷에 항목을 추가하려면 그 역할에 해당 버킷에 대한 쓰기 권한이 필요합니다. DynamoDB 테이블에서 항목을 가져오려면 그 역할에 해당 테이블을 읽을 수 있는 권한이 필요합니다.
세 번째 시나리오는 어떤 이벤트에 대한 응답으로 다른 서비스가 Lambda 함수를 트리거하고자 하는 경우에 해당합니다. 예를 들어, 새 항목이 특정 S3 버킷에 추가되거나 이벤트가 Kinesis 스트림에 도착할 때 Lambda 함수를 트리거할 수 있습니다. 이를 위해서는 Lambda 함수가 '리소스 기반 정책'을 사용해야 합니다. 이 정책은 다른 서비스에 Lambda 함수를 호출할 권한을 부여합니다.
소요 시간
30분
Lambda 함수에서 RDS Database Server에 액세스
SQL Server, Postgres, MySQL과 같이 친숙한 서비스를 사용할 때의 장점은 Lambda 함수에서 서비스를 호출할 때 코드와 관련하여 다른 작업을 수행할 필요가 없다는 것입니다. Entity Framework/ADO/NpgSql 등은 로컬/랙 데이터베이스와 마찬가지로 AWS 호스팅 데이터베이스에서도 잘 작동합니다. 동일한 방식으로 호출하면 AWS SDK 라이브러리가 필요하지 않습니다. 물론, 관련 NuGet 패키지는 프로젝트에 추가해야 합니다. 하지만 그 외에는 모두 똑같습니다.
Lambda 함수에서 AWS 서비스에 액세스
2. 모든 역할에 연결할 수 있는 독립 실행형 정책으로 생성합니다. AWS에서는 후자를 고객 관리형 정책이라고 합니다.
역할에 가능한 한 최소한의 권한을 부여하는 것이 좋습니다. DynamoDB 테이블에서 데이터를 읽는 다음 예시에서는 Lambda 역할에 dynamodb:GetItem과 dynamodb:DescribeTable이라는 두 가지 권한을 부여해야 합니다. 그리고 해당 권한을 관심 있는 특정 테이블로 제한합니다.
먼저 People이라는 새 DynamoDB 테이블을 생성합니다. Windows 명령 프롬프트를 사용하는 경우, PowerShell에서 다음 명령을 사용할 수 있습니다. 그렇지 않으면 Linux 쉘에서는 문자열에 대해 다른 이스케이프가 필요합니다.
다음을 실행합니다.
aws dynamodb create-table --table-name People --attribute-definitions AttributeName=PersonId,AttributeType=N --key-schema AttributeName=PersonId,KeyType=HASH --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1
테이블에 몇 가지 항목을 추가합니다.
aws dynamodb put-item --table-name People --item '{"PersonId":{"N":"1"},"State":{"S":"MA"}, "FirstName": {"S":"Alice"}, "LastName": {"S":"Andrews"}}'
aws dynamodb put-item --table-name People --item '{"PersonId":{"N":"2"},"State":{"S":"MA"}, "FirstName": {"S":"Ben"}, "LastName": {"S":"Bradley"}}'
aws dynamodb put-item --table-name People --item '{"PersonId":{"N":"3"},"State":{"S":"MA"}, "FirstName": {"S":"Claire"}, "LastName": {"S":"Connor"}}'
이제 다음을 사용하여 Lambda 함수를 생성합니다.
dotnet new lambda.EmptyFunction -n LambdaFunctionDynamoDB
cd LambdaFunctionDynamoDB /src/LambdaFunctionDynamoDB
dotnet add package AWSSDK.DynamoDBv2
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DataModel;
using Amazon.Lambda.Core;
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
namespace LambdaFunctionDynamoDB ;
public class Function
{
public async Task<string> FunctionHandler(ILambdaContext lambdaContext)
{
AmazonDynamoDBConfig clientConfig = new AmazonDynamoDBConfig();
AmazonDynamoDBClient client = new AmazonDynamoDBClient(clientConfig);
DynamoDBContext dynamoDbContext = new DynamoDBContext(client);
Person person = await dynamoDbContext.LoadAsync<Person>(1);
return $"{person.FirstName} {person.LastName} lives in {person.State}";
}
}
[DynamoDBTable("People")]
public class Person
{
[DynamoDBHashKey]
public int PersonId {get; set;}
public string State {get; set;}
public string FirstName {get; set;}
public string LastName {get; set;}
}
dotnet lambda deploy-function LambdaFunctionDynamoDB
다음을 사용하여 Lambda 함수를 AWS Lambda에 배포합니다.
dotnet lambda deploy-function LambdaFunctionDynamoDB
그러면 '코드에 AWS 보안 인증을 제공할 IAM 역할 선택:'이라는 메시지가 표시되어 이전에 생성한 역할 목록이 표시됩니다. 목록 하단에 ‘*** 새 IAM 역할 생성***’ 옵션이 표시되며 해당 옵션 옆에 번호를 입력합니다.
'새 IAM 역할 이름 입력:'을 묻는 메시지가 표시됩니다. 'LambdaFunctionDynamoDBRole'을 입력합니다.
그러면 '새 역할에 연결하고 권한을 부여할 IAM 정책을 선택하세요'라는 메시지가 표시되고 정책 목록이 나옵니다. AWSLambdaBasicExecutionRole를 선택합니다. 이 번호는 제 목록 6번에 있습니다. (AWSLambdaDynamoDBExecutionRole이라는 정책이 있다는 것은 알고 있지만, 이 모듈의 목표는 필요한 권한을 직접 추가하는 방법을 보여주는 것입니다.)
그런 다음, Lambda 함수를 다시 호출합니다.
dotnet lambda invoke-function LambdaFunctionDynamoDB
"errorMessage": "User: arn:aws:sts::YOUR_ACCOUNT_NUMBER:assumed-role/LambdaFunctionDynamoDB Role/LambdaFunctionDynamoDB is not authorized to perform: dynamodb:DescribeTable on resource: arn:aws:dynamodb:us-east-1:YOUR_ACCOUNT_NUMBER:table/People because no identity-based policy allows the dynamodb:DescribeTable action"
이는 Lambda 함수가 실행 중인 역할에 필요한 DynamoDB:DescribeTable 권한이 없다는 것을 의미합니다.
이 문제를 해결하려면 역할에 DynamoDB:DescribeTable 권한을 부여하는 정책을 추가해야 합니다. 위에서 언급했듯이 인라인 정책(이 역할에만 해당) 또는 독립 실행형 정책(모든 역할에서 사용 가능)을 추가할 수 있습니다.
LambdaFunctionDynamoDB 폴더(/src/LambdaFunctionDynamoDB)에 DynamoDBAccessPolicy.json 파일을 생성합니다.
DynamoDBAccessPolicy를 편집하되, 리소스에 계정 번호를 사용하세요.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:DescribeTable"
],
"Resource": "arn:aws:dynamodb:us-east-1:YOUR_ACCOUNT_NUMBER:table/People"
}
]
}
aws iam put-role-policy --role-name LambdaFunctionDynamoDBRole --policy-name LambdaFunctionDynamoDBAccess --policy-document file://DynamoDBAccessPolicy.json
dotnet lambda deploy-function LambdaFunctionDynamoDB
dotnet lambda invoke-function LambdaFunctionDynamoDB
이번 메시지는 다음과 같습니다.
"errorMessage": "User: arn:aws:sts::YOUR_ACCOUNT_NUMBER:assumed-role/LambdaFunctionDynamoDB Role/LambdaFunctionDynamoDB is not authorized to perform: dynamodb:GetItem on resource: arn:aws:dynamodb:us-east-1:YOUR_ACCOUNT_NUMBER:table/People because no identity-based policy allows the dynamodb:GetItem action",
DynamoDBAccessPolicy.json 파일을 다음과 같이 업데이트합니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:DescribeTable",
"dynamodb:GetItem"
],
"Resource": "arn:aws:dynamodb:us-east-1:YOUR_ACCOUNT_NUMBER:table/People"
}
]
}
dotnet lambda deploy-function LambdaFunctionDynamoDB
dotnet lambda invoke-function LambdaFunctionDynamoDB
Amazon Lambda Tools for .NET Core applications (5.4.2)
Project Home: https://github.com/aws/aws-extensions-for-dotnet-cli, https://github.com/aws/aws-lambda-dotnet
Payload:
"Alice Andrews lives in MA"
사용 중인 SDK 메서드 위로 마우스를 가져가는 방법도 있습니다. 메타데이터에는 권한에 대한 유용한 정보가 포함되어 있을 수 있습니다. 모든 메서드 메타데이터에 권한 정보가 포함된 것은 아닙니다.
이제 함수에 필요한 권한을 찾는 방법과 Lambda 함수가 실행되는 역할에 올바른 권한을 부여하는 방법을 알게 되었습니다.
다른 서비스가 Lambda 함수를 호출하도록 허용
이전 단원에서는 Lambda 함수에 다른 서비스에서 작업을 수행할 수 있는 권한을 부여하는 방법을 배웠습니다. 이 단원에서는 Lambda 함수를 호출할 수 있는 권한을 다른 서비스에 부여하는 방법을 알아봅니다.
serverless.* 템플릿을 사용하는 경우, 이미 Lambda 함수를 호출하는 데 필요한 권한을 API Gateway에 부여했을 것입니다. 이러한 기능을 배포한 경우, 구성 탭으로 이동하고 왼쪽에서 권한을 선택한 다음, 리소스 기반 정책 섹션으로 스크롤합니다. API Gateway가 Lambda 함수를 호출하도록 허용하는 정책을 확인할 수 있습니다. 이 정책은 dotnet lambda deploy-serverless 명령 및 프로젝트의 serverless.template을 통해 추가했습니다.
아래 이미지에서 API Gateway가 Lambda 함수를 호출하도록 허용하는 두 가지 정책 설명을 볼 수 있습니다.
S3 버킷 생성
버킷을 us-east-1에 두고 싶다면 다음 명령을 사용할 수 있습니다.
aws s3api create-bucket --bucket my-unique-bucket-name-lambda-course
aws s3api create-bucket --bucket my-unique-bucket-name-lambda-course --create-bucket-configuration LocationConstraint=REGION
Lambda 함수 생성
명령줄에서 다음을 실행합니다.
dotnet new lambda.S3 -n S3EventHandler
cd S3EventHandler/src/S3EventHandler
public async Task FunctionHandler(S3Event evnt, ILambdaContext context)
{
context.Logger.LogInformation($"A S3 event has been received, it contains {evnt.Records.Count} records.");
foreach (var s3Event in evnt.Records)
{
context.Logger.LogInformation($"Action: {s3Event.EventName}, Bucket: {s3Event.S3.Bucket.Name}, Key: {s3Event.S3.Object.Key}");
if (!s3Event.EventName.Contains("Delete"))
{
try
{
var response = await this.S3Client.GetObjectMetadataAsync(s3Event.S3.Bucket.Name, s3Event.S3.Object.Key);
context.Logger.LogInformation( $"The file type is {response.Headers.ContentType}");
}
catch (Exception e)
{
context.Logger.LogError(e.Message);
context.Logger.LogError($"An exception occurred while retrieving {s3Event.S3.Bucket.Name}/{s3Event.S3.Object.Key}. Exception - ({e.Message})");
}
}
else
{
context.Logger.LogInformation($"You deleted {s3Event.S3.Bucket.Name}/{s3Event.S3.Object.Key}");
}
}
}
S3 이벤트가 객체 삭제에 대한 응답인 경우, 함수는 버킷/키 이름을 CloudWatch에 기록합니다.
Lambda 함수 배포
dotnet lambda deploy-function S3EventHandler
그러면 '코드에 AWS 보안 인증을 제공할 IAM 역할 선택:'이라는 메시지가 표시되어 이전에 생성한 역할 목록이 표시됩니다. 목록 하단에 ‘*** 새 IAM 역할 생성***’ 옵션이 표시되며 해당 옵션 옆에 번호를 입력합니다.
'새 IAM 역할 이름 입력:'을 묻는 메시지가 표시됩니다. 'S3EventHandlerRole'을 입력합니다.
그러면 '새 역할에 연결하고 권한을 부여할 IAM 정책을 선택하세요'라는 메시지가 표시되고 정책 목록이 나옵니다. AWSLambdaBasicExecutionRole를 선택합니다. 이 번호는 제 목록 6번에 있습니다. GetObjectMetadataAsync(..)를 호출하려면 S3 버킷에 대한 액세스 권한을 부여하는 정책을 추가해야 합니다.
Lambda 함수에 객체 메타데이터를 가져오기 위한 권한 부여
이 작업을 수행하는 방법은 몇 가지가 있습니다.
정책은 다음과 같지만 리소스에 버킷 이름이 표시됩니다. 끝에 있는 /*에 주의하세요. 이는 s3:GetObject가 버킷의 모든 객체에 적용된다는 것을 의미합니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::my-unique-bucket-name-lambda-course/*"
}
]
}
aws iam create-policy --policy-name S3AccessPolicyForCourseBucket --policy-document file://S3AccessPolicyForCourseBucket.json
그런 다음, 이전에 생성한 역할에 정책을 연결합니다. 다음을 실행합니다.
aws iam attach-role-policy --role-name S3EventHandlerRole --policy-arn arn:aws:iam::694977046108:policy/S3AccessPolicyForCourseBucket
구성 탭을 클릭한 다음, 왼쪽의 권한을 클릭하고 역할 이름을 클릭합니다.
권한 추가를 클릭하고 정책 연결을 클릭합니다.
정책 생성을 클릭합니다.
작업 섹션에서 getobject를 입력하고 목록에서 GetObject를 선택합니다.
리소스 섹션에서 특정을 선택하고 ARN 추가를 클릭합니다.
정책 생성을 클릭한 탭으로 돌아갑니다. 다음 단계를 따르세요.
1. 정책 목록을 다시 로드합니다.
2. 필터에 S3AccessPolicyForCourseBucket을 입력합니다.
3. 정책 옆의 상자를 선택합니다.
4. 정책 연결을 클릭합니다.
S3 버킷, Lambda 함수 및 S3 버킷에서 객체 메타데이터를 가져오는 데 필요한 권한이 생겼습니다.
이제 S3 버킷을 Lambda 함수에 연결할 차례입니다. 그러면 생성 및 삭제 이벤트가 Lambda 함수를 트리거합니다.
S3 버킷에서 Lambda 함수를 트리거합니다.
S3 https://s3.console.aws.amazon.com/s3/buckets에서 버킷 목록을 엽니다.
생성한 것을 클릭합니다.
아래로 스크롤하여 이벤트 알림 섹션으로 이동합니다.
이벤트 알림 생성을 클릭합니다.
이벤트 알림의 이름을 입력합니다.
왼쪽의 첫 번째 확인란 두 개(모든 객체 생성 이벤트, 모든 객체 제거 이벤트)를 선택합니다.
하단의 대상 섹션으로 스크롤합니다.
Lambda 함수를 대상으로 선택합니다.
드롭다운 목록에서 이전에 생성한 Lambda 함수의 이름을 입력합니다.
변경 사항 저장을 클릭합니다.
AWS Console에 앞서 생성한 Lambda 함수로 이동합니다.
참고로 S3는 이제 Lambda 함수의 트리거로 나열되어 있습니다.
구성 탭을 클릭한 다음, 왼쪽의 권한을 클릭합니다.
S3가 Lambda 함수를 호출할 수 있도록 허용하는 정책 문이 표시됩니다.
테스트하기
대신 Lambda 함수가 CloudWatch에 로그인하므로 함수가 작동하는지 확인하려면 해당 함수로 이동해야 합니다.
컴퓨터에 텍스트 파일을 생성하여 S3에 업로드합니다.
명령줄에서 다음을 실행합니다.
aws s3api put-object --bucket my-unique-bucket-name-lambda-course --key Hello.txt --body Hello.txt --content-type "text/plain"
aws s3api delete-object --bucket my-unique-bucket-name-lambda-course --key Hello.txt
이제 AWS Console의 Lambda 함수로 이동하여 로그를 확인하세요.
모니터 탭을 클릭한 다음, CloudWatch에서 로그 보기를 클릭합니다.
과정은 세 가지 방법 모두 비슷합니다. AWS 확장 프로그램을 열고 CloudWatch 로그를 클릭한 다음, /aws/lambda/S3EventHandler에 대한 로그 스트림/그룹을 찾습니다. 그런 다음, 가장 최근 스트림을 엽니다.
과정은 세 가지 방법 모두 비슷합니다. AWS 확장 프로그램을 열고 CloudWatch 로그를 클릭한 다음, /aws/lambda/S3EventHandler에 대한 로그 스트림/그룹을 찾습니다. 그런 다음, 가장 최근 스트림을 엽니다.
결론
중요한 점은 Lambda 함수가 다른 AWS 서비스와 상호 작용하도록 하려면 함수에 다른 서비스에서 작동할 권한을 부여해야 한다는 것입니다.
다른 서비스가 함수를 호출하도록 하려면 리소스 기반 정책을 사용하여 해당 서비스에 함수에 대한 액세스 권한을 부여해야 합니다.
지식 확인
1. 다른 서비스가 Lambda 함수를 호출하도록 하려면 어떻게 해야 합니까?(하나 선택)
b. 호출 서비스에 Lambda 함수를 호출할 권한을 부여하는 리소스 기반 정책 문서를 생성합니다.
c. 아무것도 하지 않습니다. Lambda는 다른 모든 AWS 서비스를 신뢰합니다.
d. Lambda 함수가 as1로 실행하는 역할에 올바른 권한을 추가합니다.
2. AWS 서비스에 액세스할 권한을 부여하려면 역할에 무엇을 추가해야 합니까?(하나 선택)
b. 리소스 기반 정책
c. 필수적인 권한이 있는 정책
d. 액세스 제어 목록 문서
3. Lambda 함수가 실행되는 역할과 함께 사용할 고객 관리형 정책을 생성하는 두 가지 방법은 무엇입니까?(두 개 선택)
a. 명령줄 사용
b. 함수의 소스 코드에 포함
c. AWS Console 사용
d. 함수를 실행할 때 페이로드에 추가
정답: 1-b, 2-c, 3-ac
결론
중요한 점은 Lambda 함수가 다른 AWS 서비스와 상호 작용하도록 하려면 함수에 다른 서비스에서 작동할 권한을 부여해야 한다는 것입니다.
다른 서비스가 함수를 호출하도록 하려면 리소스 기반 정책을 사용하여 해당 서비스에 함수에 대한 액세스 권한을 부여해야 합니다.