AWS 가 Tag Editor 태그 관리 기능을 AWS Resource Groups 콘솔에서 AWS 리소스 탐색기 콘솔로 이동했습니다. Resource Explorer를 사용하면 리소스를 검색 및 필터링한 다음 단일 콘솔에서 리소스 태그를 관리할 수 있습니다. Resource Explorer의 리소스 태그 관리에 대한 자세한 내용은 Resource Explorer 사용 설명서의 리소스 관리를 참조하세요.
기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
자습서: 필수 태그가 누락된 Amazon EC2 인스턴스 자동 중지하기
AWS 계정 관리하는 AWS 리소스 풀이 증가하면 태그를 사용하여 리소스를 더 쉽게 분류할 수 있습니다. 태그는 일반적으로 비용 할당 및 보안과 같은 중요한 사용 사례에 사용됩니다. AWS 리소스를 효과적으로 관리하려면 리소스에 일관되게 태그를 지정해야 합니다. 리소스가 프로비저닝될 때 적절한 태그를 모두 가져오는 경우가 많습니다. 하지만 이후 프로세스에서 태그가 변경되어 회사 태그 정책에서 벗어날 수 있습니다. 태그 변경 사항을 모니터링하면 태그 드리프트를 발견하고 즉시 대응할 수 있습니다. 이를 통해 리소스를 적절하게 분류하는 프로세스가 원하는 결과를 가져올 것이라는 확신을 가질 수 있습니다.
다음 예는 Amazon EC2 인스턴스에서 태그 변경을 모니터링하여 지정된 인스턴스에 필요한 태그가 계속 있는지 확인할 수 있는 방법을 설명합니다. 인스턴스의 태그가 변경되어 인스턴스에 더 이상 필요한 태그가 없는 경우, Lambda 함수를 호출하여 인스턴스가 자동으로 종료됩니다. 왜 이런 작업이 필요할까요? 기업 태그 정책에 따라 모든 리소스에 태그가 지정되면 효과적으로 비용을 할당할 수 있으며, ABAC(속성 기반 액세스 제어)를 기반으로 보안을 신뢰할 수 있습니다.
중요
중요한 인스턴스를 실수로 종료해서는 안 되는 비프로덕션 계정에서 이 자습서를 수행할 것을 강력히 권장합니다.
이 자습서의 예제 코드는 의도적으로 이 시나리오의 영향을 인스턴스 ID 목록에 있는 인스턴스로 제한합니다. 테스트를 위해 종료할 인스턴스 ID로 목록을 업데이트해야 합니다. 이렇게 하면의 리전에 있는 모든 인스턴스를 실수로 종료할 수 없습니다 AWS 계정.
테스트 후에는 회사의 태그 지정 전략에 따라 모든 인스턴스에 태그가 지정되었는지 확인합니다. 그런 다음, 함수를 목록에 있는 인스턴스 ID로 제한하는 코드를 제거하면 됩니다.
이 예에서는 JavaScript 및 16.x 버전의 Node.js를 사용합니다. 이 예제에서는 예제 AWS 계정 ID 123456789012과 AWS 리전 미국 동부(버지니아 북부)()를 사용합니다us-east-1
. 이를 계정 ID과 리전으로 바꿉니다.
참고
콘솔이 기본값으로 다른 리전을 사용하는 경우, 콘솔을 변경할 때마다 이 자습서에서 사용 중인 리전을 변경해야 합니다. 이 자습서가 실패하는 일반적인 원인은 인스턴스와 함수를 서로 다른 두 리전에 두고 있기 때문입니다.
us-east-1
와 다른 리전을 사용하는 경우, 다음 코드 예시에 있는 모든 참조를 선택한 리전으로 변경해야 합니다.
주제
1단계. Lambda 함수 생성
Lambda 함수를 만들려면
-
AWS Lambda 관리 콘솔
을 엽니다. -
함수 생성을 선택한 다음 새로 작성를 선택합니다.
-
함수 이름에
AutoEC2Termination
을 입력합니다. -
런타임에는 Node.js 16.x를 선택합니다.
-
다른 필드를 기본값으로 그대로 두고 함수 생성을 선택합니다.
-
AutoEC2Termination
세부 정보 페이지의 코드 탭에서 index.js 파일을 열어 코드를 확인합니다.-
index.js 탭이 열려 있는 경우, 해당 탭의 편집 상자를 선택하여 코드를 편집할 수 있습니다.
-
index.js 탭이 열려 있지 않은 경우, 탐색 창의 AutoEC2Terminator 폴더에 있는 index.js 파일에서 마우스 오른쪽 버튼을 클릭합니다. 그런 다음 열기을 선택합니다.
-
-
index.js 탭에서 편집 상자에 다음 코드를 붙여넣고 이미 있는 코드를 대체합니다.
값
RegionToMonitor
을 이 함수를 실행할 리전으로 바꿉니다.// Set the following line to specify which Region's instances you want to monitor // Only instances in this Region are succesfully stopped on a match const RegionToMonitor = "us-east-1" // Specify the instance ARNs to check. // This limits the function for safety to avoid the tutorial shutting down all instances in account // The first ARN is a "dummy" that matches the test event you create in Step 3. // Replace the second ARN with one that matches a real instance that you want to monitor and that you can // safely stop const InstanceList = [ "i-0000000aaaaaaaaaa", "i-05db4466d02744f07" ]; // The tag key name and value that marks a "valid" instance. Instances in the previous list that // do NOT have the following tag key and value are stopped by this function const ValidKeyName = "valid-key"; const ValidKeyValue = "valid-value"; // Load and configure the AWS SDK const AWS = require('aws-sdk'); // Set the AWS Region AWS.config.update({region: RegionToMonitor}); // Create EC2 service object. const ec2 = new AWS.EC2({apiVersion: '2016-11-15'}); exports.handler = (event, context, callback) => { // Retrieve the details of the reported event. var detail = event.detail; var tags = detail["tags"]; var service = detail["service"]; var resourceType = detail["resource-type"]; var resource = event.resources[0]; var resourceSplit = resource.split("/"); var instanceId = resourceSplit[resourceSplit.length - 1]; // If this event is not for an EC2 resource, then do nothing. if (!(service === "ec2")) { console.log("Event not for correct service -- no action (", service, ")" ); return; } // If this event is not about an instance, then do nothing. if (!(resourceType === "instance")) { console.log("Event not for correct resource type -- no action (", resourceType, ")" ); return; } // CAUTION - Removing the following 'if' statement causes the function to run against // every EC2 instance in the specified Region in the calling AWS 계정. // If you do this and an instance is not tagged with the approved tag key // and value, this function stops that instance. // If this event is not for the ARN of an instance in our include list, then do nothing. if (InstanceList.indexOf(instanceId)<0) { console.log("Event not for one of the monitored instances -- no action (", resource, ")"); return; } console.log("Tags changed on monitored EC2 instance (",instanceId,")"); // Check attached tags for expected tag key and value pair if ( tags.hasOwnProperty(ValidKeyName) && tags[ValidKeyName] == "valid-value"){ // Required tags ARE present console.log("The instance has the required tag key and value -- no action"); callback(null, "no action"); return; } // Required tags NOT present console.log("This instance is missing the required tag key or value -- attempting to stop the instance"); var params = { InstanceIds: [instanceId], DryRun: true }; // call EC2 to stop the selected instances ec2.stopInstances(params, function(err, data) { if (err && err.code === 'DryRunOperation') { // dryrun succeeded, so proceed with "real" stop operation params.DryRun = false; ec2.stopInstances(params, function(err, data) { if (err) { console.log("Failed to stop instance"); callback(err, "fail"); } else if (data) { console.log("Successfully stopped instance", data.StoppingInstances); callback(null, "Success"); } }); } else { console.log("Dryrun attempt failed"); callback(err); } }); };
-
배포를 선택하여 변경 사항을 저장하고 새 버전의 함수를 활성화합니다.
이 Lambda 함수는 EventBridge의 태그 변경 이벤트에서 보고한 대로 Amazon EC2 인스턴스의 태그를 확인합니다. 이 예에서 이벤트의 인스턴스에 필수 태그 키 valid-key
가 없거나 해당 태그에 값 valid-value
가 없는 경우 함수는 인스턴스를 중지하려고 시도합니다. 특정 사용 사례에 맞게 이 논리적 검사 또는 태그 요구 사항을 변경할 수 있습니다.
브라우저에서 Lambda 콘솔 창을 열어 둡니다.
2단계. 필요한 IAM 권한 설정
함수를 성공적으로 실행하려면 먼저 함수에 EC2 인스턴스를 중지할 수 있는 권한을 부여해야 합니다. AWS 제공된 역할에는 해당 권한이 lambda_basic_executionAutoEC2Termination-role-
라는 함수의 실행 역할에 첨부된 기본 IAM 권한 정책을 수정합니다. 이 자습서에 필요한 최소 추가 권한은 uniqueid
ec2:StopInstances
입니다.
Amazon EC2별 IAM 정책을 생성하는 방법에 대한 자세한 내용은 IAM 사용 설명서의 Amazon EC2: 프로그래밍 방식과 콘솔에서 EC2 인스턴스를 시작 또는 중지하고 보안 그룹 수정하기를 참조하십시오.
IAM 권한 정책을 생성하여 Lambda 함수의 실행 역할에 연결하는 방법
-
다른 브라우저 탭 또는 창에서 IAM 콘솔의 역할
페이지를 엽니다. -
역할 이름
AutoEC2Termination
을 입력하고, 목록에 역할 이름이 나타나면 해당 역할 이름을 선택합니다. -
역할의 요약 페이지에서 권한 탭을 선택하고 이미 연결된 정책의 이름을 선택합니다.
-
정책의 요약 페이지에서 정책 편집를 선택합니다.
-
시각적 편집기 탭에서 추가 권한 추가를 선택합니다.
-
서비스에서 EC2를 선택합니다.
-
작업에서 인스턴스 중지를 선택합니다. 검색 창에
Stop
를 입력한 다음 표시되는StopInstances
를 선택합니다. -
리소스의 경우, 모든 리소스를 선택하고 정책 검토를 선택한 다음 변경 사항 저장을 선택합니다.
그러면 새 버전의 정책이 자동으로 생성되고 이 버전이 기본으로 설정됩니다.
최종 파일은 다음 예제와 비슷할 것입니다.
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": "ec2:StopInstances", "Resource": "*" }, { "Sid": "VisualEditor1", "Effect": "Allow", "Action": "logs:CreateLogGroup", "Resource": "arn:aws:logs:us-east-1:123456789012:*" }, { "Sid": "VisualEditor2", "Effect": "Allow", "Action": [ "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:us-east-1:123456789012:log-group:/aws/lambda/AutoEC2Termination:*" } ] }
3단계. Lambda 함수의 예비 테스트 수행
이 단계에서는 함수에 테스트 이벤트를 제출합니다. Lambda 테스트 기능은 수동으로 제공된 테스트 이벤트를 제출하는 방식입니다. 함수는 이벤트가 EventBridge에서 발생한 것처럼 테스트 이벤트를 처리합니다. 값이 다른 여러 테스트 이벤트를 정의하여 코드의 다양한 부분을 모두 실행할 수 있습니다. 이 단계에서는 Amazon EC2 인스턴스의 태그가 변경되었으며 새 태그에 필수 태그 키와 값이 포함되어 있지 않음을 나타내는 테스트 이벤트를 제출합니다.
Lambda 함수를 테스트하는 방법
-
Lambda 콘솔이 있는 창 또는 탭으로 돌아가서 AutoEC2Termination 함수의 테스트 탭을 엽니다.
-
새 역할 생성을 선택합니다.
-
이벤트 이름에
SampleBadTagChangeEvent
를 입력합니다. -
Event JSON에서 텍스트를 다음 예제 텍스트에 표시된 샘플 이벤트로 변경합니다. 계정, 리전 또는 인스턴스 ID를 수정하지 않아도 이 테스트 이벤트는 제대로 작동합니다.
{ "version": "0", "id": "bddcf1d6-0251-35a1-aab0-adc1fb47c11c", "detail-type": "Tag Change on Resource", "source": "aws.tag", "account": "123456789012", "time": "2018-09-18T20:41:38Z", "region": "us-east-1", "resources": [ "arn:aws:ec2:us-east-1:123456789012:instance/i-0000000aaaaaaaaaa" ], "detail": { "changed-tag-keys": [ "valid-key" ], "tags": { "valid-key": "NOT-valid-value" }, "service": "ec2", "resource-type": "instance", "version": 3 } }
-
저장를 선택한 다음 테스트를 선택합니다.
테스트가 실패한 것처럼 보이지만 괜찮습니다.
대응의 실행 결과 탭에 다음 오류가 표시됩니다.
{ "errorType": "InvalidInstanceID.NotFound", "errorMessage": "The instance ID 'i-0000000aaaaaaaaaa' does not exist", ... }
이 오류는 테스트 이벤트에 지정된 인스턴스가 존재하지 않기 때문에 발생합니다.
함수 로그의 실행 결과 탭에 있는 정보를 통해 Lambda 함수에서 EC2 인스턴스 중지를 성공적으로 시도했음을 알 수 있습니다. 하지만 코드에서 처음에 인스턴스를 중지하기 위해
DryRun
작업을 시도했으나 인스턴스 ID가 유효하지 않은 것으로 확인되어 실패했습니다.START RequestId: 390c1f8d-0d9b-4b44-b087-8de64479ab44 Version: $LATEST 2022-11-30T20:17:30.427Z 390c1f8d-0d9b-4b44-b087-8de64479ab44 INFO Tags changed on monitored EC2 instance ( i-0000000aaaaaaaaaa ) 2022-11-30T20:17:30.427Z 390c1f8d-0d9b-4b44-b087-8de64479ab44 INFO This instance is missing the required tag key or value -- attempting to stop the instance 2022-11-30T20:17:31.206Z 390c1f8d-0d9b-4b44-b087-8de64479ab44 INFO Dryrun attempt failed 2022-11-30T20:17:31.207Z 390c1f8d-0d9b-4b44-b087-8de64479ab44 ERROR Invoke Error {"errorType":"InvalidInstanceID.NotFound","errorMessage":"The instance ID 'i-0000000aaaaaaaaaa' does not exist","code":"InvalidInstanceID.NotFound","message":"The instance ID 'i-0000000aaaaaaaaaa' does not exist","time":"2022-11-30T20:17:31.205Z","requestId":"a5192c3b-142d-4cec-bdbc-685a9b7c7abf","statusCode":400,"retryable":false,"retryDelay":36.87870631147607,"stack":["InvalidInstanceID.NotFound: The instance ID 'i-0000000aaaaaaaaaa' does not exist"," at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/services/ec2.js:50:35)"," at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20)"," at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10)"," at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:686:14)"," at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)"," at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)"," at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10"," at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)"," at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:688:12)"," at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18)"]} END RequestId: 390c1f8d-0d9b-4b44-b087-8de64479ab44
-
올바른 태그를 사용했음에도 코드에서 인스턴스를 중지하려고 시도하지 않았다는 것을 증명하기 위해 다른 테스트 이벤트를 만들어 제출해보겠습니다.
코드 소스 위에 있는 테스트 탭을 선택합니다. 콘솔에는 기존 SampleBadTagChangeEvent 테스트 이벤트가 표시됩니다.
-
새 역할 생성을 선택합니다.
-
이벤트 이름에
SampleGoodTagChangeEvent
를 입력합니다. -
17행에서
NOT-
를 삭제하여 값을valid-value
로 변경합니다. -
테스트 이벤트 창 상단에서 저장를 선택한 다음 테스트를 선택합니다.
결과는 다음과 같이 표시되며, 이를 통해 함수가 유효한 태그를 인식하고 인스턴스 종료를 시도하지 않았음을 알 수 있습니다.
START RequestId: 53631a49-2b54-42fe-bf61-85b9e91e86c4 Version: $LATEST 2022-12-01T23:24:12.244Z 53631a49-2b54-42fe-bf61-85b9e91e86c4 INFO Tags changed on monitored EC2 instance ( i-0000000aaaaaaaaaa ) 2022-12-01T23:24:12.244Z 53631a49-2b54-42fe-bf61-85b9e91e86c4 INFO The instance has the required tag key and value -- no action END RequestId: 53631a49-2b54-42fe-bf61-85b9e91e86c4
브라우저에서 Lambda 콘솔을 열어둡니다.
4단계. 함수를 실행하는 EventBridge 규칙을 만듭니다.
이제 이벤트와 일치하고 Lambda 함수를 가리키는 EventBridge 규칙을 만들 수 있습니다.
EventBridge 규칙을 만드는 방법
-
다른 브라우저 탭 또는 창에서 EventBridge 콘솔
을 열고 규칙 생성 페이지를 엽니다. -
이름에
ec2-instance-rule
을 입력한 후 다음를 선택합니다. -
아래로 스크롤하여 생성 방법으로 이동한 다음 사용자 정의 패턴(JSON 편집기)을 선택합니다.
-
편집 상자에 다음 패턴 텍스트를 붙여넣고 다음를 선택합니다.
{ "source": [ "aws.tag" ], "detail-type": [ "Tag Change on Resource" ], "detail": { "service": [ "ec2" ], "resource-type": [ "instance" ] } }
이 규칙은 Amazon EC2 인스턴스의
Tag Change on Resource
이벤트를 매칭하고 다음 단계에서 대상으로 지정한 모든 이벤트를 호출합니다. -
다음으로, Lambda 함수를 대상으로 추가합니다. 대상 1 상자의 대상 선택에서 Lambda 함수를 선택합니다.
-
함수에서 이전에 생성한 AutoEC2Termination 함수를 선택한 후 다음를 선택합니다.
-
태그 구성 페이지에서 다음를 선택합니다. 검토 및 생성 페이지에서 규칙 생성을 선택합니다. 이렇게 하면 EventBridge가 지정된 Lambda 함수를 호출할 수 있는 권한도 자동으로 부여됩니다.
5단계. 전체 솔루션을 테스트합니다.
EC2 인스턴스를 만들고 해당 태그를 변경할 때 어떤 일이 발생하는지 관찰하는 방식으로 최종 결과를 테스트할 수 있습니다.
실제 인스턴스로 모니터링 솔루션을 테스트하는 방법
-
Amazon EC2 콘솔
의 인스턴스 페이지를 엽니다. -
Amazon EC2 인스턴스 생성 실행하기 전에 키
valid-key
와 값valid-value
이 포함된 태그를 지정합니다. 인스턴스를 생성하고 시작하는 방법에 대한 자세한 내용은 Amazon EC2 사용 설명서의 1단계: 인스턴스 시작을 참조하세요. 인스턴스 시작 절차의 3단계에서 이름 태그를 입력할 때도 추가 태그 추가를 선택하고 태그 추가를 선택한 다음valid-key
의 키 및valid-value
의 값을 입력합니다. 이 인스턴스가 본 자습서의 목적으로만 사용되고 완료 후 인스턴스를 삭제할 계획이라면 키 쌍 없이 계속 진행할 수 있습니다. 1단계가 끝나면 이 자습서로 돌아갑니다. 2단계: 인스턴스에 연결을 수행할 필요가 없습니다. -
콘솔에서 InstanceID를 복사합니다.
-
Amazon EC2 콘솔에서 Lambda 콘솔로 변경합니다. AutoEC2Termination 함수를 선택하고 코드 탭을 선택한 다음 index.js 탭을 선택하여 코드를 편집합니다.
-
Amazon EC2 콘솔에서 복사한 값을 붙여넣어
InstanceList
의 두 번째 항목을 변경합니다.RegionToMonitor
값이 붙여넣은 인스턴스가 포함된 리전과 일치하는지 확인합니다. -
배포를 선택하여 변경 사항을 적용합니다. 이제 지정된 리전의 해당 인스턴스에 대한 태그를 변경했으므로 함수를 활성화할 수 있습니다.
-
Lambda 콘솔에서 Amazon EC2 콘솔로 변경합니다.
-
valid-key 태그를 삭제하거나 해당 키의 값을 변경하여 인스턴스에 연결된 태그를 변경합니다.
참고
실행 중인 Amazon EC2 인스턴스에서 태그를 변경하는 방법에 대한 자세한 내용은 Amazon EC2 사용 설명서의 개별 리소스에 태그 추가 및 삭제를 참조하세요.
-
몇 초간 기다린 다음 콘솔을 새로 고침합니다. 인스턴스는 인스턴스 상태를 중지 중으로 변경한 다음 중지 됨으로 변경해야 합니다.
-
함수를 사용하여 Amazon EC2 콘솔에서 Lambda 콘솔로 변경하고 모니터 탭을 선택합니다.
-
로그 탭을 선택하고 최근 간접 호출 표의 LogStream 열에 있는 가장 최근 항목을 선택합니다.
Amazon CloudWatch 콘솔이 열리면 Lambda 함수를 마지막으로 간접 호출한 로그 이벤트 페이지가 열립니다. 마지막 항목은 다음 예시와 유사합니다.
2022-11-30T12:03:57.544-08:00 START RequestId: b5befd18-2c41-43c8-a320-3a4b2317cdac Version: $LATEST 2022-11-30T12:03:57.548-08:00 2022-11-30T20:03:57.548Z b5befd18-2c41-43c8-a320-3a4b2317cdac INFO Tags changed on monitored EC2 instance ( arn:aws:ec2:us-west-2:123456789012:instance/i-1234567890abcdef0 ) 2022-11-30T12:03:57.548-08:00 2022-11-30T20:03:57.548Z b5befd18-2c41-43c8-a320-3a4b2317cdac INFO This instance is missing the required tag key or value -- attempting to stop the instance 2022-11-30T12:03:58.488-08:00 2022-11-30T20:03:58.488Z b5befd18-2c41-43c8-a320-3a4b2317cdac INFO Successfully stopped instance [ { CurrentState: { Code: 64, Name: 'stopping' }, InstanceId: 'i-1234567890abcdef0', PreviousState: { Code: 16, Name: 'running' } } ] 2022-11-30T12:03:58.546-08:00 END RequestId: b5befd18-2c41-43c8-a320-3a4b2317cdac
자습서 요약
이 자습서에서는 Amazon EC2 인스턴스에 대한 리소스 이벤트의 태그 변경과 일치하는 EventBridge 규칙을 만드는 방법을 설명합니다. 이 규칙은 필요한 태그가 없는 경우 인스턴스가 자동으로 종료되는 Lambda 함수를 가리키고 있습니다.
AWS 리소스의 태그 변경에 대한 Amazon EventBridge 지원은 여러에서 이벤트 기반 자동화를 구축할 수 있는 가능성을 열어 줍니다 AWS 서비스. 이 기능을와 결합하면 AWS 리소스에 안전하게 액세스하고, 온디맨드로 확장하며, 비용 효율적인 서버리스 솔루션을 구축할 수 있는 도구를 AWS Lambda 제공합니다.
리소스에 대한 태그 변경 EventBridge 이벤트의 기타 사용 사례는 다음과 같습니다.
-
누군가 비정상적인 IP 주소에서 리소스에 액세스하는 경우 경고 표시 - 태그를 사용하여 리소스에 액세스하는 각 방문자의 소스 IP 주소를 저장합니다. 태그를 변경하면 CloudWatch 이벤트가 생성됩니다. 이 이벤트를 사용하여 소스 IP 주소를 유효한 IP 주소 목록과 비교하고 소스 IP 주소가 유효하지 않은 경우 경고 이메일이 활성화됩니다.
-
리소스에 대한 태그 기반 액세스 제어에 변경 사항이 있는지 모니터링 - 속성 기반 액세스 제어(ABAC)를 사용하여 리소스에 대한 액세스를 설정한 경우 태그 변경으로 생성된 EventBridge 이벤트를 사용하여 보안팀에 감사를 요청할 수 있습니다.