Showing posts with label lambda. Show all posts
Showing posts with label lambda. Show all posts

Monday, June 5, 2017

AWS EC2 인스턴스에서 Host 기반 침입탐지시스템(IDS) 모니터링 하기 (원제: How to Monitor Host-Based Intrusion Detection System Alerts on Amazon EC2 Instances)

 AWS 리소스를 보호하기 위해서 저희는 예방 및 탐지 컨트롤을 포함하는 계층화 된 접근 방식을 권하고 있습니다. 예를 들어 Amazon EC2 인스턴스에 대해 호스트 기반 컨트롤을 통합하면 액세스를 제한하고 시스템 동작 및 액세스 패턴에 대한 적절한 수준의 가시성을 제공 할 수 있습니다. 이러한 컨트롤을 위해서는 호스트의 네트워크 트래픽, 로그 파일 및 파일 액세스를 모니터링하고 분석하는 호스트 기반 침입 탐지 시스템 (HIDS)이 필요합니다. HIDS는 일반적으로 경고, 자동 치료 솔루션을 통합하여 사용자 환경의 공격, 허가되지 않은 활동 또는 의심스러운 활동 및 일반적인 오류를 탐지하고 해결합니다.
 이 포스팅에서는 Amazon CloudWatch Logs를 사용하여 OSSEC (Open Source Security) HIDS에서 알림을 수집하고 집계하는 방법을 소개합니다. CloudWatch Logs 구독을 사용하여 Amazon Elasticsearch Service (이하 Amazon ES)에 alert을 전달해 분석하고 이것을 오픈 소스 도구인 Kibana로 시각화 합니다.
이 솔루션의 가시성을 위해 대부분의 배포 과정을 처리할 CloudFormation 템플릿도 제공할 것입니다. 이 솔루션을 통해 사용자는 EC2 인스턴스 플릿 전체에 대해 향상된 가시성과 통찰력을 확보할 수 있으며 보안성 개선에 도움을 받을 수 있습니다. 예를 들어, 특정 호스트가 EC2 인스턴스를 스캐닝해 OSSEC 경고를 트리거하는 경우 VPC 네트워크 접근통제 리스트(Access Control List) 또는 AWS WAF 규칙을 구현하여 해당 소스 개별 IP 주소 또는 전체 CIDR 블록을 차단할 수 있습니다.

솔루션 개요

다음 다이어그램은 지금부터 소개할 솔루션에 대한 개요를 보여줍니다.
솔루션은 다음과 같이 동작합니다:
  1. 대상 EC2 인스턴스에서 OSSEC HIDS는 alert을 생성하고 그것을 CloudWatch 로그 에이전트가 캡처합니다. HIDS는 로그 분석, 무결성 검사, Windows 레지스트리 모니터링, 루트킷 탐지, 실시간 경고 및 능동적 대응을 수행합니다. 자세한 내용은 OSSEC 시작하기를 참조하세요.
  2. CloudWatch 로그 그룹은 alert을 이벤트로써 수신합니다.
  3. CloudWatch 로그 구독은 대상 로그 그룹에 적용되어 AWS Lambda를 통해 Amazon ES로 이벤트를 전달합니다.
  4. Amazon ES는 기록된 alert 데이터를 로드합니다.
  5. Kibana는 alert을 실시간에 가깝게 시각화합니다. Amazon ES는 모든 Amazon ES 도메인에서 기본설정된 Kibana를 제공합니다.

배포 고려사항

 이 포스팅에서는, alert이 각 시스템에서 로컬로 생성되고 수집되는 Linux 머신에서 OSSEC HIDS을 구성합니다. 솔루션은 배포하려는 리전의 Amazon ES 및 Lambda에 영향을 받을 수 있으며 리전별 AWS 서비스에 대한 최신 정보는 리전 목록에서 확인할 수 있습니다. 또한, EC2 인스턴스가 필요한 구성 요소를 올바르게 제공 할 수 있도록 Amazon VPC (Virtual Private Cloud) 서브넷에서 인터넷 액세스 및 DNS 검색이 정상적으로 작동하는지 미리 확인해야합니다.
 배포 프로세스를 간소화하기 위한 테스트환경을 AWS CloudFormation 템플릿으로 만들어 두었습니다. 이 템플릿을 사용하면 테스트 환경 스택을 기존 Amazon VPC 서브넷에 자동으로 프로비저닝 할 수 있습니다. 이 경우, CloudFormation을 사용하여이 솔루션의 핵심 구성 요소를 프로비저닝 한 다음, alert 분석을 위한 Kibana 설정을 하면 됩니다. 이 솔루션의 소스 코드는 GitHub에서 내려받을 수 있습니다.
제공된 CloudFormation 템플릿은 선택된 리전에서 다음과 같은 단계를 수행합니다:
  1. CloudWatch의 로그에 액세스 할 수 있는 IAM(Identity and Access Management) 역할을 부여한 두 개의 Amazon Linux 인스턴스 생성. (참고 : 샘플 HIDS 경고 데이터를 얻기 위해 두 개의 EC2 인스턴스가 시뮬레이션 된 HIDS 경고를 로컬로 생성하도록 구성됩니다.)
  2. OSSEC, CloudWatch 로그 에이전트 및 테스트 환경에 사용되는 추가 패키지를 설치하고 구성합니다.
  3. 대상 HIDS Amazon ES 도메인을 만듭니다.
  4. 대상 HIDS CloudWatch 로그 그룹을 만듭니다.
  5. Amazon ES에 HIDS alert을 보내기 위해 Lambda 함수 및 CloudWatch Logs 구독을 만듭니다.
CloudFormation 스택이 배포되고 나면 Amazon ES 도메인의 Kibana 인스턴스에 액세스하여 아래에서 소개할 테스트 환경 설정을 마무리 할 수 있습니다.
 이 포스팅에서 다루는 범위를 조금 벗어난 이야기입니다만, OSSEC을 기존 EC2 환경에 배포 할 경우에는 모니터링 할 로그 파일, 무결성 검사할 디렉터리 및 활성 응답 등 원하는 구성을 직접 결정해야 하며 이후 시스템 환경을 최적화하고 테스트, 튜닝 등이 뒤따라야 합니다. OSSEC 문서에는 이러한 과정에서 참조할 많은 정보들이 있습니다. 또한 이벤트의 중앙처리 및 CloudWatch에의 전송을 담당할 에이전트 혹은 별도의 OSSEC 매니저를 이용하는 형식의 배포 또한 선택가능하나 이 경우에는 추가적인 서버 구성 요소와 에이전트와 관리자 간의 네트워크 통신이 필요합니다. Windows Server의 경우는 OSSEC이 지원하는 운영체제이지만 에이전트 기반 설치만 가능하므로 OSSEC 매니저를 이용해야 합니다. OSSEC 아키텍처 및 배포 옵션에 대한 추가적인 정보를 확인하기 위해서는 OSSEC 아키텍처 페이지에서 확인할 수 있습니다.

솔루션 배포

솔루션의 배포 단계는 다음과 같습니다:
  1. CloudFormation 스택 실행
  2. Kibana 색인 패턴 구성 및 alert 탐색 시작
  3. Kibana HIDS 대시 보드 구성 및 alert 시각화

1. CloudFormation 스택 실행

 자동 프로비저닝을 위해 CloudFormation 템플릿으로 테스트 환경을 시작합니다. 이를 위해 대상 VPC와 서브넷 (인터넷 액세스 필요)등 몇 가지 매개 변수를 입력해야합니다. 배포대상 서브넷이 인터넷 게이트웨이를 사용하는 경우 AssignPublicIP 매개 변수를 true로 설정하십시오. 대상 서브넷이 NAT 게이트웨이를 사용하는 경우 AssignPublicIP의 기본 설정(false)으로 두면 됩니다.
 먼저, 동일 리전의 S3 버킷에 Lambda 함수 배포 패키지를 준비해야합니다. 이를위해 압축 된 배포 패키지를 다운로드하여 버킷에 업로드하십시오. S3에 개체를 업로드하는 방법에 대한 자세한 내용은 Amazon S3에 개체 업로드를 참조할 수 있습니다.
또한 스택을 만든 후 환경에 액세스하고 인스턴스와 연결할 신뢰할 수있는 IP 주소 또는 CIDR 블록을  설정하고, 인스턴스와 묶일 EC2 키 쌍을 선택해야합니다. EC2 Key Pair 생성에 대한 자세한 내용은 Amazon EC2를 사용하여 Key Pair 만들기를 참조하십시오. 신뢰할 수있는 IP 주소 또는 CIDR 블록은 Kibana 액세스를 위해 자동으로 Amazon ES 엑세스 정책에 반영됩니다. 모든 IPv4 주소로부터 인스턴스에 액세스를 허용하는 0.0.0.0/0을 사용하기보다 특정 IP 주소 또는 CIDR 범위를 사용하는 것이 안전합니다. 인스턴스에 대한 인바운드 트래픽 권한 부여에 대한 자세한 내용은 Linux 인스턴스에 대한 인바운드 트래픽 인증을 참조하십시오.
입력한 매개 변수 (자세한 내용은 다음 스크린 샷과 표 참조)를 확인한 후 CloudFormation 스택을 생성합니다.
파라미터설명
1. HIDSInstanceSize테스트 서버에 사용할 EC2 인스턴스 사이즈
2. ESInstanceSizeAmazon ES 인스턴스 사이즈
3. MyKeyPair인스턴스 접속을 위한 공개/비밀 Key Pair 
4. MyS3Bucket압축 된 배포 패키지가 업로드된 동일 리전 S3 버킷
5. MyS3Key압축 된 배포 패키지가 업로드된 동일 리전 S3버킷의 Key
6. VPCId솔루션을 배포할 Amazon VPC
7. SubnetId
선택한 VPC 내에서 아웃바운드 연결을 사용하는 서브넷 ID
(인터넷 연결 필요)
8. AssignPublicIP서브넷이 인터넷게이트웨이를 통해 인터넷에 연결하도록 설정되어 있을 경우에는 true, NAT 게이트웨이를 통하도록 설정되어 있을 경우에는 false
9. MyTrustedNetworkEC2 인스턴스와 Amazon ES 엔트포인트로의 화이트리스트 엑세스를 허용할 신뢰할 수 있는 IP 혹은 CIDR 블록 
CloudFormation 스택 생성 마무리:
  1. 적절한 파라미터 입력 후 Next
  2. Options 페이지에서 default 설정 선택 후 Next
  3. Review 페이지에서 설정값들이 제대로 입력되었는지 확인 후 I acknowledge that AWS CloudFormation might create IAM resources 체크박스를 선택하고 Create. (스택 생성에 약 10분 소요)
스택이 생성되면 CloudFormation의 Outputs 탭에서 HIDSESKibanaURL을 확인한 후에 다음 섹션에서 설명할 Kibana 구성 넘어가십시오.

2. Kibana 색인 패턴 구성 및 alert 탐색 시작

이 섹션에서는 Kibana의 초기 설정을 수행합니다. CloudFormation의 스Outputs (이전 섹션 참조)에 제공된 HIDSESKibanaURL으로 접속하면 Amazon ES 인스턴스에 프로비저닝 된 Kibana 페이지로 이동합니다. CloudFormation 매개 변수로 입력한 IP는 Amazon ES 액세스 정책에 자동으로 반영이 되어 있습니다. 만약 다음과 같은 오류가 발생한다면 Amazon ES 액세스 정책이 올바른지 확인해야합니다.
{"Message":"User: anonymous is not authorized to perform: es:ESHttpGet on resource: hids-alerts"}
Amazon ES 도메인에 대한 액세스 보안에 대한 추가 정보는 Amazon Elasticsearch 서비스 도메인에 대한 액세스를 제어하는 방법을 참조하십시오.
OSSEC HIDS 경고가 이제 Amazon ES로 넘겨집니다. Kibana를 사용하여 대화식으로 alert 데이터를 분석하기위해서는, Amazon ES에서 분석할 데이터를 식별할 수 있도록 색인 패턴을 구성해야합니다. Kibana 문서에서 색인 패턴에 대한 추가 정보를 찾을 수 있습니다.
Index name or pattern 상자에 cwl-2017. *을 입력합니다. 색인 패턴은 람다 함수 내에서 cwl-YYYY.MM.DD로 생성되므로 와일드 카드 문자를 사용하여 2017의 데이터를 매칭할 수 있습니다. Time-field name 드롭 다운 메뉴에서는 @timestamp를 선택하하고 Create를 클릭합니다.
Kibana에서 이제 Discover 창이 선택가능해지고 alert이 채워지는 것을 볼 수 있습니다. alert 갱신 빈도를 설정하려면 오른쪽 상단에서 원하는 시간 범위 (예 : Last 15 minutes)를 선택하십시오.
 Auto-refresh을 선택하고 5 seconds 등 적절한 인터벌을 선택합니다.
Kibana는 이제 매 5초마다 자동 갱신 되도록 구성되었을 것입니다. 다음 스크린샷과 같이 카운트그래프와 함께 alert이 업데이트됩니다.
EC2 인스턴스는 CloudFormation에 의해 자동으로 구성된 두 다음과 같은 시뮬레이션이 동작하며 여러 alert을 표시합니다:
  • Successful sudo to ROOT executed – Linux의 sudo 명령어가 성공적으로 실행됨.
  • Web server 400 error code – 서버가 클라이언트 에러로 인해 요청을 진행하지 못함 (조작된 요청, 큰 사이즈, 유효하지 않은 요청 메시지 프레임 등)
  • SSH insecure connection attempt (scan) – SSH listener로 유효하지 않은 커넥션 시도
  • Login session opened – 시스템에서 로그인 세션이 열림
  • Login session closed – 시스템에서 로그인 세션이 닫힘
  • New Yum package installed – 시스템에 패키지가 설치됨
  • Yum package deleted – 시스템에서 패키지가 삭제됨
다음 스크린 샷으로 몇 가지 alert 필드들을 자세히 살펴 보겠습니다.
위 스크린 샷의 필드들은 다음과 같은 내용을 담고 있습니다:
  1. @log_group – CloudWatch 로그 그룹
  2. @log_stream – The CloudWatch 로그 스트임 이름 (인스턴스ID)
  3. @message – OSSEC의 원본 alerts.json에서의 JSON 페이로드
  4. @owner – alert이 발생한 AWS 계정 ID
  5. @timestamp – Lambda 함수에 의해 정의된 타임스탬프
  6. full_log – 로그 원본 파일
  7. location – 로그 원본의 경로와 파일이름
  8. rule.comment – OSSEC 룰에 대한 간략한 설명
  9. rule.level – 0~16으로 나뉜 OSSEC 룰 분류 (Rules Classification 페이지 참조)
  10. rule.sidid – OSSEC 룰 ID
  11. srcip – alert을 트리거한 IP 주소. 테스트시뮬레이션이 진행된 이 경우에는 서버의 로컬 IP가 표시됨
Kibana 쿼리 바에 검색 조건을 입력하면 HIDS 경고 데이터를 대화식으로 탐색 할 수 있습니다. 예를 들어, 다음 쿼리를 이용해 소스 IP가 10.10.10.10 이고 ID가 i-0e427a8594852eca2인 EC2인스턴스의 레벨 6 alert을 볼 수 있습니다.
“rule.level: 6 AND @log_stream: "i-0e427a8594852eca2" AND srcip: 10.10.10.10”
간단한 텍스트, Lucene 쿼리 구문 또는 전체 JSON 기반 Elasticsearch Query DSL에 이르기까지 다양한 방법을 사용할 수 있습니다. Elasticsearch 문서는 데이터 검색에 대한 추가 정보를 제공하고 있습니다.

3. Kibana HIDS 대시보드 구성 및 alert 시각화

시간 경과에 따른 alert의 추세 및 패턴 분석에는 차트 및 그래프가 유용할 수 있습니다. Kibana 인스턴스로 바로 import할 수 있는 대시보드 템플릿을 구성해 공유해두었습니다.
인스턴스에 샘플 HIDS 대시보드 템플릿 추가:
  1. 템플릿을 로컬에 저장하고 Kibana 네비게이션 창에서 Management 선택
  2. 차례대로 Saved ObjectsImport, 로컬에 저장한 샘플 HIDS 대시보드 템플릿을 선택합니다..
  3. HIDS Alerts 대시보드 항목의 오른쪽에있는 눈 모양 아이콘을 선택하십시오. 이 버튼을 누르면 추가한 대시보드 템플릿으로 이동할 것입니다.
Kibana 대시보드 템플릿으로 이동하면, 다음 스크린 샷과 같이 HIDS 대시보드가 표시됩니다. 이 HIDS 샘플 대시보드는 시간별 alert, 상위 20 개 alert 유형, 규칙 수준 분석, 상위 10 개 규칙 소스 ID 및 상위 10 개 소스 IP 등을 표시합니다.
다음 두개의 스크린샷과 같이 필터링 할 alert 유형을 선택해 alert 데이터를 더 자세히 탐색할 수 있습니다.
You can see more details about the alerts based on criteria such as source IP address or time range. For more information about using Kibana to visualize alert data, see the Kibana User Guide.
소스 IP 주소 또는 시간 범위와 같은 기준에 따라 자세한 내용들을 출력합니다. Kibana를 사용한 데이터 시각화의 자세한 내용은 Kibana User Guide를 참조하십시오.

요약

이 포스팅에서는 CloudWatch 로그를 이용해 OSSEC HIDS에서 alert을 수집하고 CloudWatch와 Kibana, 그리고 Amazon ES을 사용해 분석 및 시각화하는 방법을 설명했습니다. 이 솔루션은 AWS 환경에서 심층 방어 보안 전략의 일환으로 EC2 플릿의 보안 모니터링 개선에 일조합니다.
이 솔루션을 통해 EC2 플릿에 대한 공격이나 이상 행동 및 오류 추세를 탐지 할 수 있으며 시스템 재조정 작업의 우선 순위 지정이나 VPC 보안 그룹 규칙, VPC 네트워크 ACL 또는 AWS WAF 규칙과 같은 추가 제어 결정에 참고할 수 있을 것입니다.
이 게시물에 대한 의견이 있으시면 아래에 커맨트를 달아주시기 바랍니다. 이 솔루션 구현에 대한 질문 혹은 의견은 CloudWatch 또는 Amazon ES 포럼에서 새 스레드를 시작하십시오. 이 솔루션의 소스 코드는 GitHub에서 내려받을 수 있습니다. OSSEC 특정한 지원이 필요한 경우에는OSSEC Support Options을 참조하십시오.
– Cameron




번역된 컨텐츠입니다.

AWS Security Blog. by Cameron Worrell, How to Monitor Host-Based Intrusion Detection System Alerts on Amazon EC2 Instances. https://aws.amazon.com/blogs/security/how-to-monitor-host-based-intrusion-detection-system-alerts-on-amazon-ec2-instances/


Translated article.

AWS Security Blog. by Cameron Worrell, How to Monitor Host-Based Intrusion Detection System Alerts on Amazon EC2 Instances. https://aws.amazon.com/blogs/security/how-to-monitor-host-based-intrusion-detection-system-alerts-on-amazon-ec2-instances/

Monday, March 6, 2017

AWS 스팟인스턴스에서의 텐서플로 러닝 자동화 (원제: AWS スポットインスタンスでの TensorFlow 学習の自動化)

mizti 님의 AWS Step Functions과 Lambda로 딥러닝 훈련을 전자동화하기 를 수정한 버전입니다.

배경

  • AWS의 고성능 GPU 머신, p2 인스턴스로 딥러닝(텐서플로) 학습을 실행하려 한다.
  • 하지만 p2는 고가!
    • 스팟인스턴스를 사용하면 저렴하다!
      • 하지만 스팟인스턴스는 실행중의 입찰가격에 따라 강제 셧다운된다.
        • 학습중의 데이터를 정기적으로 S3에 업로드하려 한다.
      • 스팟인스턴스를 사용해 학습 시작을 자동화하려 한다.
    • 학습이 끝나면 인스턴스를 셧타운 하려 한다.

사양

  1. 학습시작을 Slack으로 알림
  2. 데이터 저장위치인 S3의 체크
    • bucket은 존재하는가
    • 기존 학습결과를 저장한 디렉터리는 없는가 (덮어쓰지 않도록 체크)
  3. 스팟인스턴스에 대한 입찰 및 결과를 Slack으로 알림
  4. 인스턴스상에서의 데이터다운로드와 학습(혹은 임의 테스크) 실행
  5. 학습 완료 후 Slack으로 알리고 인스턴스 삭제
를 스스로 하도록 합니다.
AWS StepFuncion과 AWS Lambda를 사용합니다.
데이터 취득 방법이나, 학습을 실행하는 커맨드는 Step Function에 인수로써 json을 사용해 전달하므로 딥러닝 학습 외에도 시간이 걸리는 성과물을 파일로 출력하는 작업 등 범용적으로 사용할 수 있습니다.
{
  "exec_name": "test1",                                 // 실행명. 결과를 저장할 디렉터리명
  "bucket_name": "your-output-bucket-name",             // 결과를 저장할 버킷 이름
  "repository_url": "https://github.com/hoge/fuga.git", // 학습용 프로그램이 들어있는 저장소
  "repository_name": "fuga",                            // 저장소 이름
  "data_dir": "fuga/data/",                             // 로컬에서의 학습데이터 저장장소
  "output_dir": "fuga/output",                          // 로컬에서의 학습결과 저장장소
  "data_get_command": "aws s3 cp s3://your-data-bucket-name/hoge/fuga.data fuga/data/",
                                                        // S3등에서의 데이터 취득 커맨드
  "exec_command": "python fuga/train.py",               // 학습실행 커맨드
  "ami_id" : "ami-111111",                              // 재기동할 인스턴스의 AMI ID
  "instance_type" : "p2.xlarge",                        // 재기동할 인스턴스의 타입
  "spot_price" : "7.2"                                  // 스팟 리퀘스트의 최고금액
}

mizti님의 내용과의 차이점

위 내용은 mizti님의 AWS Step Functions과 Lambda로 딥러닝 훈련을 전자동화하기에서 잘 설명되어있으나, 완전히 똑같이 만들어 본 뒤 제 나름대로 다음과 같이 커스터마이징 하였습니다.
  • 알림을 푸쉬가 아니라 Slack으로
    • 전반적인 에러 발생시에도 Slack으로 알림
  • 스팟 인스턴스의 입찰이 완료될 때 까지 반복하여 대기
  • 하나의S3버킷 안에 복수의 학습결과를 차례로 저장
  • 학습완료후 즉시 인스턴스 파기

자동화

전체적인 설명

AWS Lambda를 사용해 S3의 체크, EC2의 스팟리퀘스트 송신~학습 시작, Slack으로의 알림등 개별 작업을 구현합니다.
그것들을 AWS Step Function을 사용해서 조합, 자동화를 실현합니다.

사전 준비

학습용 인스턴스의 AMI를 제작

AWS EC2 - p2 인스턴스에 텐서플로 도입하기 (번역)를 참고해 텐서플로를 실행하기 위한 AMI를 만듭니다.

Lambda용 Role 작성

lambda에서 S3의 상태를 체크하거나 EC2의 스팟플리트리퀘스트를 송신하는 등의 작업에 필요한 Role을 작성합니다.
lambda-training이라는 이름으로 만들겠습니다.
아래와 같이 Policy를 attach 합니다.
여기서 AmazonEC2SpotFleetRole-FleetCreation는 스팟플리트를 작성하기 위한 Policy로 다음과 같이 만들었습니다.
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeImages",
                "ec2:DescribeSubnets",
                "ec2:RequestSpotInstances",
                "ec2:RequestSpotFleet",
                "ec2:TerminateInstances",
                "ec2:DescribeInstanceStatus",
                "iam:PassRole"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
각 서비스 별 보안 정책에 맞게 권한을 적절하게 조절하는 것이 좋습니다.
신뢰관계로는 lambda를 지정해둡니다.
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

작업실행을 위한 EC2 Role 작성

학습을 실행할 EC2는 데이터를 S3 등의 저장소로부터 다운로드/업로드 할 필요가 있기에 적절한 권한을 지정한 Role을 작성해야합니다.
ec2-deep-learning으로 이름붙이겠습니다.
관리 Policy에 AmazonS3FullAccess등을 추가해둡니다.
신뢰관계는 EC2를 설정합니다.
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

스팟플리트Role 작성

이것은 한번이라도 AWS Console에서 스팟리퀘스트를 송신한 적이 있다면 그 때에 작성되는 것 같습니다.
AmazonEC2SpotFleetRole Policy를 attach해, spotfleet.amazonaws.com에 신뢰관계를 갖고 있는 Role입니다.
aws-ec2-spot-fleet-role이라고 이름붙이겠습니다.

암호화 키 작성

Slack의 WebHook URL등의 정보를 암호화하기 위해 AWS의 암호화키를 만듭니다.
  1. IAM 좌측 메뉴의 '암호화키' 선택
  2. 리전을 EC2와 같은 것으로 선택 (중요)
  3. '키 작성' 클릭

이미지는 만들어진 후의 모습을 보여줍니다..
다음과 같이 작성합니다.
  • alias: lambda-training 등
  • 키 관리자: 관리권한을 갖게 하려는 사용자를 적당히 (이 작업을 진행중인 자신 등)
  • 키 유저: 방금 전 만든 lambda-training Role을 체크
이를 통해 lambda-training Role에서 실행되는 AWS Lambda가 암호화 · 복호화를 할 수 있습니다.

lambda-training Role이 lambda-training 키를 사용할 수 있도록 설정

이름이 같아 까다롭지만, Role에도 설정을 추가하여 키를 사용할 수 있도록 합니다.Role의 lambda-training 인라인 Policy에 다음을 추가하십시오.
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "lambdakms",
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt"
            ],
            "Resource": [
                "arn:aws:kms:us-west-2:111111111:key/1111-1111-1111"
            ]
        }
    ]
}
Resource부분은 lambda-training 키의 arn을 지정합니다.

AWS Lambda의 구현

AWS Console 상에서 Lambda function을 구현합니다.
halhorn가 사용하고 있는 lambda나 step function은 https://github.com/halhorn/AWSAutoLearning에 올려두었으므로 그쪽을 참조 부탁드립니다. 마지막의 .py는 필요하지 않습니다.
(대부분의 코드는 원래의 mizti님 것을 사용해 주세요.
AWS Lambda 내에서의 AWS 조작에는 boto3를 사용합니다.
사용상의 레퍼런스가 필요하시면 Boto3 - EC2나 Boto3 - S3을 참조하시면 좋습니다.
Lambda는 lambda_handler을 엔트리 포인트로 실행되어 json으로 넘겨진 인수가 이벤트 변수에 들어간 상태로 실행됩니다.
또한, event를 마지막으로 return 함으로써, 그 내용을 step function에서 정의 된 다음 lambda에 전달하는 것이 가능합니다.
작성한 lambda는 적당한 json을 인수로 넣어 테스트함으로써 확인을 해 보는 것이 중요합니다.
여기에서는 특히 주의가 필요한 것들에 대해서만 설명합니다

request_spot_fleet

플릿 리퀘스트를 하고, 인스턴스가 실행된 후 학습 코드를 실행하기 위한 Lambda 입니다.
FLEET_ROLE이나 EC2_ROLE 등 정수부분을 적절하게 설정해 주세요.
KEY_NAME은 인스턴스 작성시에 사용하고 있는 키 페어 명을 지정해 주세요.

EC2 재기동시의 처리

create_user_data 안을 편집하는 것으로 EC2 실행 후의 학습실행 커맨드를 바꿀 수 있습니다.
이 커맨드는 root 권한으로 실행됩니다. 그 때문에 일일이 sudo -u ubuntu ** 을 사용합니다.
또한 sudo -u ubuntu -i COMMAND 를 이용해 .zshenv 등도 로드된 상태에서 커맨드 실행이 가능합니다. 하지만, 이것은 현재 디렉터리가 ubuntu의 home인 상황에서 실행되므로 주의하세요. 또한, 제 환경에서는 .zshrc를 로드할 수 없었습니다.
실행되는 것은 다음과 같습니다.
  • 정기적으로 학습 결과 등을 S3에 업로드 하는 cron 작성
  • 데이터 취득
  • 학습 실행
  • complete.log 라고 하는 학습완료 플래그가 되는 파일 생성
    • 이것이 S3에 업로드 됨으로써 Lambda가 학습을 완료했다는것을 알게 되는 구조입니다.

테스트

다음과 같은 인수로 테스트 할 수 있습니다.
{
  "exec_name": "test1",
  "bucket_name": "your-output-bucket-name",
  "repository_url": "https://github.com/hoge/fuga.git",
  "repository_name": "fuga",
  "data_dir": "fuga/data/",
  "output_dir": "fuga/output",
  "data_get_command": "aws s3 cp s3://your-data-bucket-name/hoge/fuga.data fuga/data/",
  "exec_command": "python fuga/train.py",
  "ami_id" : "ami-111111",
  "instance_type" : "p2.xlarge",
  "spot_price" : "7.2"
}
디렉터리는 홈 디렉터리에서 git clone 한 것으로 전제합니다.
절대경로로 쓰면 /home/ubuntu/fuga/... 와 같은 모습입니다.

send_notification / send_error_notification

작업의 진행 등을 Slack 알림을 사용합니다.
우선, 사전에 InCommingWebHook를 Slack으로부터 취득해 두세요.이런 모습입니다.
다음으로, Webhook을 평문 그대로 사용하는 것은 보안상 좋지 않기에 암호화 한 뒤 환경변수에 포함합니다.
코드 하단에 환경변수를 포함할 장소가 있기때문에 여기에서 slackChannel과 kmsEncryptedHookUrl을 설정해 주세요. 단, url은 https://을 제외해 주세요. 또한 이 경우 '암호화 Helper를 활성화'에 체크해야 합니다.

암호화 키는 이전에 만들어둔 「lambda-training」을 지정합니다. 만약 여기서 lambda-training가 보이지 않는다면 키를 만든 리전이 다르거나 Role 설정이 잘못되었을 가능성이 있습니다.
다음은 '암호화'를 클릭해 kmsEncryptedHookUrl만 암호화 합니다.

AWS Step Function의 구현

각각의 Lambda가 완성되면, 그것들을 합쳐 Step Function을 구현합니다.
이것은 json으로 기록되며 작업의 종류, 실행내용, 다음 무엇을 할 것인가 등을 지정합니다.
Create a State Machine을 이용해 작성합니다.
한번 만들면 편집할 수 없는 것 같습니다.

기동

개별 Lambda를 테스트로 확인했다면 StepFunction은 잘 움직여 줄 것입니다.
다음과 같은 분위기의 데이터로 실행해봅시다.
{
  "exec_name": "test1",
  "bucket_name": "your-output-bucket-name",
  "repository_url": "https://github.com/hoge/fuga.git",
  "repository_name": "fuga",
  "data_dir": "fuga/data/",
  "output_dir": "fuga/output",
  "data_get_command": "aws s3 cp s3://your-data-bucket-name/hoge/fuga.data fuga/data/",
  "exec_command": "python fuga/train.py",
  "ami_id" : "ami-111111",
  "instance_type" : "p2.xlarge",
  "spot_price" : "7.2"
}
또한 개인 Github 저장소를 사용하는 경우에는 키 정보를 암호화 키를 사용해 보안을 확보하거나, 액세스키를 이용해 repository_url에 연결하는 등의 방법을 사용하면 됩니다.

순서대로 잘 진행되네요! 
고생하셨습니다. 





번역된 컨텐츠입니다.
Qiita. by halhorn. http://qiita.com/halhorn/items/ae402e8c22bc1083ff23

Translated article.
Qiita. by halhorn. http://qiita.com/halhorn/items/ae402e8c22bc1083ff23