AWS 雑なメモ書き

CodeCommitで突然403

KeyChain Accessのアプリを開き、codecommitで検索。アクセス制御でURLをマイナスで削除。

Apache Spark

Exception in thread "main" java.lang.IllegalArgumentException: Field "x" does not exist.

sourceのcsvの先頭が

x,y
0.0,0.00112248

で始めないといけない。x,yの行が必要。

cfn_flipコマンド

CloudFormationでJSONとYAMLを変換

AWSがGitHubで公開しているCloudFormationの変換ツールを使ってみた | DevelopersIO

はじめに こんにちは、中山です。 先日AWSがGitHub上に開設しているアカウントを見ていたのですが、便利そうなツールを発見したので本エントリでご紹介したいと思います。…

確認

$ aws dynamodb create-table --endpoint-url http://localhost:8000 --profile private --table-name sample_table \
 --attribute-definitions AttributeName=key,AttributeType=S \
 --key-schema AttributeName=key,KeyType=HASH \
 --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1
{
    "TableDescription": {
        "TableArn": "arn:aws:dynamodb:ddblocal:000000000000:table/sample_table",
        "AttributeDefinitions": [
            {
                "AttributeName": "key",
                "AttributeType": "S"
            }
        ],
        "ProvisionedThroughput": {
            "NumberOfDecreasesToday": 0,
            "WriteCapacityUnits": 1,
            "LastIncreaseDateTime": 0.0,
            "ReadCapacityUnits": 1,
            "LastDecreaseDateTime": 0.0
        },
        "TableSizeBytes": 0,
        "TableName": "sample_table",
        "TableStatus": "ACTIVE",
        "KeySchema": [
            {
                "KeyType": "HASH",
                "AttributeName": "key"
            }
        ],
        "ItemCount": 0,
        "CreationDateTime": 1488946192.292
    }
}
$ aws dynamodb describe-table --table-name sample_table --endpoint-url http://localhost:8000 --profile private
{
    "Table": {
        "TableArn": "arn:aws:dynamodb:ddblocal:000000000000:table/sample_table",
        "AttributeDefinitions": [
            {
                "AttributeName": "key",
                "AttributeType": "S"
            }
        ],
        "ProvisionedThroughput": {
            "NumberOfDecreasesToday": 0,
            "WriteCapacityUnits": 1,
            "LastIncreaseDateTime": 0.0,
            "ReadCapacityUnits": 1,
            "LastDecreaseDateTime": 0.0
        },
        "TableSizeBytes": 0,
        "TableName": "sample_table",
        "TableStatus": "ACTIVE",
        "KeySchema": [
            {
                "KeyType": "HASH",
                "AttributeName": "key"
            }
        ],
        "ItemCount": 0,
        "CreationDateTime": 1488946192.292
    }
}

JSからS3に直接画像のアップロード

S3のCORSの設定で以下のように記述する。

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>http://sample.jp</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>HEAD</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
    <CORSRule>
        <AllowedOrigin>http://localhost</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>HEAD</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

利用料金をSlackに毎日通知

1.アカウント > 設定 から 請求アラートを受け取る を選択して請求額通知を有効化する。 2.SlackをHookするURLを取得する。 3.LambdaでCron設定で毎日回して以下のコードとライブラリをzipにしてアップロードする。

var aws = require('aws-sdk');
var url = require('url');
var https = require('https');
var hookUrl, slackChannel;
var cloudwatch = new aws.CloudWatch({region: 'us-east-1', endpoint: 'http://monitoring.us-east-1.amazonaws.com'});

hookUrl = 'https://hooks.slack.com/services/XXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
slackChannel = 'charge_infra';

var postMessage = function(message, callback) {
    var body = JSON.stringify(message);
    var options = url.parse(hookUrl);
    options.method = 'POST';
    options.headers = {
        'Content-Type': 'application/json',
        'Content-Length': Buffer.byteLength(body),
    };

    var postReq = https.request(options, function(res) {
        var chunks = [];
        res.setEncoding('utf8');
        res.on('data', function(chunk) {
            return chunks.push(chunk);
        });
        res.on('end', function() {
            var body = chunks.join('');
            if (callback) {
                callback({
                    body: body,
                    statusCode: res.statusCode,
                    statusMessage: res.statusMessage
                });
            }
        });
        return res;
    });

    postReq.write(body);
    postReq.end();
};

exports.handler = function(event, context) {
    console.log('Start checking cloudwatch billing info.');

    var startDate = new Date();
    startDate.setDate(startDate.getDate() - 1);

    var params = {
        MetricName: 'EstimatedCharges',
        Namespace: 'AWS/Billing',
        Period: 86400 * 31,
        StartTime: new Date(new Date().setDate(1)),
        EndTime: new Date(),
        Statistics: ['Maximum'],
        Dimensions: [
            {
                Name: 'Currency',
                Value: 'USD'
            }
        ]
    };
    cloudwatch.getMetricStatistics(params, function(err, data) {
        if (err) {
            console.error(err, err.stack);
            context.fail("Failed to get billing metrics.");
        } else {
            console.dir(data);
            var datapoints = data['Datapoints'];
            if (datapoints.length < 1) {
                console.error("There is no billing info.");
                context.fail("There is no billing info.");
            }

            var latestData = datapoints[datapoints.length - 1];
            console.log(latestData);

            var dateString = [startDate.getFullYear(), startDate.getMonth() + 1, startDate.getDate()].join("/");
            var statusColor = "#439FE0";
            var price = Number(latestData['Maximum']);
            if (price > 70) {
                statusColor = "danger";
            } else if (price > 50) {
                statusColor = "warning";
            } else if (price > 30) {
                statusColor = "good";
            }

            var slackMessage = {
                channel: slackChannel,
                attachments: [
                    {
                        color:statusColor,
                        text:"AWS 利用料金(現在): $" + String(price)
                    }
                ]
            };

            postMessage(slackMessage, function(response) {
                if (response.statusCode < 400) {
                    console.info('Message posted successfully');
                    context.succeed();
                } else if (response.statusCode < 500) {
                    console.error("Error posting message to Slack API: " + response.statusCode + " - " + response.statusMessage);
                    context.succeed();
                } else {
                    context.fail("Server error when processing message: " + response.statusCode + " - " + response.statusMessage);
                }
            });
        }
    });
};

参考

  • http://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/monitor_estimated_charges_with_cloudwatch.html
  • http://qiita.com/saku/items/fc6b70a420a5c510de2b

AWSシークレットキーをcommitするのを防止

git secrets --install /path/to/project --register-aws

Basic認証下のHealth checkが401が返る

2通りの方法 1.Health check用のURLを設定 2.PingプロトコルをTCPへ変更

  location @app {
    auth_basic "Restricted";
    auth_basic_user_file /etc/nginx/.htpasswd;

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_redirect off;

    proxy_pass http://aokiji_svr;
  }

  location = /healthcheck.txt {
    access_log off;

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
    proxy_redirect off;

    proxy_pass http://aokiji_svr/healthcheck;
  }
<Files healthcheck.txt>
    Satisfy Any
    Allow from all
</Files>

http://stackoverflow.com/questions/23921370/aws-load-balancer-with-no-health-check-or-make-it-work-with-non-200-response http://5net.com/blog/2010/12/elb-healthcheck-with-apache-basicauth.html

IAMユーザで請求書が見れない

IAMポリシーの設定

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "aws-portal:*",
            "Resource": "*"
        }
    ]
}

AWS ウェブサイトへのアクセスのアクティベート

routeアカウントで、[IAM User Access to Billing Information] の横にある [Edit] を押してIAMユーザによる請求書情報ページへのアクティベートをする。 https://docs.aws.amazon.com/ja_jp/awsaccountbilling/latest/aboutv2/grantaccess.html

KMSで暗号化時にS3からダウンロードするとエラー

download failed: s3://kms-test-865011514531/test.txt to ./test_downloaded.txt An error occurred (InvalidArgument) when calling the GetObject operation: Requests specifying Server Side Encryption with AWS KMS managed keys require AWS Signature Version 4. You can enable AWS Signature Version 4 by running the command: 
aws configure set s3.signature_version s3v4

AWS Signature Version 4を有効にする

aws configure set s3.signature_version s3v4

構成図 自動作成

Hava http://dev.classmethod.jp/cloud/aws/generate-aws-architecture-diagrams-automatically-with-hava/

Cloudcraft Live http://dev.classmethod.jp/cloud/cloudcraft-live/

SESの承認メールの送り先のメールが操作できない時

[ACM] SSL証明書発行時のドメイン認証メールをSESで受け取ってみた | DevelopersIO

はじめに AWSが提供するACM(AWS Certificate Manager)、 CloudFront、ELB(2016年4月17日より東京リージョンでも利用可能になりました)で利用できる、 HTTPS通信用のサ…

  • Rule setを有効化しないといけない

S3で静的ホスティングをする場合の注意点

ホスト名とバケット名を一致させる バケットの作成はバケット名はAWS全てのバケット内で一意のものでないと上手くいかない

404 Not Found

Code: NoSuchKey
Message: The specified key does not exist.
Key: already.html
RequestId: 643FE9E94482BB5B
HostId: qcuzLKNL/XXRnOsH1pwrMaUIVR0BW1pudcV4jl6G7OE/ZwqGYLK95HCaf3R2DrtqvXCTr7DW+rQ=
An Error Occurred While Attempting to Retrieve a Custom Error Document

Code: NoSuchKey
Message: The specified key does not exist.
Key: error.html

MFAデバイスを紛失した場合

AWSアカウントの場合→サポートセンターに連絡 IAMユーザーの場合→管理者に連絡して、MFAデバイスの無効化をしてもらう

デバイスが正常に動いているようでもAWSリソースにアクセスできない場合→同期できていない可能性があるので同期し直す

参考

FlyData

AWS Kinesisへのエージェント型ログ収集ツール(Fluentdみたいなかんじ) http://www.flydata.com/ja/resources/flydata-sync/getting-started-sync/

Lambdaでzipでアップロードするときの注意点

ライブラリのinstallのし忘れに注意する(※アップロードするディレクトリ内に含める)

$ pip install requests -t .

(参考)http://qiita.com/Hironsan/items/0eb5578f3321c72637b4

zip化してアップロードする

$ zip -r upload.zip *

確認方法

以下のコマンドを入力する

$ python
Python 3.5.1 (v3.5.1:37a07cee5969, Dec  6 2015, 01:38:48) [MSC v.1900 32 bit (In
tel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from lambda_function import lambda_handler
>>> lambda_handler(None,None)

依存ライブラリの管理方法

$ cat requirements.txt
requests
$ pip install -r requirements.txt ( -t . )

(参考)http://dev.classmethod.jp/cloud/deploy-aws-lambda-python-with-lambda-uploader/

EC2上で169.254.169.254にアクセスして、IPやホスト名、VPC情報などを取得

インスタンスIDを取得

$ curl 169.254.169.254/latest/meta-data/instance-id/
i-577f7355

取得情報一覧

$ curl http://169.254.169.254/latest/meta-data/
ami-id
ami-launch-index
ami-manifest-path
block-device-mapping/
hostname
instance-action
instance-id
instance-type
kernel-id
local-hostname
local-ipv4
mac
metrics/
network/
placement/
profile
public-hostname
public-ipv4
public-keys/
reservation-id
security-groups

参考

意外と知られてない?AWS EC2上で169.254.169.254にアクセスして、IPやホスト名、VPC情報などを取得する方法。 – 人生やまあり

意外と知られていないAWS EC2のインスタンスIDやホスト名、AMI-IDなどの情報を、EC2インスタンス内から取得する方法を紹介。 どんなことができるのか 詳しい説明は後にし…

AWS CodeDeploy + AutoScale 注意点

EC2インスタンスへのタグの付与タイミングとCodeDeployエージェントの起動順序の考慮

#!/bin/bash

## Role タグと Env タグを付与
aws ec2 create-tags \
  --resources $(wget -q -O - http://169.254.169.254/latest/meta-data/instance-id) \
  --tags Key=Role,Value=api Key=Env,Value=production

## プロビジョニングする (Chef, Puppet, Ansible, Itamae)
aws s3 sync s3://itamae-repo/ /path/to/itamae-repo/ --delete
cd /path/to/itamae-repo && itamae local bootstrap.rb --ohai

## CodeDeploy Agent は最後に起動する
service codedeploy-agent start

参考

http://blog.takus.me/2015/12/03/aws-codedeploy-and-auto-scaling/ https://blogs.aws.amazon.com/application-management/post/Tx1NRS217K1YOPJ/Under-the-Hood-AWS-CodeDeploy-and-Auto-Scaling-Integration (AWS公式ブログ)

AWS EC2でELB配下のどれか1台でのみ実行

#!/bin/bash

LOAD_BALANCER_NAME="[ロードバランサ名]"

# Get self instance id and ip address.
MY_INSTANCE=`curl -s 169.254.169.254/latest/meta-data/instance-id/`


# ロードバランサ配下の有効なインスタンスの一覧を取得
INSTANCE_LIST=`aws elb describe-instance-health \
  --load-balancer-name ${LOAD_BALANCER_NAME} \
  --region ap-northeast-1 \
  --query 'InstanceStates[?State==\`InService\`].InstanceId' | jq -r '.[]'`

IS_ACTIVE=0

for INSTANCE in ${INSTANCE_LIST}
do
    if [ ${INSTANCE} = ${MY_INSTANCE} ]; then
        IS_ACTIVE=1
        continue
    fi

    if [ ${INSTANCE} \< ${MY_INSTANCE} ]; then
        exit 1
    fi
done

if [ ${IS_ACTIVE} -eq 1 ]; then
    exit 0
else
    exit 1
fi
#!/bin/bash

check.sh
IS_RUN=$?

if [ $IS_RUN -eq 0 ]; then
    [バッチの実行]
fi

参考

AWS EC2でELB配下のどれか1台でのみ実行 – Qiita

EC2をELB経由でウェブサーバとして、複数台使用しているときに、1台だけでバッチを実行したいとします。いままでは、タグにBatchなどをつけることで、バッチを実行する…

My Twitter & RSS

Leave a Reply

Your email address will not be published. Required fields are marked *