Thursday, March 9, 2017

draw.io + AWS CloudWatch로 모니터링 대시보드 만들어보기 (원제: draw.io + Amazon CloudWatchでAWS監視ダッシュボードもどきを作る!)

 AWS CloudWatch의 단조로운 화면에 지쳐 근사한 모니터링 대시보드를 만들어 보고자 draw.io을 이용해 간단하게 인프라 구성도를 그린 뒤 그것을 모니터링 대시보드로 사용하는 아이디어를 구현해 보았습니다.
이름하여 Drawatchio 입니다!

목표


이렇게 CloudWatch의 메트릭을 표시해 주는 동시에, 알람이 울리면 대상 인스턴스가 반짝거리는 등 인프라의 상태를 시각적으로 알려주는 대시보드를 만들고자 합니다.

간단한 구조

draw.io는 mxGraph를 기반으로 만들어져 있는데 그 API를 사용해 Plugin을 만듭니다.
draw.io Online Blog draw.io API
https://support.draw.io/display/DOB/2016/04/28/draw.io+API

Javascript를 사용할 수 있는 것 같고, 그렇다면, Amazon Cognito와 연동해서 Amazon CloudWatch에 간단하게 접근 가능할 것 같았습니다.

즉, 다음과 같이 연동하려 합니다.
draw.io <=> Javascript으로 작성한 Plugin <=> Amazon Cognito에서 인증 <=> Amazon CloudWatch API
제가 Javascript가 익숙치 않기에 실수가 있다면 피드백 부탁드립니다!

사용법

매우 쉽게 사용 가능합니다!

먼저 그림을 그림

당연한 이야기지이만, 우선 draw.io을 이용해 멋진 그림을 그립니다. 이게 제대로 되지 않으면 앞으로의 단계가 의미가 없어요.

Cognito에서 Identity pool을 작성

구글링 하면 많은 정보를 얻을 수 있기에 간단히 설명하겠습니다!
Cognito 화면을 열어 "Manage Federated Identities"를 선택합니다.

적당한 이름을 붙여서 Identity pool을 만듭니다. 간단한 설명을 위해 인증없이 연결하겠습니다. "Enable access to unauthenticated identities"을 선택합니다.
이것은 아래의 Role을 누구에게나 부여하는 것이기 때문에 실제 환경에서는 제대로 인증된 것만 통과시키도록 설정합시다.

그리고 Cognito에서 인증 시(혹은 인증 없는 경우에도)에 부여하는 Role을 지정하는 화면이 나오는데, 기본설정값대로 만들어두도록 하겠습니다.

작성 후에는 Sample Code에서 "Identity Pool ID"에 나온 값을 메모해 둡니다. Cognito를 이용하는데에 이 ID가 사용됩니다.

Cognito에서 만든 IAM  Role에 CloudWatch의 접근을 허용

Role을 작성했습니다만, 아직 아무런 권한도 갖고 있지 않기에 CloudWatch에 읽기권한을 부여합니다.

이 경우에도 동일하게, 인증 없이 CloudWatchReadOnlyAccess를 부여하면 불특정한 모든 사람들에게 CloudWatch가 보여지기에 보안을 생각해 Cognito와 IAM를 설정해 두어야 합니다.

CloudWatch의 Alarm을 만들거나, 매트릭스를 기억

CloudWatch를 사용하여 모니터링을 할 때에 적용해 둘 알람을 작성합니다. CPU 상태를 기준으로 하든, SQS의 Queue 수를 기준으로 하든, ScaleOut 상태를 기준으로 하든 자유롭게 만듭니다. 이 알람의 이름을 조금 뒤에 사용하도록 하겠습니다.

또한, 표시하고 싶은 매트릭스도 봐 둡니다.

작성해두었던 그림에 Cognito와 CloudWatch의 패턴을 포함

이제 여기서부터는
Drawatchio의 독자적 설정입니다.
앞에서 그려둔 그림에 메타데이터로써 Cognito와 CloudWatch의 정보를 포함시킵니다.
구체적인 내용은 깃허브 페이지나 아래의 동영상을 참고해 주세요. 대상 오브젝트를를 우클릭하여 "Edit Data ..."에 속성을 추가합니다.

draw.io에 Plugin 설정

포함시킨 메타테이터를 바탕으로 CloudWatch와 연동되게 Plugin을 설정합니다.
메뉴 - Extras - Plugins...
를 열어 아래 2가지를 추가한 뒤 draw.io 페이지를 리로드 합니다.

모니터링 시작!

드디어 모니터링을 시작합니다!
적당한 오브젝트를 우클릭해서 "Start Monitoring"을 눌러주세요.
설정한 매트릭스가 수집되고 있으면 모니터링이 정상 작동하고 있는 것입니다.

설정 분위기 영상

Cognito와 CloudWatch의 파라미터를 포함한 이후의 작업을 영상으로 만들어 두었으니 참고하세요.
동영상 제작 시에 사용된 Cognito ID는 이미 파기해 두었습니다. :)

마치며

이것으로 모니터링의 효율이 얼마나 오를지는 모르겠지만 조금이라도 즐겁게 업무가 될 수 있었으면 좋겠습니다.

그럼 이쯤에서 글을 마치겠습니다.



번역된 컨텐츠입니다.
Qiita. by Yaggytter. http://qiita.com/Yaggytter/items/6d7ab0384aa3c326e71f

Translated article.
Qiita. by Yaggytter. http://qiita.com/Yaggytter/items/6d7ab0384aa3c326e71f

Monday, March 6, 2017

AWS Certificate manager을 사용하기 전에 조심해야 할 것들 (원제: AWS Certificate manager の導入前に気を付ける事)

개요

AWS의 무료 SSL 발행 서비스인 ACM의 서비스를 대략 확인하신 뒤 도입을 검토중인 분들을 위해 세세한 부분들에 대한 설명입니다.

ACM란

AWS의 증명발행 서비스입니다.
와일드 카드 증명서도 대응 하고 있습니다.
발행에 돈이 들지 않습니다.
증명서는 자동 갱신되므로 만기를 걱정할 필요가 없습니다.

자동갱신이 되지 않는 조건

・와일드카드 증명서 발행
「*.example.co.jp」과 같이 와일드카드로 신청한 경우
・FQDN의 resolution 결과가 AWS의 리소스가 아닐 경우
「dig test.example.co.jp 」등에서 얻을 수 있는 answer가 ELB의 IP 등 AWS의 리소스가 아닌 경우
・인터넷으로부터 SSL/TLS로 접속 불가한 경우
「openssl s_client -connect test.example.co.jp:443」등의 커맨드로 SSL/TLS접속이 가능해야 함
위 경우 외에도 AWS의 방침에 따라 변경 가능성이 있습니다.

검증도메인의 대상 변경

AWS CLI에서 다음 명령으로 변경이 가능합니다.
exp 검증 도메인을 test.example.co.jp에서 example.co.jp로 변경하는 경우.
※사전에 실행 리전을 확인합시다.
aws acm request-certificate \
--domain-name test.example.co.jp \
--domain-validation-options DomainName=test.example.co.jp,ValidationDomain=example.co.jp
만약 매년 갱신이 필요한 도메인의 경우 이러한 변경 사항은 다음 업데이트시에도 유효합니다.
반대로, 신청시에 확인 도메인을 변경하면 되돌릴 수 없습니다
※이 기사는 2017년 3월 시점의 정보입니다.


번역된 컨텐츠입니다.
Qiita. by ya53782. http://qiita.com/ya53782/items/1b5f9f845ad577daf5cf

Translated article.
Qiita. by ya53782. http://qiita.com/ya53782/items/1b5f9f845ad577daf5cf

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