【AWS】Auto Scaling機能を使わずに定時になったらインスタンスの変更を行う処理

#Auto Scaling機能を使わずに定時になったらインスタンスサイズの変更を行う処理
Auto Scaling機能を使えない状況でインスタンスの変更からターゲットグループの
変更まで自動でやりたい人向けの機能になります。

#やりたかったこと
金曜日の定時になったら通常稼働用インスタンスと切り替え用インスタンスを交代させ、さらにELBのターゲットグループも変更する。
月曜日の定時になったら切り替え用インスタンスと通常稼働用インスタンスを交代させ、ELBのターゲットグループの変更をしてもとに戻す。

これらの動作をAuto Scaling機能を使わずに実施したいのが今回の目標

#やったこと

##IAMロールの登録
IAMロールにEC2操作用ロールとターゲットグループ操作用ロールを登録します。

###EC2操作用ロール
・設定するポリシー名
AmazonEC2FullAccess
AWSLambdaExecute

既存のポリシー2種類を選択する。

###ターゲットグループ操作用ロール
・設定するポリシー
あらかじめターゲットグループ操作用ポリシーを作成しておきそれをアタッチする。

ポリシーの中身

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "elasticloadbalancing:DescribeTargetHealth",
                "elasticloadbalancing:DeregisterTargets",
                "elasticloadbalancing:RegisterTargets"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances"
            ],
            "Resource": "*"
        }
    ]
}
```

##Lambda関数作成
###〇EC2起動・停止用Lamda関数
名前：関数の名前
ランタイム：Python 3.6 
ロール：既存のロール
既存のロール：IAMロールの作成の項目で作成したEC2操作用ロールを選択

###関数の中身
起動用

```
import boto3
instances = ['インスタンスID']
def lambda_handler(event, context):
    ec2 = boto3.client("ec2")
    ec2.start_instances(InstanceIds=instances)
```

停止用

```
import boto3
instances = ['インスタンスID']
def lambda_handler(event, context):
    ec2 = boto3.client("ec2")
    ec2.stop_instances(InstanceIds=instances)
```

※間にカンマを挟むことで複数のインスタンスを指定可能
例：instances = ['インスタンスID','インスタンスID']

###〇ターゲットグループ登録・除外用Lambda関数
名前：関数の名前
ランタイム：Node.js 8.10 
ロール：既存のロール
既存のロール：IAMロールの作成の項目で作成したターゲットグループ操作用ロールを選択

インスタンスIDを指定してさらに指定したターゲットグループに所属させる処理
###追加の場合

```
const INSTANCE_ID = 'インスタンスID';  
const ARN = "追加したいターゲットグループのARN"; 

 
var AWS = require('aws-sdk'); 
AWS.config.region = '所属アベイラビリティゾーン';
 
function albRegister(cb){
  var elbv2 = new AWS.ELBv2();
 
  var params = {
    TargetGroupArn: ARN, 
    Targets: [
       { Id: INSTANCE_ID }
    ]
  };
   
  elbv2.registerTargets(params, function(err, data) {
     if (err) {
       console.log(err, err.stack);
       // an error occurred
     }
     else {
       console.log(data);
       // successful response
     }
  });
}
 
exports.handler = function(event, context) {
  console.log('start');
 
  albRegister(function() {
    context.done(null, 'Started Register');
  });
};
```

###停止の場合

```
const INSTANCE_ID = 'インスタンスID'; 

const ARN = "停止したいターゲットグループのARN";

var AWS = require('aws-sdk');
AWS.config.region = 'アベイラビリティゾーン'; 
 
function albRegister(cb){
  var elbv2 = new AWS.ELBv2();
 
  var params = {
    TargetGroupArn: ARN, 
    Targets: [
       { Id: INSTANCE_ID }
    ]
  };
   
  elbv2.deregisterTargets(params, function(err, data) {
     if (err) {
       console.log(err, err.stack);
     }
     else {
       console.log(data);
     }
  });
}
 
exports.handler = function(event, context) {
  console.log('stop');
 
  albRegister(function() {
    context.done(null, 'Stopdd deregisterTargets');
  });
};
```

※対象によって変動する設定項目
const INSTANCE_ID=対象のインスタンス指定
const ARN =ターゲットグループのRAMN指定
AWS.config.region=対象インスタンスの所属しているアベイラビリティゾーン

##実行イベント作成
作成した関数をCloudWatchで定時実行するだけ！


##まとめ
Auto Scaling機能を使わずに自動でインスタンスの変更を行うという処理でした。
基本的に手動でやる部分をLambda関数を使って強引に自動化した感じなので改善点が多く今後の課題となりました。
もうちょっとスマートにしたいのと定時実行ではなく直前のステータスを見て後続を実行できるようにしたいです。