信頼はずっと、挑戦はもっと。

お問い合わせ
TEL:03-3496-3888

BLOG コアテックの社員ブログ (毎週月曜~金曜更新中)

LIST OF ARTICLES

記事一覧

  • テクログ

    Lambda でサーバレスな運用自動化を!

    皆さん、AWS使ってますか? 今回は 「Lambda(らむだ)」 を紹介したいと思います! 正確なサービス説明は公式ページを参照して頂ければ・・・なのですが、一言で表現すると、  「サーバ不要でコードの実行環境が手に入るサービス」 になる感じでしょうか。 特に美味しい点を挙げるとすれば、  ・サーバレス ・料金が爆安 ・コードの知識が流用できる ・様々なAWSサービスと連携できる あたりでしょうか。 当社では現在インフラチームが生産性やサービス品質の向上を主な目的として試しつつ効果があれば実用化する取組みを進めています。例えば・・・  ・商用サービスでS3に格納される画像を自動的にロスレス圧縮する ・チャットからAthenaにクエリ実行させて結果をチャットで確認する ・DynamoDBのキャパシティ変更を任意に実行する ・定型タスクを直接実行させたり、チャットにリマインド通知させたりする ・開発チームがAWSリソースを作成した際にインフラチームへ通知する 他にも色々とありますが、今回は割愛します。 まだインフラチームが使い始めている段階なのでプロビジョニングや運用を自動化していく使い方が多いのですが、開発チームにも布教していってサーバレスを広げていきたいですね! ただ、使い始めて判明したサーバレスの夢と現実も色々とありました・・・。 そこについては次回にでも伝えられればと思います! 
  • テクログ

    AWSの監視を監視したくありませんか?

    AWSのCloudWatch監視、便利ですよね。でもね、監視が漏れてたりとかしますよね。しない人なんかいない。 監視漏れの確認とかちょう疲れるんですよ。しかも終わりがない。…ということで面倒なことは自動化しましょう。 ●やりたいことAWSのあるリソースについて、[期待している監視]がついているかを自動で確認して、確認結果をSlackとかに通知したい。(とりあえずEC2を対象) ●どうやって?Lambdaで。Pythonでいいかな。3.6です。 ●具体的にはまず[期待している監視]を定義します。MetricName と Alarmのアクション(通知先) が期待しているものだったらOKとします。あと、開発環境や一時的に作成したものなのでアラームチェックから外したい場合もあるので、タグを付けて識別することとします。+漏れたら困るので、タグがついていない場合も監視対象とします。タグは CheckAlarmSetting って名前にして、NOなら監視しない。それ以外なら監視する。です。 流れは(1)インスタンス一覧を取得(現在動いているものに絞る + タグで絞り込み)(2)CloudWatchのアラーム一覧を取得して、(1)で取得したインスタンス一覧に該当するものについて、 期待しているアラームが付いているかを確認。(3)結果をみてわかりやすい感じにしてSlackへ通知。(てっくんに喋らせてます) です。 ●使うものLambdaの環境変数に以下を設定: ACCOUNT_NAME → 複数のAWSアカウントがあると、どれをチェックしたのかわかんないので動的になるため。CHECK_METRIC_NAMES → 監視したいメトリック名 これらがついてない場合にはちゃんとついてない!って言われる。               複数あると思うので、カンマ区切りで設定します。CHECK_ALARM_ACTION → アラームについていてほしいARN。監視してても通知先がなかったり違ったら意味ないですから。               複数あると思うので、カンマ区切りで設定します。ARNはWebコンソールで見てください。SLACK_URL → SlackのWebhookのURLです。 詳細はこちらなどをご参照ください。  ライブラリ:slackwebslackwebpipしましょう。 ロール:EC2とLambdaが使える感じのを作って付けましょう。 ●ソース # -*- coding: utf-8 -*- # EC2のアラーム設定チェック import boto3 import os import slackweb ##################################################### #設定 ##################################################### # アカウント名 ACCOUNT_NAME       = os.environ['ACCOUNT_NAME'] # ついていてほしいCloudWatchのMetricName CHECK_METRIC_NAMES = os.environ['CHECK_METRIC_NAMES'].split(",") #slackurl(あれならKMSで暗号化もしてください) SLACK_URL          = os.environ['SLACK_URL'] # ついていてほしいAlarmのアクション CHECK_ALARM_ACTION = os.environ['CHECK_ALARM_ACTION'].split(",") REGION_NAME = 'ap-northeast-1' ##################################################### #本体 ##################################################### def lambda_handler(event, context):     #まずインスタンスIDの一覧を取得する(今動いているもの)     instance_lists = get_InstanceList()     print('CheckInstanceList:')     print(instance_lists)     #アラームをチェック     instance_list_results = check_CloudWatchAlarmList(instance_lists)     print('CheckInstanceResult:')     print(instance_list_results)     #チェック結果を確認して、通知     checkResult_AND_Notify(instance_list_results) ##################################################### # インスタンスID一覧を取得 ##################################################### def get_InstanceList():     instance_list = []     #ページャーで全て取得     client    = boto3.client('ec2', region_name=REGION_NAME)     paginator = client.get_paginator('describe_instances')     # Filterで動いているものだけにする     page_iterator = paginator.paginate(         Filters=[         {             'Name': 'instance-state-name',             'Values': [                 'running',             ]         }     ],)     #instanceIDを取得     for page in page_iterator:         for reservation in page["Reservations"]:             for instance in reservation["Instances"]:                 instance_id  = instance["InstanceId"]                 #Tagsを見て、CheckAlarmSettingがNOならば除外(NOではない、またはタグが存在しないなら追加                 check_flag = True                 Tags = instance["Tags"]                 for tag in Tags:                     if tag['Key'] == 'CheckAlarmSetting':                         if tag['Value'] == 'NO':                             print('CheckAlarmSetting,NO:' + instance_id)                             check_flag = False                 if check_flag == True:                     print('CheckAlarmSetting,YES:' + instance_id)                     instance_id_dict = {instance_id : list(CHECK_METRIC_NAMES)}                     instance_list.append(instance_id_dict)     return instance_list ##################################################### # CloudWatchのアラーム一覧を取得し、チェック ##################################################### def check_CloudWatchAlarmList(instance_lists):     cloud_watch_client    = boto3.client('cloudwatch', region_name=REGION_NAME)     cloud_watch_paginator = cloud_watch_client.get_paginator('describe_alarms')     page_iterator = cloud_watch_paginator.paginate()     for page in page_iterator:         alarms = page['MetricAlarms']         for alarm in alarms:             # それぞれのアラームについて、期待した宛先があるかを確認             # +ついてないものがチェック対象のものならば通知             checkAction = False             for AlarmAction in alarm['AlarmActions']:                 if AlarmAction in CHECK_ALARM_ACTION:                     checkAction = True             if alarm['Namespace'] == 'AWS/EC2':                 i = 0                 for instance_list in instance_lists:                     instance_id = alarm['Dimensions'][0]['Value']                     if instance_id in instance_list:                         if checkAction == False:                             slack = slackweb.Slack(url=SLACK_URL)                             slack.notify(text=ACCOUNT_NAME + "のEC2アラームチェック途中だけど、\n" + alarm['AlarmName'] + "\nのアラームの宛先にxxxx@xxxxxxがないよ!つけてね!")                         #元の一覧からアラームを取り除いていって、残ったらそれが付いていない、ということなので警告をだす。                         if alarm['MetricName'] in instance_lists[i][instance_id]:#必要なもの以外のアラームが付いていてもエラーとはしない                             instance_lists[i][instance_id].remove(alarm['MetricName'])                     i += 1     return instance_lists ##################################################### # 結果を確認し、漏れがあるかどうかを通知 ##################################################### def checkResult_AND_Notify(instance_list_results):     print('checkResult_AND_Notify')     client    = boto3.client('ec2', region_name=REGION_NAME)     exist_no_Alarm_Flag = False     res_str = ''     for instance_list_result in instance_list_results:         for result in instance_list_result.items():             if len(result[1]) != 0:                 exist_no_Alarm_Flag = True                 no_Alarm_instance_id = result[0]                 print('no_Alarm_instance_id:' + no_Alarm_instance_id)                 res = client.describe_instances(                     InstanceIds=[                         no_Alarm_instance_id                     ]                 )                 for tag in res['Reservations'][0]['Instances'][0]['Tags']:                     if tag['Key'] == 'Name':                         res_str += '>    Name:' + tag['Value'] + '    インスタンスID:' + no_Alarm_instance_id + '\n'     if exist_no_Alarm_Flag:         title_str = "アラームをつけてないEC2インスタンスがあったよ! アラームを付けてね!\n"     else:         title_str = "アラームをつけてないEC2インスタンスはなかったよ!\n"     slack = slackweb.Slack(url=SLACK_URL)     slack.notify(text=ACCOUNT_NAME + "のEC2アラームチェックをしたよ!\n\n" + title_str + res_str)  …という感じです。 コアテックでは他にもRDS,ElastiCache,DynamoDB,Lambdaのアラーム監視もやってます。結構返り値とか呼び方が違ってたりして、EC2のをそのまま利用できる!って感じではなかったですが、一度作ればもう手動チェックはいらなくなるのでおためしください! 
  • テクログ

    Amazon Athena で快適なデータ分析ライフを!

    皆さん、AWS使ってますか? 今回は 「Amazon Athena」 を紹介したいと思います! ざっくり言うと、 「S3にある様々なフォーマットのデータを標準的なSQLで分析できるサービス」 です。 まず何が良いか?って言うと、  ・サーバレスなので、インフラ管理が不要 ・標準SQLなので、学習コストが低い ・読み込みしたデータ容量で課金なので、費用が超安い ・事前のデータ加工が不要で、すぐ使い始められる ・クエリが並列処理されるので、レスポンスが高速 あたりです。 現在では米国のリージョンしか利用できないですが、分析したデータが入っているS3バケットが他リージョンでも設定可能な為に全く問題なく使えます。 当社ではサイトのアクセスログを分析するのに、  Apache の生ログと格闘     ↓ SumoLogic で独自クエリ投げて分析     ↓ Amazon Elasticsearch Service と Kibana で代替     ↓ Amazon Athena での自動化を検証中 ★今ココ! という経緯を辿っています。 今後、ログ的なものは全てS3にとにかく突っ込んでおいて、必要な情報だけ後で取り出す・・・という流れが加速しそうです。 様々なユースケースに対応できるサービスかと思いますので、皆さん是非とも使ってみて下さい!
  • テクログ

    ラズパイでVPNアクセスルータを作ってみた

    はい!ムチャぶりおにぃです。とある案件にてVPNアクセスルータが必要になった為、普通に売っているブロードバンドルータではなく技術会社っぽくLinuxを使ってVPNアクセスルータを作ってみた。案件に必要最低限の設定のみしています。といいつつ、先人たちのお知恵を存分に拝借しています。 (1)~機材集め~まず、機材選定をする段階で、Linuxが動くことが前提になったが今となるとどんな機器でも動くので、コストを抑えるためにRaspberry Piを選んでみました。Raspberry Piにもいろいろなバージョンがあり、【Raspberry Pi 3 Model B】で搭載されている無線LANは今回不要なので、あえて【Raspberry Pi 2 Model B】(ラズパイ2)を選択。あと、動かすためのmicroSD(後述のOSイメージが3Gあるので4GB以上を用意)・スマホの充電器・ケースを購入。全部で9千円いかないぐらい(安いね)。 (2)~OS選択~ラズパイで利用できるLinux・Raspbian(Debianベース)・Pidora(Fedoraベース)・Arch Linux・CentOS 7とあり、去年の3月ぐらいから利用できるようになった【CentOS 7】を選択しました。弊社のシステム基盤としては、CentOSをベースとして使っていますので。 (3)~OSインストール~CentOSのオフィシャルサイトからラズパイ2用のイメージファイルをダウンロードして、microSDに書き込みます。ダウンロード先:https://wiki.centos.org/Download └ RaspberryPi2 (img) microSDに書き込むツールは、シリコンリナックス社様が公開している【DD for Windows】を利用しています。ダウンロード先:http://www.si-linux.co.jp/techinfo/index.php?DD%20for%20Windows └ Ver.0.9.9.8【DD for Windows】の使い方は、検索して調べてね。Windows10で作業していますが、「管理者として実行」で実行しないと利用できませんでした。Windows7以降必須らいしいです。 (4)~初期設定~CentOSを書き込んだmicroSDをラズパイ2に差し込んで起動します。この時、minimalでインストールされた状態のCentOSが起動しますので、ログイン画面が表示されたらroot/centosでログインします。とりあえず、LANケーブルを刺せばDHCPでIPが取得できるので、アップデートだったりパッケージのインストールは可能です。ということで、以下の流れで設定しています・・・◆操作しやすいようにコンソールログインをして、ifconfigをしましょう。# ifconfig・インターフェースのIPアドレスをWindows/MacからSSHで接続しましょう。◆microSDをすべて利用できるようにパーティションの拡張# fdisk /dev/mmcblk0・パーティション領域確認します。「p」・拡張するパーティション(最後のパーテ)を一度削除する。「d」「3」・再度パーティション領域を設定する。「n」「p」「入力せずENTER」「入力せずENTER」※First sector/Last sectorは自動で入力されます。・パーティション領域を保存します。「w」# shutdown -r now・変更したパーティションを反映させる# resize2fs /dev/mmcblk0p3・パーティション領域を実際に使えるよう拡張する◆キーボード・タイムゾーンの設定# localectl set-keymap jp# timedatectl set-timezone Asia/Tokyo◆ログインユーザー追加(wheel追加)・公開鍵を作成# adduser hogehoge# usermod -G wheel hogehoge# passwd hogehoge・コンソールでログインするためにパスワードを設定。# su - hogehoge・作成したユーザーにスイッチ。$ mkdir -m 700 ~/.ssh$ ssh-keygen -q -N "" -f ~/.ssh/id_rsa$ cat ~/.ssh/id_rsa.pub > ~/.ssh/authorized_keys$ chmod 600 ~/.ssh/authorized_keys$ cat ~/.ssh/id_rsa・リモート元に転記。$ exit◆sshログインを公開鍵方式に設定変更# sed -i -e "/^root/a\hogehoge ALL=(ALL) NOPASSWD:ALL" /etc/sudoers# sed -i -e 's/^%wheel/# %wheel/g' /etc/sudoers# sed -i -e '/#PermitRootLogin/a\PermitRootLogin no' /etc/ssh/sshd_config# sed -i -e 's/^PasswordAuthentication yes/#PasswordAuthentication no/g' /etc/ssh/sshd_config# service sshd restart・ログインチェック(rootログインできないこと・作成したユーザーで鍵ログインできること)◆rootパスワード削除# sed -i -e 's/^root/#root/g' /etc/shadow# sed -i -e '/root/a\root:*LOCK*:14600::::::' /etc/shadow# sed -i -e '/#root/d' /etc/shadow◆CTRL+ALT+DELETEを無効化# ln -s /dev/null /etc/systemd/system/ctrl-alt-del.target◆IPv6を無効化# cat << EOL > /etc/sysctl.d/disable_ipv6.confnet.ipv6.conf.all.disable_ipv6 = 1net.ipv6.conf.default.disable_ipv6 = 1EOL# sysctl -p /etc/sysctl.d/disable_ipv6.conf◆irqbalanceバグ# cat << EOF > /etc/cron.daily/irqbalance#!/bin/sh/bin/systemctl restart irqbalance.serviceEOF◆キャッシュクリア・パッケージアップデート# yum clean all# yum -y update◆基本パッケージをインストール# yum -y install chrony ntpdate perl bind-utils iptables-services wget# yum -y groupinstall "Development Tools"◆フィルタリングソフトをiptablesに変更# systemctl stop firewalld# systemctl disable firewalld# mv /etc/sysconfig/iptables /etc/sysconfig/iptables.orig# cat << EOL > /etc/sysconfig/iptables*filter:INPUT DROP [0:0]:FORWARD DROP [0:0]:OUTPUT ACCEPT [0:0]-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT-A INPUT -m state --state INVALID -j DROP-A INPUT -p tcp -m tcp --sport 80 --dport 80 -j DROP-A INPUT -i lo -j ACCEPT-A INPUT -s 事務所の固定IP/32 -j ACCEPT-A INPUT -p icmp -j ACCEPT-A INPUT -j DROPCOMMITEOL# systemctl enable iptables# systemctl start iptables◆時刻設定# sed -i -e 's/0.centos.pool.ntp.org/ntp.nict.jp/g' /etc/chrony.conf# sed -i -e 's/1.centos.pool.ntp.org/ntp1.jst.mfeed.ad.jp/g' /etc/chrony.conf# sed -i -e 's/2.centos.pool.ntp.org/ntp2.jst.mfeed.ad.jp/g' /etc/chrony.conf# sed -i -e 's/3.centos.pool.ntp.org/ntp3.jst.mfeed.ad.jp/g' /etc/chrony.conf# ntpdate ntp.nict.jp# systemctl start chronyd# systemctl enable chronyd (5)~ルータ設定~初期設定が完了したらルータにすべく以下の流れで設定しています・・・設定が終わり再起動するタイミングでLANケーブルをONU(光回線終端装置)とつなぎ替えます。◆パッケージインストール# yum -y install rp-pppoe ppp-devel◆PPPoE設定# pppoe-setup・出てくる質問に答えて設定をしていく。Enter your Login Name:ISPの接続IDを入力Enter the Ethernet interface:LANケーブルを刺すインターフェイス名を入力Enter the demand value:常時接続なので「no」Enter the DNS information here:ネームサーバーを固定するので「8.8.8.8」Enter the secondary DNS server address here:ネームサーバーを固定するので「8.8.4.4」Please enter your Password:ISPの接続パスワードnormal user to start or stop DSL connection:rootユーザー以外操作させないので「no」Choose a type of firewall:ルータとして利用するので「2」Please enter no or yes:起動時に有効かするので「yes」※入力確認が表示されたら「y」で保存◆インターフェイス設定・pppoeで使うインターフェースのプライベートIPを固定する# cp /etc/sysconfig/network-scripts/ifcfg-eth0.bak /etc/sysconfig/network-scripts/ifcfg-eth0# cp /etc/sysconfig/network-scripts/ifcfg-eth0 /etc/sysconfig/network-scripts/ifcfg-eth0.bak# nmcli c modify eth0 ipv4.addresses "10.10.10.254/24"# nmcli c modify eth0 +ipv4.dns 8.8.8.8# nmcli c modify eth0 ipv4.method manual# nmcli c modify eth0 ipv4.gateway "10.10.10.254"# nmcli c modify eth0 ipv4.never-default yes◆SELinuxを無効化するsed -i -e 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config◆起動時にpppoe接続できない対応・/etc/sysconfig/networkのファイルがないとpppoe接続ができないtouch /etc/sysconfig/network◆再起動してルータになっているかテストをする# shutdown -r now・設定不備がなければpppoe接続できていてログイン画面になる (6)~VPN設定~VPNにも、IPsec, L2TP/IPsec, PPTP, IPIP, L2TPv3と多種多様の方式があります。今回は、セキュリティーレベルを考えると【L2TP/IPsec】なのですが、通信速度が遅くなるので【pptp】を選択しました。ということで、VPN設定についても以下の流れで設定しています・・・◆パッケージインストール・yumでインストールできないのでソースインストールになります。# cd /usr/local/src# wget https://jaist.dl.sourceforge.net/project/poptop/pptpd/pptpd-1.4.0/pptpd-1.4.0.tar.gz# tar xvzf pptpd-1.4.0.tar.gz# cd pptpd-1.4.0# ./configure --prefix=/usr# make# make install# cp samples/pptpd.conf /etc/# cp samples/options.pptpd /etc/ppp/・conf設定# cp /etc/pptpd.conf /etc/pptpd.conf.orig# echo "localip 10.10.10.254" >> /etc/pptpd.conf# echo "remoteip 10.10.10.11-30" >> /etc/pptpd.conf# cp /etc/ppp/options.pptpd /etc/ppp/options.pptpd.orig# sed -i -e '/ms-dns 10.0.0.2/a\ms-dns 8.8.4.4' /etc/ppp/options.pptpd# sed -i -e '/ms-dns 10.0.0.2/a\ms-dns 8.8.8.8' /etc/ppp/options.pptpd# echo "#" >> /etc/ppp/options.pptpd# echo "mtu 1200" >> /etc/ppp/options.pptpd# echo "mru 1200" >> /etc/ppp/options.pptpd・pptp認証ユーザー設定# cp /etc/ppp/chap-secrets /etc/ppp/chap-secrets.orig# echo 'hogeuser pptpd "hogepass" *' >> /etc/ppp/chap-secrets・パケット転送をできるように設定# sed -i -e '/net.ipv4.ip_forward/d' /etc/sysctl.conf# echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf# sysctl -p・pptpd起動スクリプト設定と自動起動設定# cat << EOL > /etc/init.d/pptpd#!/bin/sh## Startup script for pptpd## chkconfig: - 85 15# description: PPTP server# processname: pptpd# config: /etc/pptpd.conf# Source function library.. /etc/rc.d/init.d/functions# See how we were called.case "\$1" in start)    echo -n "Starting pptpd: "    /sbin/modprobe nf_conntrack_proto_gre    /sbin/modprobe nf_conntrack_pptp    if [ -f /var/lock/subsys/pptpd ] ; then        echo        exit 1    fi    daemon /usr/sbin/pptpd    echo    touch /var/lock/subsys/pptpd    ;; stop)    echo -n "Shutting down pptpd: "    killproc pptpd    echo    rm -f /var/lock/subsys/pptpd    ;; status)    status pptpd ;; condrestart)    if [ -f /var/lock/subsys/pptpd ]; then        \$0 stop        \$0 start    fi    ;; reload|restart)    \$0 stop    \$0 start    echo "Warning: a pptpd restart does not terminate existing "    echo "connections, so new connections may be assigned the same IP "    echo "address and cause unexpected results. Use restart-kill to "    echo "destroy existing connections during a restart."    ;; restart-kill)    \$0 stop    ps -ef | grep pptpd | grep -v grep | grep -v rc.d | awk '{print \$2}' | uniq | xargs kill 1> /dev/null 2>&1    \$0 start    ;; *)    echo "Usage: \$0 {start|stop|restart|restart-kill|status}"    exit 1esacexit 0EOL# chmod +x /etc/init.d/pptpd# chkconfig pptpd on# /etc/init.d/pptpd start・iptablesにpptpdとパケット転送の許可設定を追加# sed -i '/icmp/a\-A INPUT -p tcp -m state --state NEW -m tcp --dport 1723 -j ACCEPT' /etc/sysconfig/iptables# sed -i '/icmp/a\-A INPUT -p gre -j ACCEPT' /etc/sysconfig/iptables# sed -i '/-A INPUT -j DROP/a\-A FORWARD -o ppp+ -j ACCEPT' /etc/sysconfig/iptables# cat << EOL >> /etc/sysconfig/iptables*nat:PREROUTING ACCEPT [0:0]:INPUT ACCEPT [0:0]:OUTPUT ACCEPT [0:0]:POSTROUTING ACCEPT [0:0]-A POSTROUTING -o ppp+ -j MASQUERADECOMMITEOL# service iptables restart (7)~クライアント設定~WindowsだったりLinuxだったりにpptp認証ユーザー設定で登録したID/PWを使って設定をしてVPN接続しVPNアクセスルータ経由で外部にアクセスできれば設定完了!!あとどのように運用するかは貴方次第!・固定IPのプロバイダを使ってない場合・・・ラズパイを再起動するとIP変わっちゃうよ!なので何かしらの方法でIPを確認する方法を実装しないとです。。。・pppoe接続タイミングの兼ね合いでiptablesがうまく適応できないことがわかっています。現在は/etc/rc.localなどで調整をしています。 そんな感じで設定は完了です。では。
  • テクログ

    AWS Certificate Manager (ACM) について

    皆さん、AWS使ってますか? 今回よりマスオさんはAWSを中心とした話題を書いていきたいと思います! 第一弾となる今回は満を持してAWSがサービス開始した AWS Certificate Manager (ACM) を紹介したいと存じます。 ざっくり言うと、 「AWS サービスで使用する SSL/TLS 証明書の管理を行えるマネージドサービス」 です。 昨年5月から東京リージョンで提供開始されており、当社でも利用範囲が絶賛拡大中となっています。 AWSのサービス(ELB/CloudFront)を使っていないと適用できなかったり、EV証明書が選択できなかったり等の制限はありますが、逆に制限が問題なければ(AWS使っていてEVじゃなくても良い)、超便利なサービスとなります。 主には・・・  ・無料(やはり重要!) ・簡単(基本クリックだけ!) ・自動更新(ただし、条件あり!) など今までの運用における常識を覆すサービスと言っても過言ではありません。 HTTPからHTTPSにすると検索ランキングが向上するとAWS自ら公言しているほどSEOに良い影響を与えると考えられている事から相次ぎ導入するサイトが増えているようです。 ユーザーの通信手段はサービス運営側で選べませんが、SSL化によってサービス運営側で信頼性を主体的に高める事はできるので、プログラム修正など必要になる事を考慮しても間違いなく導入した方が良いですよね~。 もう全世界、全サービスで暗号化を推進していこうぜ!って感じです。 皆さん是非とも使ってみて下さい!
  • テクログ

    PHPとElasticTranscoder

    PHPとElasticTranscoder 皆さんこんにちわ。 ni-yoです。 本日も技術ネタを少々… 弊社はサーバの主流はAWSになっています。 構築の手間と冗長性等を考慮するとオンプレより多方面でメリットが大きく 手放せない存在になっています。 本日はそんな機能の1つElasticTranscoderの紹介をさせていただきます。 Webの世界もクラウド技術の発達等により昔は制限があって実装できないような コンテンツを実現できるようになってきました。 Webの世界もここ近年動画コンテンツの実装率が日々あがってきていることを感じます。 とはいえ、Webでの動画実装はそれほど簡単ではありません。 動画には画像よりもずっと多くの規格があり、(mp4/avi/wmv/flv等) 反面Webブラウザで再生できる規格にはある程度制限があります。 例えばYoutubeのようにユーザ投稿型のコンテンツを作ろうという場合、 ある程度ブラウザで再生できる規格に変換する必要性があります。 この作業をエンコードと言い、動画変換作業の中でデジタル映像をアナログ信号に デコードしないでエンコードを行う作業をトランスコードと言います。 今回紹介するElasticTranscoderはこのトランスコードの作業をAWSでできる技術です。 今回はWebで考えるのでPHPからElasticTranscoderへジョブ通知することにスポットし、 ElasticTranscoder自体は詳しく掘り下げません。 ざっと手順を言えば ①トランスコード元ファイルを配置するS3フォルダを作成 ②トランスコード済みファイルを配置するS3フォルダを作成 ③ElasticTranscoderの入力を①、出力を②で指定したパイプラインを作る ④ElasticTranscoderにアクセスできるIAMを作る。 ⑤IAMの鍵をPHPのソースに記載して①のS3にファイルアップ、パイプラインに変換指示を送る ⑥パイプラインがトランスコード処理を行い、出力先にトランスコード済みファイルが配置される。 のような手順です。 ⑤の部分のPHPプログラムは例えば下記のようになります。 public function getInstance() {         $this->obj = null;         if (is_null($this->obj)) {             $this->obj = Aws::factory([                 'key'    => (IAMで設定したkey),                 'secret' => (IAMで設定したパスワード),                 'region' => Region::TOKYO             ])->get('ElasticTranscoder');         }         return $this->obj;     }     public function createJob($args) {         try {             $res = $this->getInstance()->createJob($args);         } catch (Exception $e) {             echo $e->getMessage();             return false;         }         return $res;     }          public function transcode() {           $result = $this->createJob([             'PipelineId' => (③で作成したパイプラインのID),             'Input' => [                 'Key' => (入力S3に配置したファイルパス),             ],             'Outputs' => [                 // mp4 & Thumbnail                 [                     'Key'              => (出力先に配置したいファイルパス),                     'PresetId'         => '1351620000001-100070',                     'ThumbnailPattern' =>(入力S3に配置したファイルパス)."-{count}"                 ],                 // webm                 [                     'Key'             => $mp4Keyfile.'.webm',                     'PresetId'        => '1351620000001-100240',                 ]             ],         ]);     } transcode関数をコールした時点で入力用S3には動画ファイルを置かれている前提です。 これで、出力したいファイルパスにはmp4とwebmという形式で変換された動画が配置されるはずです。 今回は例としてmp4とwebm形式を指定しています、PCとスマートフォンの対応という部分を考えれば この2つのフォーマットを作成すればほぼカバーできると思います。 もし、それ以外の形式で出力したければ 'PresetId'         => '1351620000001-100070', をそれに準じたものに変更すれば出力されます。 この出力形式はプリセットと呼び、出力したい最適なものを https://docs.aws.amazon.com/ja_jp/elastictranscoder/latest/developerguide/system-presets.html から選択して使用するか、細かい設定をしたければ自作でプリセットを作成することができます。 簡単ですが以上です。 今まで動画配信業者等を使わなくては実現できなかった部分が自前でできるので日々技術進歩を感じますね。 それでは (^-^)ノ