かべぎわブログ

ブログです

AnsibleでEC2インスタンスを作成してみる

AnsibleでEC2インスタンスを作成してみようと思います。

環境

  • Ansible 2.4.2
  • python 2.7

インスタンスを作成してみる

インスタンスを作成してみます。

実行コマンド

$ ansible-playbook -i ansible_hosts instance_create.yml

playbookは以下のようにしています。

Ansible

インベントリファイルは以下のようなかんじ。

$ cat ansible_hosts
[local]
localhost

実行確認

インスタンスが作成できました! f:id:kabegiwakun:20180208071013p:plain

おわりに

インスタンスを作成するところからAnsibleで実行することができます。
構成管理がはかどりますね!!!

初めてのAnsible

初めてのAnsible

Auto Scalingでスケールインしたときの動作まとめ

概要

Auto Scalingを利用していて、スケールインしたときの動きについてまとめてみます。
AWSドキュメントによると、スケールイン時のうごきが以下の通り。

Auto Scaling は、選択したアベイラビリティーゾーンで、保護されていないどのインスタンスが最も古い起動設定を使用しているかを判断します。このよう title:なインスタンスが 1 つある場合、そのインスタンスを終了します。

docs.aws.amazon.com

つまり、古いものから停止されていくので、グループ内で稼働し続けるようなインスタンスは存在しないということになります。

実際に試してみる

Auto Scalingを設定して、実際に動きを確認してみます。

Auto Scaling(スケジュールされたイベント) の設定

設定は以下ようなかんじで設定してみました。

名前 繰り返し 最小 最大
start 5,15,25,35,45,55 * * * * 4 4
stop 0,10,20,30,40,50 * * * * 3 3

startとstopがcronに従って実行され、startで4台にスケールアウト、stopで3台にスケールインするような動きになります。

これでしばらく放置してみます。

実行結果確認

ログを見て、本当に古いインスタンスから削除されているのかを確認します。 ログは以下の実行ログのとおりです。
例えば、直近("StartTime": "2018-02-01T08:10:56.120Z")で停止されたi-ddddddddddddddddを見てみます。

このインスタンスが作成されたのは"StartTime": "2018-01-29T07:35:52.259Z"です。 その時点でのAuto Scaling Groupのインスタンスの起動時刻をそれぞれ表すと以下になります。

インスタンスID 起動時刻
i-ggggggggggggggggg 2018-02-03T08:05:31.933Z
i-fffffffffffffffff 2018-02-03T07:55:38.692Z
i-eeeeeeeeeeeeeeeee 2018-02-03T07:45:45.317Z
i-dddddddddddddddd 2018-02-03T07:35:52.259Z

実際に古いものから削除されているようです!

実行ログ

$  aws autoscaling describe-scaling-activities --auto-scaling-group-name kabegiwa_scaling_group --query 'Activities[].{StartTime:StartTime,Descriprtion:Description}'

[
    {
        "Descriprtion": "Terminating EC2 instance: i-dddddddddddddddd", 
        "StartTime": "2018-02-03T08:10:56.120Z"
    }, 
    {
        "Descriprtion": "Executing scheduled action stop", 
        "StartTime": "2018-02-03T08:10:26.252Z"
    }, 
    {
        "Descriprtion": "Launching a new EC2 instance: i-ggggggggggggggggg", 
        "StartTime": "2018-02-03T08:05:31.933Z"
    }, 
    {
        "Descriprtion": "Executing scheduled action start", 
        "StartTime": "2018-02-03T08:05:00.074Z"
    }, 
    {
        "Descriprtion": "Terminating EC2 instance: i-ccccccccccccccccc", 
        "StartTime": "2018-02-03T08:00:33.408Z"
    }, 
    {
        "Descriprtion": "Executing scheduled action stop", 
        "StartTime": "2018-02-03T08:00:03.635Z"
    }, 
    {
        "Descriprtion": "Launching a new EC2 instance: i-fffffffffffffffff", 
        "StartTime": "2018-02-03T07:55:38.692Z"
    }, 
    {
        "Descriprtion": "Executing scheduled action start", 
        "StartTime": "2018-02-03T07:55:07.006Z"
    }, 
    {
        "Descriprtion": "Terminating EC2 instance: i-bbbbbbbbbbbbbbbbb", 
        "StartTime": "2018-02-03T07:50:40.344Z"
    }, 
    {
        "Descriprtion": "Executing scheduled action stop", 
        "StartTime": "2018-02-03T07:50:10.562Z"
    }, 
    {
        "Descriprtion": "Launching a new EC2 instance: i-eeeeeeeeeeeeeeeee", 
        "StartTime": "2018-02-03T07:45:45.317Z"
    }, 
    {
        "Descriprtion": "Executing scheduled action start", 
        "StartTime": "2018-02-03T07:45:13.995Z"
    }, 
    {
        "Descriprtion": "Terminating EC2 instance: i-aaaaaaaaaaaaaaaaa", 
        "StartTime": "2018-02-03T07:40:47.193Z"
    }, 
    {
        "Descriprtion": "Executing scheduled action stop", 
        "StartTime": "2018-02-03T07:40:17.326Z"
    }, 
    {
        "Descriprtion": "Launching a new EC2 instance: i-dddddddddddddddd", 
        "StartTime": "2018-02-03T07:35:52.259Z"
    }, 
    {
        "Descriprtion": "Executing scheduled action start", 
        "StartTime": "2018-02-03T07:35:20.733Z"
    } 
 ]

おわりに

Auto Scalingでインスタンスを管理すれば、それだけで長期間稼働するインスタンスをなくすことができそうです。

Amazon Web Services 業務システム設計・移行ガイド (Informatics&IDEA)

Amazon Web Services 業務システム設計・移行ガイド (Informatics&IDEA)

  • 作者: 佐々木拓郎,林晋一郎,瀬戸島敏宏,宮川亮,金澤圭
  • 出版社/メーカー: SBクリエイティブ
  • 発売日: 2018/01/20
  • メディア: 単行本
  • この商品を含むブログを見る

boto3でDynamoDBのテーブルの内容をscanしてすべて取得してみる

boto3を利用してDynamoDBのテーブルの内容をscanしてすべて取得してみたいと思います。

前提

以下のようなテーブルを用意しています。
これをすべてscanして取得します。 f:id:kabegiwakun:20180202064012p:plain

コード

コードは以下の通りです。単純ですね!

python

 
以下のような結果が返ってくるはずです。 (見やすいように整形済み)

{
    'Items': [{
        'name': {
            'S': 'kenkokukinen_no_hi'
        },
        'date': {
            'S': '0211'
        }
    }, {
        'name': {
            'S': 'seijin_no_hi'
        },
        'date': {
            'S': '0108'
        }
    }, {
        'name': {
            'S': 'gantan'
        },
        'date': {
            'S': '0101'
        }
    }],
    'Count': 3,
    'ScannedCount': 3,
}

おわりに

DynamoDBのテーブルの内容をすべて取得することができました。
テーブルの内容を変数に入れて、その内容を参照しに行けばDynamoDBへのアクセスを減らすことができます。

ただし、DynamoDBのデータが多い場合は、scanした際の負荷がかなり高くなると思います。
そこらへんは要検討です。

RDB技術者のためのNoSQLガイド

RDB技術者のためのNoSQLガイド

  • 作者: 渡部徹太郎,河村康爾,北沢匠,佐伯嘉康,佐藤直生,原沢滋,平山毅,李昌桓
  • 出版社/メーカー: 秀和システム
  • 発売日: 2016/02/24
  • メディア: 単行本
  • この商品を含むブログ (3件) を見る

PackerでWindowsServerのAMIを作成する

PackerでWindowsServerのAMIをつくってみます。 これが考えられる最小構成だと思います。 これに肉付けすることでカスタムAMIを作成することができると思います。

環境

  • Packer v1.1.3
  • Packerが動いているサーバ : Amazon Linux 2
  • PackerがつくるWindowsServerのAMI : Microsoft Windows Server 2016 Base

概要

Packerを利用してWindowsServer 2016のAMIを作成します。
もととなるAMIとして使ったのはAWSが提供しているMicrosoft Windows Server 2016 Baseです。

うごきとしては以下のような感じです。

  • PackerがWindows Server 2016 Baseのインスタンスを作成/起動
  • WinRMで接続してEC2Launchを実行
  • AMI作成
  • インスタンス削除

WinRMで接続して~のところでいろいろやるように肉付けするとお好みのカスタムAMIを作成することができます。

実際にやってみる

実行コマンド

$ packer build ./template.json 

実行ログ

amazon-ebs output will be in this color.
==> amazon-ebs: Prevalidating AMI Name: kabegiwa-test-windows-server
    amazon-ebs: Found Image ID: ami-157fe573
==> amazon-ebs: Creating temporary keypair: packer_5a6ac1d4-c926-1c2c-fb7e-f0cf78d180cb
==> amazon-ebs: Creating temporary security group for this instance: packer_5a6ac1d8-b367-106b-ea1b-bd7f142b710a
==> amazon-ebs: Authorizing access to port 5985 from 0.0.0.0/0 in the temporary security group...
==> amazon-ebs: Launching a source AWS instance...
==> amazon-ebs: Adding tags to source instance
    amazon-ebs: Adding tag: "Name": "Packer Builder"
    amazon-ebs: Instance ID: i-02c873d6d7833d311
==> amazon-ebs: Waiting for instance (i-02c873d6d7833d311) to become ready...
==> amazon-ebs: Waiting for auto-generated password for instance...
    amazon-ebs: It is normal for this process to take up to 15 minutes,
    amazon-ebs: but it usually takes around 5. Please wait.
    amazon-ebs:  
    amazon-ebs: Password retrieved!
==> amazon-ebs: Waiting for WinRM to become available...
    amazon-ebs: WinRM connected.
    amazon-ebs: #< CLIXML
    amazon-ebs: <Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04"><Obj S="progress" RefId="0"><TN RefId="0"><T>System.Management.Automation.PSCustomObject</T><T>System.Object</T></TN><MS><I64 N="SourceId">1</I64><PR N="Record"><AV>Preparing modules for first use.</AV><AI>0</AI><Nil /><PI>-1</PI><PC>-1</PC><T>Completed</T><SR>-1</SR><SD> </SD></PR></MS></Obj><Obj S="progress" RefId="1"><TNRef RefId="0" /><MS><I64 N="SourceId">1</I64><PR N="Record"><AV>Preparing modules for first use.</AV><AI>0</AI><Nil /><PI>-1</PI><PC>-1</PC><T>Completed</T><SR>-1</SR><SD> </SD></PR></MS></Obj></Objs>
==> amazon-ebs: Connected to WinRM!
==> amazon-ebs: Provisioning with Powershell...
==> amazon-ebs: Provisioning with powershell script: /tmp/packer-powershell-provisioner631511055
    amazon-ebs:
    amazon-ebs: TaskPath                                       TaskName                          State
    amazon-ebs: --------                                       --------                          -----
    amazon-ebs: \                                              Amazon Ec2 Launch - Instance I... Ready
==> amazon-ebs: Stopping the source instance...
    amazon-ebs: Stopping instance, attempt 1
==> amazon-ebs: Waiting for the instance to stop...
==> amazon-ebs: Creating the AMI: kabegiwa-test-windows-server
    amazon-ebs: AMI: ami-xxxxxxxx
==> amazon-ebs: Waiting for AMI to become ready...
==> amazon-ebs: Terminating the source AWS instance...
==> amazon-ebs: Cleaning up any extra volumes...
==> amazon-ebs: Deleting temporary security group...
==> amazon-ebs: Deleting temporary keypair...
Build 'amazon-ebs' finished.
==> Builds finished. The artifacts of successful builds are:
--> amazon-ebs: AMIs were created:
ap-northeast-1: ami-xxxxxxxx
{/code}
** template.json
{code}
{
    "builders": [{
        "type": "amazon-ebs",
        "region": "ap-northeast-1",
        "source_ami": "ami-157fe573",
        "instance_type": "m4.medium",
        "ami_name": "kabegiwa-test-windows-server",
        "user_data_file": "{{template_dir}}/setup_winrm.txt",
        "communicator": "winrm",
        "winrm_username": "Administrator"
    }],
    "provisioners": [
        {
            "type": "powershell",
            "inline": [
                "C:\\ProgramData\\Amazon\\EC2-Windows\\Launch\\Scripts\\InitializeInstance.ps1 -Schedule",
                "C:\\ProgramData\\Amazon\\EC2-Windows\\Launch\\Scripts\\SysprepInstance.ps1 -NoShutdown"
            ]
        }
    ]
}
{/code}
** setup_winrm.txt
{code}
<powershell>
winrm quickconfig -q
winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="300"}'
winrm set winrm/config '@{MaxTimeoutms="1800000"}'
winrm set winrm/config/service '@{AllowUnencrypted="true"}'
winrm set winrm/config/service/auth '@{Basic="true"}'
netsh advfirewall firewall add rule name="WinRM 5985" protocol=TCP dir=in localport=5985 action=allow
netsh advfirewall firewall add rule name="WinRM 5986" protocol=TCP dir=in localport=5986 action=allow
net stop winrm
sc config winrm start=auto
net start winrm
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope LocalMachine
</powershell>

結果確認

実行ログを見るとami-xxxxxxxxというAMIが作成されたことがわかります。 それをもとにインスタンスを作成します。

インスタンス作成

$ aws ec2 run-instances \
--image-id ami-xxxxxxxx \
--subnet-id subnet-yyyyyyyy \
--security-group-ids sg-12345678 sg-abcdefgh \
--count 1 \
--instance-type t2.micro \
--key-name himitsu-key  \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=kabegiwa-test}]'

インスタンス起動確認

$ aws ec2 describe-instances --instance-id i-abcdefghijklmnop --query 'Reservations[]
.Instances[].State.Name'
[
    "running"
]

おわりに

無事にWindows ServerのAMIを作成、インスタンスを起動することができました!

継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化

継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化

Amazon Linux 2でPacker を実行したところ/usr/share/cracklib/pw_dict.pwd: Permission deniedのエラーがでる

事象

Amazon Linux 2 でPackerを実行しようとしたところ、以下のようなエラーが出てしまいました。

$ packer
/usr/share/cracklib/pw_dict.pwd: Permission denied
/usr/share/cracklib/pw_dict: Permission denied

原因

どうやら以下のPackerを実行してしまっているらしい。

$ which packer
/usr/sbin/packer

これはなにかとおもったらどうやらパスワードチェックなどに利用されるcracklib-packerのシンボリックリンクみたいです。

$ ls -l /usr/sbin/packer
lrwxrwxrwx 1 root root 15 Jan 16 18:44 /usr/sbin/packer -> cracklib-packer

解決法

シンボリックリンクを消してしまいます。

$ sudo rm /usr/sbin/packer
$ packer -v
Packer v1.1.3

無事Packerが実行できました。

AWSによるサーバーレスアーキテクチャ

AWSによるサーバーレスアーキテクチャ

EC2 External InventoryでプライベートIPで取得したい

AnsibleのEC2 External InventoryでEC2インスタンスの情報を取得したとき、デフォルトのままだと以下のようにIPアドレスがパブリックIPで表示されるかと思います。

$ ./ec2.py 
{
"_meta": {
  "ap-northeast-1a": [
    "54.xxx.xxx.xxx", 
    "13.yyy.yyy.yyy"
  ], 
  "tag_Name_kabegiwa_ansible_server": [
    "54.xxx.xxx.xxx"
  ], 
  "tag_Name_kabegiwa_ansible_client": [
    "13.yyy.yyy.yyy"
  ]

そして、パブリックIPを設定していないインスタンスについては情報がとれていませんでした。

解決法

設定ファイルであるec2.iniのvpc_destination_variableprivate_ip_addressに変更したところ、うまくいきました。

以下のように変更

vpc_destination_variable = private_ip_address
# vpc_destination_variable = ip_address

こんなかんじで無事に表示されるようになります。

$ ./ec2.py 
{
"_meta": {
  "ap-northeast-1a": [
    "172.140.1.1", 
    "172.140.1.2",
    "172.140.1.3"
  ], 
  "tag_Name_kabegiwa_ansible_server": [
    "172.140.1.1"
  ], 
  "tag_Name_kabegiwa_ansible_client": [
    "172.140.1.2"
  ],
  "tag_Name_kabegiwa_private": [
    "172.140.1.3"
  ]

おわりに

以下のように両方設定を残してしまうと下にある項目の設定になってしまうようです。(パブリックIPしか表示されないような状態になってしまう)

vpc_destination_variable = private_ip_address
vpc_destination_variable = ip_address

Ansible完全読本

Ansible完全読本

EC2 External Inventoryを利用してAnsibleのhostsを動的に管理する

Ansibleを利用した構成管理では、実行対象のホストをインベントリファイルと呼ばれるファイルに記載しておく必要があります。

以下のようなかんじ

[local]
localhosts

[test_server]
192.140.1.1
192.140.1.2

[web_server]
192.140.2.1

これだと、AWSでAutoScalingを利用した際や、新たにインスタンスをたてたときなどにこのインベントリファイルをメンテナンスし続けなければならなくなり、非常に面倒です。

これを解決するために、Ansible公式でEC2 External Inventoryというスクリプトが提供されています。
以下のec2.pyec2.iniがそのEC2 External Inventoryで利用するスクリプトと設定ファイルです。

github.com

実際に動かしてためしてみる

実際にEC2 External InventoryをEC2インスタンス上からためしてみます。

事前準備

ファイルのダウンロード

まず、Ansibleサーバ上にec2.pyec2.iniをダウンロードします。

$ wget https://raw.githubusercontent.com/ansible/ansible/devel/contrib/inventory/ec2.py
$ wget https://raw.githubusercontent.com/ansible/ansible/devel/contrib/inventory/ec2.ini

アクセス権限の設定

つづいて、AnsibleがAWSの環境を見に行くことができるようにAWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYを環境変数に設定します。

$ export AWS_ACCESS_KEY_ID='AKIA1234567890'
$ export AWS_SECRET_ACCESS_KEY='secretkey1234567890'

AnsibleサーバもAWSで動いていて、インスタンスに適切にロールが適用されている場合はこの作業は必要ありません。

以上で事前準備は完了です!

ためしにec2.pyを動かしてみる

ec2.pyを単体で動かすと、以下のような情報がかえってきました。

$ ./ec2.py 
{
"_meta": {
  "ap-northeast-1a": [
    "172.140.1.1", 
    "172.140.1.2"
  ], 
  "tag_Name_kabegiwa_ansible_server": [
    "172.140.1.1"
  ], 
  "tag_Name_kabegiwa_ansible_client": [
    "172.140.1.2"
  ], 
  "type_t2_micro": [ 
    "172.140.1.2"
  ], 
  "type_t2_large": [ 
    "172.140.1.2"
  ], 
  "vpc_id_vpc_12345678": [
    "172.140.1.1", 
    "172.140.1.2"
  ]

AZやリージョン、タグ名などでまとまった情報がJSON形式で応答されていることがわかります。
このひとつひとつがAnsibleでいうグループになります。

Ansibleコマンドを実行する

実際にAnsibleを実行してみます。
Ansibleの-iオプションでec2.pyをわたしてあげるだけです。
たとえば、Nameタグがkabegiwa_ansible_clientのものにpingを実行してみます。

$ ansible -i ec2.py tag_Name_kabegiwa_ansible_client -u ec2-user --private-key='./himitsukagi.pem' -m ping
172.140.1.2 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

無事実行できました!

おわりに

このようにEC2 External Inventoryをつかうことで動的にAnsibleのインベントリファイルを作成することができます。

インフラのコード化と自動化がはかどりますね!!!

入門Ansible

入門Ansible

AnsibleでS3からファイルをダウンロードする3つの方法

AnsibleでS3からファイルをダウンロードする方法を紹介します!

① s3_getを利用する

AnsibleのCloudModuleであるs3_getを利用する方法です。

前提条件

  • ターゲットノードにS3へのアクセス許可が必要

実行コマンド

$ ansible-playbook -i ansible_hosts s3_get.yml

ansible_hosts

[test_server]
172.140.1.1

s3_get.yml

- name: s3_get
  hosts: test_server
  tasks:
   - aws_s3:
       bucket: kabegiwa-bucket
       object: /test.txt
       dest: /home/ec2-user/test.txt
       mode: get

② get_urlを利用する

S3バケットに静的Webサイトホスティングの設定またはオブジェクトごとにPublicアクセスの許可設定を実施し、ダウンロードを行う方法です。

前提条件

  • S3上のファイルは静的WebホスティングまたはPublicアクセスの許可が必要

    実行コマンド

$ ansible-playbook -i ansible_hosts geturl.yml

ansible_hosts

[test_server]
172.140.1.1

geturl.yml

- name: get_url_test
  hosts: test_server
  tasks:
    - get_url: url=https://s3-ap-northeast-1.amazonaws.com/kabegiwa-bucket/test.txt dest=/home/ec2-user/

③ AWSCLIを利用する方法

単純にAnsibleのcommandを利用してAWSCLIを実行させます。

前提条件

  • ターゲットノードにS3へのアクセス許可がなければならない
  • ターゲットノードにAWSCLIがインストールされていなければならない

    実行コマンド

$ ansible-playbook -i ansible_hosts awscli.yml

ansible_hosts

[linux]
172.22.69.51

awscli.yml

- name: awscli_test
  hosts: test_server
  tasks:
    - command: 'aws s3 cp s3://kabegiwa-bucket/test.txt /home/ec2-user/test.txt'

入門Ansible

入門Ansible

S3上のテキストファイルをLambda(Python)で取得する

今回はS3の中に入っているテキストファイルの内容をLambda(Python)で取得してみたいと思います。

S3上には内閣府が公表している国民の休日のcsvファイルの文字コードをutf-8に変換したものを格納しています。

↓これをsjisからutf-8に変換
http://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv

コード

python

以下のような結果が返ってくるはずです。

['国民の祝日月日,国民の祝日名称', '2016-01-01,元日', '2016-01-11,成人の日', '2016-02-11,建国記念の日', '2016-03-20,春分の日', '2016-04-29,昭和の日', '2016-05-03,憲法記念日', '2016-05-04,みどりの日', '2016-05-05,こどもの日', '2016-07-18,海の日', '2016-08-11,山の日', '2016-09-19,敬老の日', '2016-09-22,秋分の日', '2016-10-10,体育の日', '2016-11-03,文化の日', '2016-11-23,勤労感謝の日', '2016-12-23,天皇誕生日', '2017-01-01,元日', '2017-01-09,成人の日', '2017-02-11,建国記念の日', '2017-03-20,春分の日', '2017-04-29,昭和の日', '2017-05-03,憲法記念日', '2017-05-04,みどりの日', '2017-05-05,こどもの日', '2017-07-17,海の日', '2017-08-11,山の日', '2017-09-18,敬老の日', '2017-09-23,秋分の日', '2017-10-09,体育の日', '2017-11-03,文化の日', '2017-11-23,勤労感謝の日', '2017-12-23,天皇誕生日', '2018-01-01,元日', '2018-01-08,成人の日', '2018-02-11,建国記念の日', '2018-03-21,春分の日', '2018-04-29,昭和の日', '2018-05-03,憲法記念日', '2018-05-04,みどりの日', '2018-05-05,こどもの日', '2018-07-16,海の日', '2018-08-11,山の日', '2018-09-17,敬老の日', '2018-09-23,秋分の日', '2018-10-08,体育の日', '2018-11-03,文化の日', '2018-11-23,勤労感謝の日', '2018-12-23,天皇誕生日']

解説

s3_get_objectでバケットとファイル名を指定してskyujitsu.csvを取得します。
その結果はresponseのBody部に格納されますのでそれをreadしてデコード、改行コードでsplitしています。

退屈なことはPythonにやらせよう ―ノンプログラマーにもできる自動化処理プログラミング

退屈なことはPythonにやらせよう ―ノンプログラマーにもできる自動化処理プログラミング

LambdaのトリガにCloudWatchを設定した際にWe currently do not support adding policies for $LATEST. のエラーがでた場合の対処法

LambdaのトリガにCloudWatchを設定した際にWe currently do not support adding policies for $LATEST.のエラーがでた場合の対処法をご紹介します。

事象

バージョンが$LATESTのLambda関数のトリガにCloudWatch Eventsを追加しようとしたところ以下のようなエラーが出てしまいました。

We currently do not support adding policies for $LATEST. (Service: AWSLambda; Status Code: 400; Error Code: InvalidParameterValueException; Request ID: 70ce2637-f806-11e7-91e6-098e8967446a)

f:id:kabegiwakun:20180112202053p:plain

原因

雑な日本語訳をすると「$LATESTのポリシーの追加はサポートされていない」といったようなメッセージのようです。

これの原因はCloudWatchルールにデフォルトの場合、以下のように設定されているためです。
f:id:kabegiwakun:20180113111713p:plain

バージョン/エイリアスの設定の箇所がデフォルトになっており、エイリアスが非修飾のLambda関数を呼び出すようになっているためです。
CloudWatchルールのターゲットはLambda関数のバージョンまたはエイリアス単位で設定してあげる必要あります。
つまり、$LATESTなんてバージョンはしらねーぞというエラーみたいです。

解決策

このエラーを解決するためにはCloudwatchルールのターゲットでこのLambdaの$LATESTの設定を入れてあげればいいわけですが、そのままでは以下のように「項目がありません」と言われてしまいます。
f:id:kabegiwakun:20180113112602p:plain

これを解決するためにLambdaで$LATESTのエイリアスをつくってあげる必要があります。

Lambdaの設定(エイリアス作成)

マネジメントコンソールでLambdaのページに戻り、バージョンで$LATESTを選び、アクションから「エイリアスの作成」を選択します。
f:id:kabegiwakun:20180113112919p:plain

新しいエイリアスの作成ウインドウが開きますのでエイリアスの名前を適当に決め、バージョンで$LATESTを選択します。
f:id:kabegiwakun:20180113113056p:plain

CloudWatchの設定

上記のLambdaの設定を行うと、ターゲットで先程追加したエイリアスが選択できるようになっています。
f:id:kabegiwakun:20180113113410p:plain

これでバージョンが$LATESTのLambda関数のトリガにCloudWatch Eventsを追加することができます!

おわり

まあ言われてみれば当たり前といえば当たり前なんですが、わすれがちです。
デフォルトのエイリアスで非修飾のエイリアスが$LATESTになっているので、特に意識しなくてもいいようにはなっているんですが、特殊な設定をしたいといったときには有効です。

Amazon Web Services 業務システム設計・移行ガイド (Informatics&IDEA)

Amazon Web Services 業務システム設計・移行ガイド (Informatics&IDEA)

  • 作者: 佐々木拓郎,林晋一郎,瀬戸島敏宏,宮川亮,金澤圭
  • 出版社/メーカー: SBクリエイティブ
  • 発売日: 2018/01/20
  • メディア: 単行本
  • この商品を含むブログを見る

停止中のインスタンスのIAMロールを置換するとエラーになる

だいたいタイトルのとおりです。
停止中のEC2インスタンスのIAMロールを置換しようとするとエラーがでて、置換することができません。

以下のようなエラーがでます。

when calling the ReplaceIamInstanceProfileAssociation operation: The association iip-assoc-000000000012345678 is not the active association

そんなときは一度IAMロールをデタッチしてあげる必要があります。
IAMロールA→ロールなし→IAMロールB
といったかんじです。
 

なんでこんなことしなきゃいけないんだと思って調べていたらIAMロールの置換ができるのは実行中のインスタンスのIAMロールだけとのこと。

IAM ロールを置き換える 実行中のインスタンスの IAM ロールを置き換えることができます。

docs.aws.amazon.com

CLIなどでスクリプトを組む際は注意しなきゃいけませんね!

Amazon Web Services 業務システム設計・移行ガイド

Amazon Web Services 業務システム設計・移行ガイド

  • 作者: NRIネットコム株式会社:佐々木拓郎,林晋一郎,株式会社野村総合研究所:瀬戸島敏宏,宮川亮,金澤圭
  • 出版社/メーカー: SBクリエイティブ
  • 発売日: 2018/01/20
  • メディア: 単行本
  • この商品を含むブログを見る

AWSCLI describe-instances でよく使うコマンドまとめ【随時更新】

EC2インスタンスの一覧を見るAWS CLIのdescribe-instancesコマンドでよくつかっているコマンドを紹介します。

リージョン内のすべてのインスタンスの情報を取得

aws ec2 describe-instances

特定のインスタンスIDの情報を取得

aws ec2 describe-instances --instance-ids i-xxxxxxxx

複数指定の場合はスペース区切りでインスタンスIDを列挙する。

aws ec2 describe-instances --instance-ids i-xxxxxxxx i-yyyyyyyy i-zzzzzzzz

起動中のインスタンスのみ取得

aws ec2 describe-instances --filter "Name=instance-state-name,Values=running"

停止中の場合はValues=stoppingで取得可能。
他にもpending,shutting-down,terminated,stoppingが指定可能です。

特定のインスタンスタイプのみ取得

aws ec2 describe-instances --filter "Name=instance-type,Values=t2.micro"

特定のVPC内のインスタンスのみ取得

 aws ec2 describe-instances --filter "Name=vpc-id,Values=vpc-xxxxxxxx"

タグが一致するものを取得

以下の例だとNameタグがwawawaのインスタンスの情報を取得します。

aws ec2 describe-instances --filter "Name=tag:Name,Values=wawawa

リージョン内のインスタンスIDの一覧を取得

aws ec2 describe-instances  --query 'Reservations[].Instances[].InstanceId'

インスタンスIDとインスタンスタイプを取得

aws ec2 describe-instances --query 'Reservations[].Instances[].{instanceid:InstanceId,instancetype:InstanceType}'

インスタンスIDとNameタグを取得

aws ec2 describe-instances --query 'Reservations[].Instances[].{instanceid:InstanceId,Tags:Tags[?Key==`Name`].Value|[0]}'

インスタンスIDとそれにアタッチされているEBSを取得

aws ec2 describe-instances --query 'Reservations[].Instances[].{instanceid:InstanceId,ebs:BlockDeviceMappings[].Ebs.VolumeId}'

インスタンスIDとそれにアタッチされているセキュリティグループを取得

aws ec2 describe-instances --query 'Reservations[].Instances[].{instanceid:InstanceId,security_groups:SecurityGroups[].GroupName[]}'

インスタンスIDとプライベートIPアドレスを取得

aws ec2 describe-instances --query 'Reservations[].Instances[].{ipaddress:NetworkInterfaces[].PrivateIpAddress[]',instanceid:InstanceId}

昇順でソートしてインスタンスIDを取得

aws ec2 describe-instances --query 'sort(Reservations[].Instances[].InstanceId)'

降順でソートしてインスタンスIDを取得

aws ec2 describe-instances --query 'reverse(sort(Reservations[].Instances[].InstanceId))'

インスタンスIDで昇順でソートして、インスタンスIDとプライベートIPを取得

aws ec2 describe-instances --query 'sort_by(Reservations[].Instances[].{ipaddress:NetworkInterfaces[].PrivateIpAddress[],instanceid:InstanceId,name:Tags[?Key==`Name`].Value|[0]},&instanceid)'

Amazon Web Services 業務システム設計・移行ガイド (Informatics&IDEA)

Amazon Web Services 業務システム設計・移行ガイド (Informatics&IDEA)

  • 作者: 佐々木拓郎,林晋一郎,瀬戸島敏宏,宮川亮,金澤圭
  • 出版社/メーカー: SBクリエイティブ
  • 発売日: 2018/01/20
  • メディア: 単行本
  • この商品を含むブログを見る

S3で一定期間が経過したファイルをGlacierに格納する

S3上にアクセスログを定期的に書き込むようなシステムがあったとして、古いアクセスログも残しておこなければならないんだけどそんなに頻繁に利用するわけではないから安価に保存したいといった場合があります。

これらを実現するために S3バケットにライフサイクルルールを設定し、古いログを削除するよう設定します。

ライフサイクルルールの設定手順

ライフサイクルルールの設定はバケット単位で設定します。

バケットの「管理」の「ライフサイクル」から「ライフサイクルルールの追加」を選択します。
f:id:kabegiwakun:20171123200009p:plain

ライフサイクルルールの「ルール名」に任意のルールを設定します。
フィルターの追加も任意で構いません。
これを設定するとtest/ディレクトリ以下のオブジェクトにのみライフサイクルを設定するといった設定ができます。
f:id:kabegiwakun:20171123200434p:plain

移行の設定で「現行バージョン」にチェックを入れ、オブジェクト作成から「AmazonGlacierへの移行の期限」を選択します。
オブジェクト作成からの日数にGlacierへ移行するまでの日数を入力します。
今回は確認のために1日としています。 f:id:kabegiwakun:20171123204855p:plain

設定の失効はとくに何も設定せずそのまま「次へ」でかまいません。
f:id:kabegiwakun:20171123204915p:plain

設定の内容が正しいことを確認して「保存」します。
f:id:kabegiwakun:20171123205219p:plain

S3の設定は以上で完了です。

実行結果

これが f:id:kabegiwakun:20171204162249p:plain
こうなります。
f:id:kabegiwakun:20171204162101p:plain

ストレージクラスがGlacierとなっているのがわかります。
Glacierに新たにボールドが作成されるわけでなく、S3から各オブジェクトを確認することになります。

Amazon Web Services実践入門 (WEB+DB PRESS plus)

Amazon Web Services実践入門 (WEB+DB PRESS plus)

Ubuntu16.04で拡張ネットワーキングをONにする【AWS】

EC2で拡張ネットワーキングを有効化する設定方法をご紹介します。

そもそも拡張ネットワーキングとは?

拡張ネットワーキングは、高い帯域幅、1 秒あたりのパケット (PPS) の高いパフォーマンス、常に低いインスタンス間レイテンシーを実現します。拡張ネットワーキングは追加料金なしで使用できます。

Linux の拡張ネットワーキング - Amazon Elastic Compute Cloud

ということです。
つまり有効にするだけで通信が早くなるというすぐれものです。

設定方法

Ubuntuでネットワーキングを有効にする方法を記載します。

環境

  • Ubuntu Server 16.04 LTS (HVM), SSD Volume Type - ami-15872773

ネットワークインターフェイスドライバーを確認する

ethtoolコマンドでネットワークインターフェースで利用されているドライバーを確認します。

driverの箇所がixgbevfとなっていたらOKです。「拡張ネットワーキングの設定を行う」まで読み飛ばしてもらって構いません。
以下の場合はvifとなっているのでネットワークインターフェースの設定を実施する必要があります。

$ ethtool -i ens3
driver: vif
version:
firmware-version:
expansion-rom-version:
bus-info: vif-0
supports-statistics: yes
supports-test: no
supports-eeprom-access: no
supports-register-dump: no
supports-priv-flags: no

ixgbevfモジュールをインストールする

まずixdbevfのモジュールのソースをwgetでダウンロードします。

wget "sourceforge.net/projects/e1000/files/ixgbevf stable/2.16.4/ixgbevf-2.16.4.tar.gz"

ダウンロードしてきたファイルを解凍します。

tar -zxvf ixgbevf-2.16.4.tar.gz

パッケージを/usr/srcの移動させます。
dkmsがこのパッケージをビルドできるようにするためです。

sudo mv ixgbevf-2.16.4 /usr/src/.

dkms.confを作成して以下のように値を設定します。
そのままコピーで大丈夫です。

sudo vim /usr/src/ixgbevf-2.16.4/dkms.conf

PACKAGE_NAME="ixgbevf"
PACKAGE_VERSION="2.16.4"
CLEAN="cd src/; make clean"
MAKE="cd src/; make BUILD_KERNEL=${kernelver}"
BUILT_MODULE_LOCATION[0]="src/"
BUILT_MODULE_NAME[0]="ixgbevf"
DEST_MODULE_LOCATION[0]="/updates"
DEST_MODULE_NAME[0]="ixgbevf"
AUTOINSTALL="yes"

dkmsを利用してモジュールを追加します。

sudo dkms add -m ixgbevf -v 2.16.4

モジュールをビルドします。

sudo dkms build -m ixgbevf -v 2.16.4

モジュールをインストールします。

sudo dkms install -m ixgbevf -v 2.16.4

拡張ネットワーキングの設定を行う

インスタンスに拡張ネットワーキングの設定を行うには、AWSCLIで以下のコマンドを実行します。

$ aws ec2 modify-instance-attribute --instance-id i-xxxxxxxxxxxxxxxxx --sriov-net-support simple

以下のAWSCLIを実行し、SriovNetSupportValuesimpleとなっていればOKです。

$ aws ec2 describe-instance-attribute --instance-id i-xxxxxxxxxxxxxxxxx --attribute sriovNetSupport
{
    "SriovNetSupport": {
        "Value": "simple"
    },
    "InstanceId": "i-xxxxxxxxxxxxxxxxx"
}

Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版

Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版

S3で一定期間が経過したファイルをライフサイクルで削除したい

S3上にアクセスログを定期的に書き込むようなシステムがあったとして、古いアクセスログを自動的に消す仕組みを作ってみたいと思います。

これらを実現するために S3バケットにライフサイクルルールを設定し、古いログを削除するよう設定します。

ライフサイクルルールの設定手順

ライフサイクルルールの設定はバケット単位で設定します。

バケットの「管理」の「ライフサイクル」から「ライフサイクルルールの追加」を選択します。

ライフサイクルルールの「ルール名」に任意のルールを設定します。
フィルターの追加も任意で構いません。
これを設定するとtest/ディレクトリ以下のオブジェクトにのみライフサイクルを設定するといった設定ができます。

以降の設定は今回はそのまま「次へ」を選択します。
Glacierなどに以降するライフサイクルを設定する場合にはここで設定を行います。

ライフサイクルルールで削除の設定を行います。
「オブジェクトの現行バージョンを執行する」の箇所が重要です。
たとえば30日より前のログが不要である場合には30を設定します。
今回はテストのために1日経過したオブジェクトを削除するように設定しています。

設定を確認して、「保存」を選択します。

実行結果

これが

一日後…

「s3_index.html」が削除されていることがわかります。

まとめ

ライフサイクル機能をつかうことで手動で過去ログを削除するといったわずわらしさから開放されます。

消し忘れや誤った削除も発生しませんので是非活用してみてください。