Automation, AWS Lambda 및 Parameter Store를 사용하여 골든 AMI 업데이트 - AWS Systems Manager

Automation, AWS Lambda 및 Parameter Store를 사용하여 골든 AMI 업데이트

다음 예시에는 조직이 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 설정 단원을 참조하십시오.

태스크 1: Systems Manager Parameter Store에서 파라미터 생성

다음 정보를 사용하는 문자열 파라미터를 Parameter Store에 생성

  • 이름: latestAmi.

  • : AMI ID입니다. 예: ami-188d6e0e.

Parameter Store 문자열 파라미터를 생성하는 방법에 대한 자세한 내용은 Systems Manager에서 Parameter Store 파라미터 생성 섹션을 참조하세요.

태스크 2: AWS Lambda용 IAM 역할 생성

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

Lambda용 IAM 서비스 역할을 생성하려면
  1. AWS Management Console에 로그인하여 https://console.aws.amazon.com/iam/ 에서 IAM 콘솔을 엽니다.

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

  3. JSON 탭을 선택합니다.

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

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "logs:CreateLogGroup", "Resource": "arn:aws:logs:region:123456789012:*" }, { "Effect": "Allow", "Action": [ "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": [ "arn:aws:logs:region:123456789012:log-group:/aws/lambda/function name:*" ] } ] }
  5. 다음: 태그를 선택합니다.

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

  7. 다음: 검토를 선택합니다.

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

  9. 정책 생성을 선택합니다.

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

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

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "ssm:PutParameter", "Resource": "arn:aws:ssm:region:123456789012:parameter/latestAmi" }, { "Effect": "Allow", "Action": "ssm:DescribeParameters", "Resource": "*" } ] }
  12. 다음: 태그를 선택합니다.

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

  14. 다음: 검토를 선택합니다.

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

  16. 정책 생성을 선택합니다.

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

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

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

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

  21. 역할 이름에 새 역할의 이름(예: lambda-ssm-role 또는 자신이 선호하는 다른 이름)을 입력합니다.

    참고

    다양한 주체가 역할을 참조할 수 있기 때문에 역할이 생성된 후에는 역할 이름을 변경할 수 없습니다.

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

작업 3: AWS Lambda 함수 생성

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

Lambda 함수 생성하려면
  1. AWS Management Console에 로그인하고 https://console.aws.amazon.com/lambda/에서 AWS Lambda 콘솔을 엽니다.

  2. 함수 생성을 선택합니다.

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

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

  5. 런타임에서 Python 3.8을 선택합니다.

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

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

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

  9. 함수 생성(Create function)을 선택합니다.

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

    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
  11. 파일, 저장을 선택합니다.

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

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

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

    { "parameterName":"latestAmi", "parameterValue":"AMI ID" }
  15. Save(저장)를 선택합니다.

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

태스크 4: 실행서 생성 및 AMI 패치

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

실행서를 생성하고 실행하려면
  1. AWS Systems Manager 콘솔(https://console.aws.amazon.com/systems-manager/)을 엽니다.

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

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

  4. 이름UpdateMyLatestWindowsAmi을 입력합니다.

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

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

  7. 문서 편집기 필드에서 기본 콘텐츠를 다음 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
  8. Create automation(자동화 생성)을 선택합니다.

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

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

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

  12. Next(다음)를 선택합니다.

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

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

  15. 실행을 선택합니다.

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