

• AWS Systems Manager CloudWatch 대시보드는 2026년 4월 30일 이후에는 더 이상 사용할 수 없습니다. 고객은 Amazon CloudWatch 콘솔을 계속 사용하여 현재와 마찬가지로 Amazon CloudWatch 대시보드를 보고, 생성하고, 관리할 수 있습니다. 자세한 내용은 [Amazon CloudWatch 대시보드 설명서](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Dashboards.html)를 참조하세요.

# Automation, AWS Lambda 및 Parameter Store를 사용하여 골든 AMI 업데이트
<a name="automation-tutorial-update-patch-golden-ami"></a>

다음 예시에는 조직이 Amazon Elastic Compute Cloud(Amazon EC2) AMIs에서 구축하는 것이 아니라 자체적인 고유의 AMIs를 유지 관리하고 정기적으로 패치하는 모델을 사용합니다.

다음 절차에서는 이미 *최신* AMI로 간주되는 AMI에 운영 체제(OS) 패치를 자동으로 적용하는 방법을 보여줍니다. 이 예제에서 `SourceAmiId` 파라미터의 기본값은 `latestAmi`라는 AWS Systems Manager Parameter Store 파라미터로 정의됩니다. `latestAmi` 값은 자동화가 끝날 때 호출되는 AWS Lambda 함수를 통해 업데이트됩니다. 이 Automation 프로세스의 결과로 최신 AMI에 패치가 항상 적용되기 때문에 AMIs를 패치하는 데 소비되는 시간과 노력이 최소화됩니다. Parameter Store와 Automation은 AWS Systems Manager의 도구입니다.

**시작하기 전 준비 사항**  
Automation 역할 및 Automation을 위한 Amazon EventBridge(옵션)를 구성합니다. 자세한 내용은 [Automation 설정](automation-setup.md) 섹션을 참조하세요.

**Topics**
+ [태스크 1: Systems Manager Parameter Store에서 파라미터 생성](#create-parameter-ami)
+ [태스크 2: AWS Lambda용 IAM 역할 생성](#create-lambda-role)
+ [작업 3: AWS Lambda 함수 생성](#create-lambda-function)
+ [태스크 4: 실행서 생성 및 AMI 패치](#create-custom-ami-update-runbook)

## 태스크 1: Systems Manager Parameter Store에서 파라미터 생성
<a name="create-parameter-ami"></a>

다음 정보를 사용하는 문자열 파라미터를 Parameter Store에 생성
+ **이름**: `latestAmi`.
+ **값**: AMI ID입니다. 예: ` ami-188d6e0e`

Parameter Store 문자열 파라미터를 생성하는 방법에 대한 자세한 내용은 [Systems Manager에서 Parameter Store 파라미터 생성](sysman-paramstore-su-create.md) 섹션을 참조하세요.

## 태스크 2: AWS Lambda용 IAM 역할 생성
<a name="create-lambda-role"></a>

다음 절차를 사용하여 AWS Lambda용 IAM 서비스 역할을 생성합니다. 이 정책은 Lambda 함수와 Systems Manager를 사용하여 `latestAmi` 파라미터의 값을 업데이트할 Lambda 권한을 부여합니다.

**Lambda용 IAM 서비스 역할을 생성하려면**

1. AWS Management Console에 로그인하여 [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)에서 IAM 콘솔을 엽니다.

1. 탐색 창에서 **정책**을 선택한 후 **정책 생성**을 선택합니다.

1. **JSON** 탭을 선택합니다.

1. 기본 콘텐츠를 다음과 같은 정책으로 바꿉니다. 각 *리소스 자리 표시자 예*를 자신의 정보로 바꿉니다.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": "logs:CreateLogGroup",
               "Resource": "arn:aws:logs:us-east-1:111122223333:*"
           },
           {
               "Effect": "Allow",
               "Action": [
                   "logs:CreateLogStream",
                   "logs:PutLogEvents"
               ],
               "Resource": [
                   "arn:aws:logs:us-east-1:111122223333:log-group:/aws/lambda/function name:*"
               ]
           }
       ]
   }
   ```

------

1. **다음: 태그**를 선택합니다.

1. (선택 사항) 이 정책에 대한 액세스를 구성, 추적 또는 제어할 태그-키 값 페어를 하나 이상 추가합니다.

1. **다음: 검토**를 선택합니다.

1. **Review policy(정책 검토)** 페이지에서 **Name(이름)**에 인라인 정책 이름을 입력합니다(예: **amiLambda**)

1. **정책 생성**을 선택합니다.

1. 2단계와 3단계를 반복합니다.

1. 다음 정책을 붙여넣습니다. 각 *example resource placeholder*를 사용자의 정보로 바꿉니다.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": "ssm:PutParameter",
               "Resource": "arn:aws:ssm:us-east-1:111122223333:parameter/latestAmi"
           },
           {
               "Effect": "Allow",
               "Action": "ssm:DescribeParameters",
               "Resource": "*"
           }
       ]
   }
   ```

------

1. **다음: 태그**를 선택합니다.

1. (선택 사항) 이 정책에 대한 액세스를 구성, 추적 또는 제어할 태그-키 값 페어를 하나 이상 추가합니다.

1. **다음: 검토**를 선택합니다.

1. **Review policy(정책 검토)** 페이지에서 **Name(이름)**에 인라인 정책 이름을 입력합니다(예: **amiParameter**)

1. **정책 생성**을 선택합니다.

1. 탐색 창에서 **역할**을 선택한 후 **역할 생성**을 선택합니다.

1. **사용 사례**에서 **Lambda**를 선택한 후 **다음**을 선택합니다.

1. **권한 추가** 페이지의 **검색** 필드를 사용하여 앞서 생성한 두 정책을 찾습니다.

1. 정책 옆 확인란을 선택하고 **다음**을 선택합니다.

1. **역할 이름**에 새 역할의 이름(예: **lambda-ssm-role** 또는 자신이 선호하는 다른 이름)을 입력합니다.
**참고**  
다양한 주체가 역할을 참조할 수 있기 때문에 역할이 생성된 후에는 역할 이름을 변경할 수 없습니다.

1. (선택 사항) 이 역할에 대한 액세스를 구성, 추적 또는 제어할 태그 키-값 페어를 하나 이상 추가한 후 **역할 생성**을 선택합니다.

## 작업 3: AWS Lambda 함수 생성
<a name="create-lambda-function"></a>

다음 절차를 사용하여 `latestAmi` 파라미터의 값을 자동으로 업데이트하는 Lambda 함수를 생성합니다.

**Lambda 함수 생성하려면**

1. AWS Management Console에 로그인하고 [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/)에서 AWS Lambda 콘솔을 엽니다.

1. **함수 생성**을 선택합니다.

1. **함수 생성** 페이지에서 **처음부터 새로 작성**을 선택합니다.

1. [**함수 이름**]에 **Automation-UpdateSsmParam**을 입력합니다.

1. **런타임**에서 **Python 3.11**를 선택합니다.

1. **아키텍처**에서 함수를 실행하는 데 사용할 Lambda용 컴퓨터 프로세서 유형(**x86\$164** 또는 **arm64**)을 선택합니다.

1. **권한** 섹션에서 **기본 실행 역할 변경**을 확장합니다.

1. [**기존 역할 사용(Use an existing role)**]을 선택하고 태스크 2에서 생성한 Lambda에 대한 서비스 역할을 선택합니다.

1. **함수 생성**을 선택합니다.

1. **코드 소스** 영역의 **lambda\$1function** 탭에서 필드에 미리 채워진 코드를 삭제하고 다음 코드 샘플을 붙여 넣습니다.

   ```
   from __future__ import print_function
   
   import json
   import boto3
   
   print('Loading function')
   
   
   #Updates an SSM parameter
   #Expects parameterName, parameterValue
   def lambda_handler(event, context):
       print("Received event: " + json.dumps(event, indent=2))
   
       # get SSM client
       client = boto3.client('ssm')
   
       #confirm  parameter exists before updating it
       response = client.describe_parameters(
          Filters=[
             {
              'Key': 'Name',
              'Values': [ event['parameterName'] ]
             },
           ]
       )
   
       if not response['Parameters']:
           print('No such parameter')
           return 'SSM parameter not found.'
   
       #if parameter has a Description field, update it PLUS the Value
       if 'Description' in response['Parameters'][0]:
           description = response['Parameters'][0]['Description']
           
           response = client.put_parameter(
             Name=event['parameterName'],
             Value=event['parameterValue'],
             Description=description,
             Type='String',
             Overwrite=True
           )
       
       #otherwise just update Value
       else:
           response = client.put_parameter(
             Name=event['parameterName'],
             Value=event['parameterValue'],
             Type='String',
             Overwrite=True
           )
           
       responseString = 'Updated parameter %s with value %s.' % (event['parameterName'], event['parameterValue'])
           
       return responseString
   ```

1. **파일, 저장**을 선택합니다.

1. Lambda 함수를 테스트하려면 **테스트** 메뉴에서 **테스트 이벤트 구성**을 선택합니다.

1. **이벤트 이름**에 테스트 이벤트의 이름을 입력합니다(예: **MyTestEvent**).

1. 기존 텍스트를 다음 JSON으로 바꿉니다. *AMI ID*를 자신의 정보로 바꾸어 `latestAmi` 파라미터 값을 설정합니다.

   ```
   {
      "parameterName":"latestAmi",
      "parameterValue":"AMI ID"
   }
   ```

1. **저장**을 선택합니다.

1. 함수를 테스트하려면 **테스트**를 선택합니다. **실행 결과** 탭에서 업데이트에 대한 다른 세부 정보와 함께 상태가 **성공**으로 보고되어야 합니다.

## 태스크 4: 실행서 생성 및 AMI 패치
<a name="create-custom-ami-update-runbook"></a>

다음 절차를 사용하여 **latestAmi** 파라미터에 지정한 AMI를 패치하는 실행서를 생성하고 실행합니다. 자동화가 완료되면 **latestAmi** 값이 새로 패치된 AMI의 ID로 업데이트됩니다. 이후 자동화는 이전 실행에서 생성된 AMI를 사용합니다.

**실행서를 생성하고 실행하려면**

1. AWS Systems Manager 콘솔([https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/))을 엽니다.

1. 탐색 창에서 **Documents**를 선택합니다.

1. **문서 생성**에서 **Automation**을 선택합니다.

1. **이름**에 **UpdateMyLatestWindowsAmi**를 입력합니다.

1. **편집기** 탭을 선택하고 **편집**을 선택합니다.

1. 메시지가 나타나면 **확인**을 선택합니다.

1. **문서 편집기** 필드에서 기본 콘텐츠를 다음 YAML 샘플 런북 콘텐츠로 바꿉니다.

   ```
   ---
   description: Systems Manager Automation Demo - Patch AMI and Update ASG
   schemaVersion: '0.3'
   assumeRole: '{{ AutomationAssumeRole }}'
   parameters:
     AutomationAssumeRole:
       type: String
       description: '(Required) The ARN of the role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to execute this document.'
       default: ''
     SourceAMI:
       type: String
       description: The ID of the AMI you want to patch.
       default: '{{ ssm:latestAmi }}'
     SubnetId:
       type: String
       description: The ID of the subnet where the instance from the SourceAMI parameter is launched.
     SecurityGroupIds:
       type: StringList
       description: The IDs of the security groups to associate with the instance that's launched from the SourceAMI parameter.
     NewAMI:
       type: String
       description: The name of of newly patched AMI.
       default: 'patchedAMI-{{global:DATE_TIME}}'
     InstanceProfile:
       type: String
       description: The name of the IAM instance profile you want the source instance to use.
     SnapshotId:
       type: String
       description: (Optional) The snapshot ID to use to retrieve a patch baseline snapshot.
       default: ''
     RebootOption:
       type: String
       description: '(Optional) Reboot behavior after a patch Install operation. If you choose NoReboot and patches are installed, the instance is marked as non-compliant until a subsequent reboot and scan.'
       allowedValues:
         - NoReboot
         - RebootIfNeeded
       default: RebootIfNeeded
     Operation:
       type: String
       description: (Optional) The update or configuration to perform on the instance. The system checks if patches specified in the patch baseline are installed on the instance. The install operation installs patches missing from the baseline.
       allowedValues:
         - Install
         - Scan
       default: Install
   mainSteps:
     - name: startInstances
       action: 'aws:runInstances'
       timeoutSeconds: 1200
       maxAttempts: 1
       onFailure: Abort
       inputs:
         ImageId: '{{ SourceAMI }}'
         InstanceType: m5.large
         MinInstanceCount: 1
         MaxInstanceCount: 1
         IamInstanceProfileName: '{{ InstanceProfile }}'
         SubnetId: '{{ SubnetId }}'
         SecurityGroupIds: '{{ SecurityGroupIds }}'
     - name: verifyInstanceManaged
       action: 'aws:waitForAwsResourceProperty'
       timeoutSeconds: 600
       inputs:
         Service: ssm
         Api: DescribeInstanceInformation
         InstanceInformationFilterList:
           - key: InstanceIds
             valueSet:
               - '{{ startInstances.InstanceIds }}'
         PropertySelector: '$.InstanceInformationList[0].PingStatus'
         DesiredValues:
           - Online
       onFailure: 'step:terminateInstance'
     - name: installPatches
       action: 'aws:runCommand'
       timeoutSeconds: 7200
       onFailure: Abort
       inputs:
         DocumentName: AWS-RunPatchBaseline
         Parameters:
           SnapshotId: '{{SnapshotId}}'
           RebootOption: '{{RebootOption}}'
           Operation: '{{Operation}}'
         InstanceIds:
           - '{{ startInstances.InstanceIds }}'
     - name: stopInstance
       action: 'aws:changeInstanceState'
       maxAttempts: 1
       onFailure: Continue
       inputs:
         InstanceIds:
           - '{{ startInstances.InstanceIds }}'
         DesiredState: stopped
     - name: createImage
       action: 'aws:createImage'
       maxAttempts: 1
       onFailure: Continue
       inputs:
         InstanceId: '{{ startInstances.InstanceIds }}'
         ImageName: '{{ NewAMI }}'
         NoReboot: false
         ImageDescription: Patched AMI created by Automation
     - name: terminateInstance
       action: 'aws:changeInstanceState'
       maxAttempts: 1
       onFailure: Continue
       inputs:
         InstanceIds:
           - '{{ startInstances.InstanceIds }}'
         DesiredState: terminated
     - name: updateSsmParam
       action: aws:invokeLambdaFunction
       timeoutSeconds: 1200
       maxAttempts: 1
       onFailure: Abort
       inputs:
           FunctionName: Automation-UpdateSsmParam
           Payload: '{"parameterName":"latestAmi", "parameterValue":"{{createImage.ImageId}}"}'
   outputs:
   - createImage.ImageId
   ```

1. **Create automation(자동화 생성)**을 선택합니다.

1. 탐색 창에서 **Automation**(자동화)을 선택한 후 **Execute automation**(자동화 실행)을 선택합니다.

1. **문서 선택(Choose document)** 페이지에서 **내 소유(Owned by me)** 탭을 선택합니다.

1. **UpdateMyLatestWindowsAmi** 런북을 검색하고 **UpdateMyLatestWindowsAmi** 카드에서 버튼을 선택합니다.

1. **다음**을 선택합니다.

1. **Simple execution(단순 실행)**을 선택합니다.

1. 입력 파라미터에 대한 값을 지정합니다.

1. **실행**을 선택합니다.

1. 자동화가 완료된 후 탐색 창에서 **Parameter Store**를 선택하고 `latestAmi`의 새 값이 자동화에서 반환된 값과 일치하는지 확인합니다. 새 AMI ID가 Amazon EC2 콘솔의 [**AMI(AMIs)**] 섹션에 있는 Automation 출력과 일치하는지도 확인할 수 있습니다.