EC2のダイナミックDNS運用

EC2で割り当てできるパブリックIPアドレスには、固定のパブリックIPアドレス(Elastic IP)とAWS Public IPの2種類がある。Elastic IPは割り当てしたインスタンスが稼働している間は課金は発生しないが、インスタンスに割り当てしない場合や、インスタンスが停止している間は1時間あたり0.005USDの課金が発生してしまう。1月あたり1EIPで約300円程度(0.005×(16時間×22日+24時間×8日)×110円)になる。一方でAWS Public IPを利用した場合には、再起動するたびにIPアドレスが変わってしまう問題がある。

DDNSを運用できるようになると、Elastic IPが必要なくなり、EC2インスタンス、RDSインスタンスを指定時間に起動及び停止する にてインスタンスのコストを最小化しようとする場合に効果を発揮する。

Building a Dynamic DNS for Route 53 using CloudWatch Events and Lambda を参考に実施してみた。最小限のコストで利用したい意図からLambda関数の内容は引用元と異なっている。詳細は後述を参照してください。

1.IAMポリシー「ddns-lambda-policy」を追加

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": "ec2:Describe*",
    "Resource": "*"
  }, {
    "Effect": "Allow",
    "Action": [
      "dynamodb:*"
    ],
    "Resource": "*"
  }, {
    "Effect": "Allow",
    "Action": [
      "logs:CreateLogGroup",
      "logs:CreateLogStream",
      "logs:PutLogEvents"
    ],
    "Resource": "*"
  }, {
    "Effect": "Allow",
    "Action": [
      "route53:*"
    ],
    "Resource": [
      "*"
    ]
  }]
}

2.IAMロールでこのロールを使用するサービスを選択欄でLambdaを選択し、1で作成したポリシーを選択し、「ddns-lambda-role」の名前を付けて作成する。

3.Lamda関数を作成する。名前は「ddns_lambda」、ランタイムは「Python 2.7」、ロールには2で作成した
「ddns-lambda-role」 を選択し、下記関数を登録する。

import json
import boto3
import re
import uuid
import time
import random
from datetime import datetime

print('Loading function ' + datetime.now().time().isoformat())
route53 = boto3.client('route53')
ec2 = boto3.resource('ec2')
compute = boto3.client('ec2')
dynamodb_client = boto3.client('dynamodb')
dynamodb_resource = boto3.resource('dynamodb')

def lambda_handler(event, context):
    """ Check to see whether a DynamoDB table already exists.  If not, create it.  This table is used to keep a record of
    instances that have been created along with their attributes.  This is necessary because when you terminate an instance
    its attributes are no longer available, so they have to be fetched from the table."""
    tables = dynamodb_client.list_tables()
    if 'DDNS' in tables['TableNames']:
        print 'DynamoDB table already exists'
    else:
        create_table('DDNS')

    # Set variables
    # Get the state from the Event stream
    state = event['detail']['state']

    # Get the instance id, region, and tag collection
    instance_id = event['detail']['instance-id']
    region = event['region']
    table = dynamodb_resource.Table('DDNS')

    if state == 'running':
        instance = compute.describe_instances(InstanceIds=[instance_id])
        # Remove response metadata from the response
        instance.pop('ResponseMetadata')
        # Remove null values from the response.  You cannot save a dict/JSON document in DynamoDB if it contains null
        # values
        instance = remove_empty_from_dict(instance)
        instance_dump = json.dumps(instance,default=json_serial)
        instance_attributes = json.loads(instance_dump)
        table.put_item(
            Item={
                'InstanceId': instance_id,
                'InstanceAttributes': instance_attributes
            }
        )
    else:
        # Fetch item from DynamoDB
        instance = table.get_item(
        Key={
            'InstanceId': instance_id
        },
        AttributesToGet=[
            'InstanceAttributes'
            ]
        )
        instance = instance['Item']['InstanceAttributes']

    try:
        tags = instance['Reservations'][0]['Instances'][0]['Tags']
    except:
        tags = []
    # Get instance attributes
    private_ip = instance['Reservations'][0]['Instances'][0]['PrivateIpAddress']
    private_dns_name = instance['Reservations'][0]['Instances'][0]['PrivateDnsName']
    private_host_name = private_dns_name.split('.')[0]
    try:
        public_ip = instance['Reservations'][0]['Instances'][0]['PublicIpAddress']
        public_dns_name = instance['Reservations'][0]['Instances'][0]['PublicDnsName']
        public_host_name = public_dns_name.split('.')[0]
    except BaseException as e:
        print 'Instance has no public IP or host name', e

    # Get the subnet mask of the instance
    subnet_id = instance['Reservations'][0]['Instances'][0]['SubnetId']
    subnet = ec2.Subnet(subnet_id)
    cidr_block = subnet.cidr_block
    subnet_mask = int(cidr_block.split('/')[-1])

    reversed_ip_address = reverse_list(private_ip)
    reversed_domain_prefix = get_reversed_domain_prefix(subnet_mask, private_ip)
    reversed_domain_prefix = reverse_list(reversed_domain_prefix)

    # Set the reverse lookup zone
    reversed_lookup_zone = reversed_domain_prefix + 'in-addr.arpa.'
    print 'The reverse lookup zone for this instance is:', reversed_lookup_zone

    # Get VPC id
    vpc_id = instance['Reservations'][0]['Instances'][0]['VpcId']
    vpc = ec2.Vpc(vpc_id)

    # Are DNS Hostnames and DNS Support enabled?
    if is_dns_hostnames_enabled(vpc):
        print 'DNS hostnames enabled for %s' % vpc_id
    else:
        print 'DNS hostnames disabled for %s.  You have to enable DNS hostnames to use Route 53 private hosted zones.' % vpc_id
    if is_dns_support_enabled(vpc):
        print 'DNS support enabled for %s' % vpc_id
    else:
        print 'DNS support disabled for %s.  You have to enabled DNS support to use Route 53 private hosted zones.' % vpc_id

    # Create the public and private hosted zone collections.  These are collections of zones in Route 53.
    hosted_zones = route53.list_hosted_zones()
    public_hosted_zones = filter(lambda x: x['Config']['PrivateZone'] is False, hosted_zones['HostedZones'])
    public_hosted_zones_collection = map(lambda x: x['Name'], public_hosted_zones)
    # Wait a random amount of time.  This is a poor-mans back-off if a lot of instances are launched all at once.
    time.sleep(random.random())

    # Loop through the instance's tags, looking for the zone and cname tags.  If either of these tags exist, check
    # to make sure that the name is valid.  If it is and if there's a matching zone in DNS, create A and PTR records.
    for tag in tags:
        if 'ZONE' in tag.get('Key',{}).lstrip().upper():
            if is_valid_hostname(tag.get('Value')):
                if tag.get('Value').lstrip().lower() in public_hosted_zones_collection:
                    print 'Public zone found', tag.get('Value')
                    public_hosted_zone_name = tag.get('Value').lstrip().lower()
                    public_hosted_zone_id = get_zone_id(public_hosted_zone_name)
                    # create A record in public zone
                    if state =='running':
                        try:
                            create_resource_record(public_hosted_zone_id, public_host_name, public_hosted_zone_name, 'A', public_ip)
                        except BaseException as e:
                            print e
                    else:
                        try:
                            delete_resource_record(public_hosted_zone_id, public_host_name, public_hosted_zone_name, 'A', public_ip)
                        except BaseException as e:
                            print e
                else:
                    print 'No matching zone found for %s' % tag.get('Value')
            else:
                print '%s is not a valid host name' % tag.get('Value')
        # Consider making this an elif CNAME
        else:
            print 'The tag \'%s\' is not a zone tag' % tag.get('Key')
        if 'CNAME' in tag.get('Key',{}).lstrip().upper():
            if is_valid_hostname(tag.get('Value')):
                cname = tag.get('Value').lstrip().lower()
                cname_host_name = cname.split('.')[0]
                cname_domain_suffix = cname[cname.find('.')+1:]
                cname_domain_suffix_id = get_zone_id(cname_domain_suffix)
                for cname_public_hosted_zone in public_hosted_zones_collection:
                    if cname.endswith(cname_public_hosted_zone):
                        cname_public_hosted_zone_id = get_zone_id(cname_public_hosted_zone)
                        #create CNAME record in public zone
                        if state == 'running':
                            try:
                                create_resource_record(cname_public_hosted_zone_id, cname_host_name, cname_public_hosted_zone, 'CNAME', public_dns_name)
                            except BaseException as e:
                                print e
                        else:
                            try:
                                delete_resource_record(cname_public_hosted_zone_id, cname_host_name, cname_public_hosted_zone, 'CNAME', public_dns_name)
                            except BaseException as e:
                                print e

def create_table(table_name):
    dynamodb_client.create_table(
            TableName=table_name,
            AttributeDefinitions=[
                {
                    'AttributeName': 'InstanceId',
                    'AttributeType': 'S'
                },
            ],
            KeySchema=[
                {
                    'AttributeName': 'InstanceId',
                    'KeyType': 'HASH'
                },
            ],
            ProvisionedThroughput={
                'ReadCapacityUnits': 4,
                'WriteCapacityUnits': 4
            }
        )
    table = dynamodb_resource.Table(table_name)
    table.wait_until_exists()

def create_resource_record(zone_id, host_name, hosted_zone_name, type, value):
    """This function creates resource records in the hosted zone passed by the calling function."""
    print 'Updating %s record %s in zone %s ' % (type, host_name, hosted_zone_name)
    if host_name[-1] != '.':
        host_name = host_name + '.'
    route53.change_resource_record_sets(
                HostedZoneId=zone_id,
                ChangeBatch={
                    "Comment": "Updated by Lambda DDNS",
                    "Changes": [
                        {
                            "Action": "UPSERT",
                            "ResourceRecordSet": {
                                "Name": host_name + hosted_zone_name,
                                "Type": type,
                                "TTL": 60,
                                "ResourceRecords": [
                                    {
                                        "Value": value
                                    },
                                ]
                            }
                        },
                    ]
                }
            )

def delete_resource_record(zone_id, host_name, hosted_zone_name, type, value):
    """This function deletes resource records from the hosted zone passed by the calling function."""
    print 'Deleting %s record %s in zone %s' % (type, host_name, hosted_zone_name)
    if host_name[-1] != '.':
        host_name = host_name + '.' 
    route53.change_resource_record_sets(
                HostedZoneId=zone_id,
                ChangeBatch={
                    "Comment": "Updated by Lambda DDNS",
                    "Changes": [
                        {
                            "Action": "DELETE",
                            "ResourceRecordSet": {
                                "Name": host_name + hosted_zone_name,
                                "Type": type,
                                "TTL": 60,
                                "ResourceRecords": [
                                    {
                                        "Value": value
                                    },
                                ]
                            }
                        },
                    ]
                }
            )
def get_zone_id(zone_name):
    """This function returns the zone id for the zone name that's passed into the function."""
    if zone_name[-1] != '.':
        zone_name = zone_name + '.'
    hosted_zones = route53.list_hosted_zones()
    x = filter(lambda record: record['Name'] == zone_name, hosted_zones['HostedZones'])
    try:
        zone_id_long = x[0]['Id']
        zone_id = str.split(str(zone_id_long),'/')[2]
        return zone_id
    except:
        return None

def is_valid_hostname(hostname):
    """This function checks to see whether the hostname entered into the zone and cname tags is a valid hostname."""
    if hostname is None or len(hostname) > 255:
        return False
    if hostname[-1] == ".":
        hostname = hostname[:-1]
    allowed = re.compile("(?!-)[A-Z\d-]{1,63}(?<!-)$", re.IGNORECASE)
    return all(allowed.match(x) for x in hostname.split("."))

def reverse_list(list):
    """Reverses the order of the instance's IP address and helps construct the reverse lookup zone name."""
    if (re.search('\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}',list)) or (re.search('\d{1,3}.\d{1,3}.\d{1,3}\.',list)) or (re.search('\d{1,3}.\d{1,3}\.',list)) or (re.search('\d{1,3}\.',list)):
        list = str.split(str(list),'.')
        list = filter(None, list)
        list.reverse()
        reversed_list = ''
        for item in list:
            reversed_list = reversed_list + item + '.'
        return reversed_list
    else:
        print 'Not a valid ip'
        exit()

def get_reversed_domain_prefix(subnet_mask, private_ip):
    """Uses the mask to get the zone prefix for the reverse lookup zone"""
    if 32 >= subnet_mask >= 24:
        third_octet = re.search('\d{1,3}.\d{1,3}.\d{1,3}.',private_ip)
        return third_octet.group(0)
    elif 24 > subnet_mask >= 16:
        second_octet = re.search('\d{1,3}.\d{1,3}.', private_ip)
        return second_octet.group(0)
    else:
        first_octet = re.search('\d{1,3}.', private_ip)
        return first_octet.group(0)

def json_serial(obj):
    """JSON serializer for objects not serializable by default json code"""
    if isinstance(obj, datetime):
        serial = obj.isoformat()
        return serial
    raise TypeError ("Type not serializable")

def remove_empty_from_dict(d):
    """Removes empty keys from dictionary"""
    if type(d) is dict:
        return dict((k, remove_empty_from_dict(v)) for k, v in d.iteritems() if v and remove_empty_from_dict(v))
    elif type(d) is list:
        return [remove_empty_from_dict(v) for v in d if v and remove_empty_from_dict(v)]
    else:
        return d

def is_dns_hostnames_enabled(vpc):
    dns_hostnames_enabled = vpc.describe_attribute(
    DryRun=False,
    Attribute='enableDnsHostnames'
)
    return dns_hostnames_enabled['EnableDnsHostnames']['Value']

def is_dns_support_enabled(vpc):
    dns_support_enabled = vpc.describe_attribute(
    DryRun=False,
    Attribute='enableDnsSupport'
)
    return dns_support_enabled['EnableDnsSupport']['Value']

タイムアウト時間を1分30秒にして、CloudWatchEventsは
イベントパターン
サービス名:ec2
イベントタイプ:EC2 Instance State-change Notification
特定の状態:running, shutting-down, stopped
として、「ec2_lambda_ddns_rule」の名前で登録すればよい。

Lambda関数の実行にそれなりに時間がかかることから、タイムアウト時間は30秒程度でよいとなっているが、ソースコードがアップロードされていたGitHubでは1分30分で登録されていたので、1分30秒とした。

4.route53でDDNSで登録したいドメイン名を登録する。なお、route53ではゾーン情報を1つ登録するごとに月額0.50USDがかかり、無料枠の対象にはならない。

5.DDNSを運用したいEC2インスタンスのタグにCNAMEを登録し、値としてFQDNを登録する。最後に”.”が入っているかを確認してほしい。
例)blog.development-network.net.

参考元の手順で実施した場合、Privateのゾーンに対して登録される仕組みになっていることと、逆引きが登録される仕様になっていたので、Privateのゾーン登録が不要な場合には上記でよいこととなる。

インスタンス間通信をRoute53で名前解決させる場合には、プライベート接続にしないとトラフィックがインターネットを経由してしまうので課金されることから、オリジナルのソースコードを採用し、Route53にはprivateとpublicの両方のゾーンを登録したほうが良いと思われる。

Non-Recurring Expense

開発依頼者が開発依頼先に開発費として一括で支払う方法のこと。
エンジニアリング・リソースや設計ツールの費用、デバイスを製造するための加工技術の費用など、デバイスの設計・製造にかかる経費の総計を指す。
⇔ Recurring Cost

スクラムガイド

2017年11月版より

スプリントプランニング
スプリントの作業計画。

スプリントレトロスペクティブ
スクラムチームの検査と次のスプリントの改善計画を作成する機会。
平成30年度システムアーキテクト試験では、スクラムチームで何がうまくいき、何がうまくいかなかったのかを議論し、継続的なプロセス改善を促進するアクティビティとなっている。

スプリントレビュー
スプリントの終了時にインクリメントの検査と、必要であればプロダクトバック ログの適応を行うもの。

デイリースクラム
開発チームのための 15 分間のタイムボックスのイベント。

CMMI 1.3版エンジニアリングのプロセス領域

平成30年度 システムアーキテクト試験 午前IIより
プロセス領域とは何か?より引用

【要件開発】顧客要件、成果物要件、および成果物構成要素の要件を引き出し、分析し、そして確立すること
【技術解】要件に対する解を選定し、設計し、そして実装することである。解、設計、および実装は、単体の、または適宜組み合わせた成果物、成果物構成要素、および成果物関連のライフサイクルプロセスを網羅すること
【成果物統合】 成果物構成要素から成果物を組み立て、統合されたものとして成果物が適切に動く (必要とされる機能性および品質属性を備えている) ようにし、そしてその成果物を納入すること
【検証】選択された作業成果物が、指定された要件を満たすようにすること
【妥当性確認】 成果物または成果物構成要素が、意図された環境に設置されたときにその意図された用途を充足することを実証すること

システムアーキテクト試験

初めて受験したが、論文で不合格になってしまった。ITサービスマネージャ試験を2年前に合格して以来不合格が続き、来春受験予定のシステム監査試験は午前I免除なしで、かなりしんどい試験になりそう。 ちなみにシステム監査試験は27年度に午後IIで論文でBランクになった後、29年度、30年度は午後Iで連続不合格になっているだけに、午後Iの対策がとても重要。。。。

受験番号  SA542-0124 の方は,   不合格   です

午前Ⅰ得点***.**点
午前Ⅱ得点72.00点
午後Ⅰ得点71点
午後Ⅱ評価ランクB

VMをVLANと接続する

VMWareの仮想マシンをVLANと接続するためには、仮想マシンにVLAN設定する方法もあるが、vSwitchのVLAN設定を変更することで仮想マシンVLAN設定する必要なくVLANに参加させることができる。

ESXi とタグ VLAN の組み合わせかたに詳しいが、VLAN IDをvSwitchにて設定して紐づけすること(External Switch Tagging (EST))で設定できる。

【VMware vSphere 6 ESXi】 ネットワークの概念まとめも併せて参考にするとよい。

EC2インスタンス、RDSインスタンスを指定時間に起動及び停止する

下記を参考にして、CloudWatch+Lambdaの組み合わせを用いて、タグ指定でインスタンスの開始、停止を実装してみた。
できるだけシンプルな仕組みで簡単にEC2の自動起動・停止を実現したい!
AWS Lambda+Python3で複数のRDSを起動停止

開発環境など業務時間内のみインスタンスを稼働させ、コストを最小化させたいときに役に立つ。

EC2インスタンスの場合
Lambda関数に設定する実行ロール

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:*:*:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances",
                "ec2:StartInstances",
                "ec2:StopInstances"
            ],
            "Resource": "*"
        }
    ]
}

Lambda関数(ec2.describe_instances()の戻りデータがそれなりに大きいので、タイムアウトをデフォルトの3秒より少し長めにしておかないとタイムアウトしてしまう)

import boto3

"""
  Request 4Parameters
    Region
    Action(start or stop)
    TagName
    TagValue
"""

def lambda_handler(event, context):
    region = event['Region']
    action = event['Action']
    tagname = event['TagName']
    tagvalue = event['TagValue']
    ec2 = boto3.client('ec2', region_name=region)
    try:
        reservations = ec2.describe_instances()
    except Exception as e:
        print(e)
        return { 'status': -1 }

    if action == 'start':
        for instances in reservations["Reservations"]:
            for instance in instances['Instances']:
                tags = instance['Tags']
                tag = next(iter(filter(lambda tag: tag['Key'] == tagname and tag['Value'] == tagvalue, tags)), None)
                if tag:
                    if instance['State']['Name'] == 'stopped':
                        response = ec2.start_instances(InstanceIds=[instance["InstanceId"]])
                        print(instance['InstanceId'] + " is starting!")
                    else:
                        print(instance['InstanceId'] + " is already started!")
    elif action == 'stop':
        for instances in reservations["Reservations"]:
            for instance in instances['Instances']:
                tags = instance['Tags']
                tag = next(iter(filter(lambda tag: tag['Key'] == tagname and tag['Value'] == tagvalue, tags)), None)
                if tag:
                    if instance['State']['Name'] == 'running':
                        response = ec2.stop_instances(InstanceIds=[instance["InstanceId"]])
                        print(instance['InstanceId'] + " is stopping!")
                    else:
                        print(instance['InstanceId'] + " is already stopped!")
    return { 'status': 0 }

CloudWatchEventで設定するターゲットの入力値(定数 (JSON テキスト))

{
  "Action": "start",
  "Region": "ap-northeast-1",
  "TagName": "AutoStart",
  "TagValue": "true"
}

上記を設定すると、東京リージョン(ap-northeast-1)にあるAutoStart=Trueとタグ設定されたEC2インスタンスが起動するようになります。Actionをstopとすると停止になります。

RDSインスタンスの場合
Lambda関数に設定する実行ロール

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:*:*:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "rds:DescribeDBInstances",
                "rds:StopDBInstance",
                "rds:StartDBInstance",
                "rds:ListTagsForResource"
            ],
            "Resource": "*"
        }
    ]
}

Lambda関数

import boto3

"""
  Request 4Parameters
    Region
    Action(start or stop)
    TagName
    TagValue
"""

def lambda_handler(event, context):
    region = event['Region']
    action = event['Action']
    tagname = event['TagName']
    tagvalue = event['TagValue']
    rds = boto3.client('rds', region_name=region)
    try:
        dbs = rds.describe_db_instances()
    except Exception as e:
        print(e)
        return { 'status': -1 }

    if action == 'start':
        for db in dbs['DBInstances']:
            instance_arn = db['DBInstanceArn']
            instance_tags = rds.list_tags_for_resource(ResourceName=instance_arn)
            tags = instance_tags['TagList']
            tag = next(iter(filter(lambda tag: tag['Key'] == tagname and tag['Value'] == tagvalue, tags)), None)
            if tag:
                if db['DBInstanceStatus'] == 'stopped':
                    response = rds.start_db_instance(DBInstanceIdentifier=db["DBInstanceIdentifier"])
                    print(db['DBInstanceIdentifier'] + " is starting!")
                else:
                    print(db['DBInstanceIdentifier'] + " is already started!")
    elif action == 'stop':
        for db in dbs['DBInstances']:
            instance_arn = db['DBInstanceArn']
            instance_tags = rds.list_tags_for_resource(ResourceName=instance_arn)
            tags = instance_tags['TagList']
            tag = next(iter(filter(lambda tag: tag['Key'] == tagname and tag['Value'] == tagvalue, tags)), None)
            if tag:
                if db['DBInstanceStatus'] == 'available':
                    response = rds.stop_db_instance(DBInstanceIdentifier=db["DBInstanceIdentifier"])
                    print(db['DBInstanceIdentifier'] + " is stopping!")
                else:
                    print(db['DBInstanceIdentifier'] + " is already stopped!")
    return { 'status': 0 }

参考)EC2とRDSのAPIに差異がある点に注意が必要。
例:EC2のstart_instancesは、リストで渡せる(Type: Array of strings)一方で、RDSのstart-db-instanceは、単一のIDしか渡せない(Type: String/リストで渡せない)。

re:Invent 2018 Second Day

明日はセミナー本番

受講予定のセミナーについて少し調べてみる。

ANT322-R – [REPEAT] High Performance Data Streaming with Amazon Kinesis: Best Practices

Amazon Kinesis makes it easy to collect, process, and analyze real-time, streaming data so you can get timely insights and react quickly to new information. In this session, we dive deep into best practices for Kinesis Data Streams and Kinesis Data Firehose to get the most performance out of your data streaming applications. Our customer NICE inContact joins us to discuss how they utilize Amazon Kinesis Data Streams to make real-time decisions on customer contact routing and agent assignments for its Call Center as a Service (CCaaS) Platform. NICE inContact walks through their architecture and requirements for low-latency, accurate processing to be as responsive as possible to changes.

終わり次第、
IOT314-R – [REPEAT] IoT Analytics Workshop
を見てみようかな。

In this workshop, you learn about the different components of AWS IoT Analytics. You have the opportunity to configure AWS IoT Analytics to ingest data from AWS IoT Core, enrich the data using AWS Lambda, visualize the data using Amazon QuickSight, and perform machine learning using Jupyter Notebooks. Join us, and build a solution that helps you perform analytics on appliance energy usage in a smart building and forecast energy utilization to optimize consumption.

DVC304 – Red Team vs. Blue Team on AWS

Red teamers, penetration testers, and attackers can leverage the same tools used by developers to attack AWS accounts. In this session, two technical security experts demonstrate how an attacker can perform reconnaissance and pivoting on AWS, leverage network, AWS Lambda functions, and implementation weaknesses to steal credentials and data. They then show you how to defend your environment from these threats.

This session is part of re:Invent Developer Community Day, a series led by AWS enthusiasts who share first-hand, technical insights on trending topics.

IOT322-R – [REPEAT] Machine Learning Inference at the Edge

Training ML models requires massive computing resources, so it is a natural fit for the cloud. But, inference typically takes a lot less computing power and is often done in real time when new data is available. So, getting inference results with very low latency is important to making sure your IoT applications can respond quickly to local events. AWS Greengrass ML Inference gives you the best of both worlds. You use ML models that are built and trained in the cloud and you deploy and run ML inference locally on connected devices. For example, you can build a predictive model in Amazon SageMaker for scene detection analysis and then run it locally on an AWS Greengrass enabled security camera device where there is no cloud connectivity to predict and send an alert when an incoming visitor is detected. We show you some examples of image recognition models running on edge devices.

場所がAriaで移動時間がかなり厳しいので、
CMP368-R – [REPEAT] Scalable Multi-Node Deep Learning Training in the Cloud

Developing and optimizing machine learning (ML) models is an iterative process. It involves frequently training and retraining models with new data and optimizing model and training parameters to increase prediction accuracy. At the same time, to drive higher prediction accuracy, models are getting larger and more complex, thus increasing the demand for compute resources. In this chalk talk, AWS and Fast.ai will share best practices on how to optimize AWS infrastructure to minimize deep learning training times by using distributed/multi-node training.

このセッションを聞くことにした。
CON308-R – [REPEAT] Building Microservices with Containers

Microservices are minimal function services that are deployed separately, but can interact together to function as a broader application. Microservices can be built, changed, and deployed quickly with a relatively small impact, empowering developers to speed up the rate of innovation. In this session, we show how containers help enable microservices-based application architectures, discuss best practices for building new microservices, and cover the AWS services that allow you to build performant microservices applications.

GENM201 – Monday Night Live

Want to enjoy live entertainment while learning about Amazon’s infrastructure updates? Be sure to attend Monday Night Live with Peter DeSantis, Vice President, AWS Global Infrastructure and Customer Support, on Nov. 26, at 7:30 PM at The Venetian, Level 2, Hall A.