AWS サイト

AWSドキュメント

https://aws.amazon.com/jp/documentation/

サンプルコード

https://aws.amazon.com/code

よくある質問

https://aws.amazon.com/jp/faqs/

GitHub レポジトリ

https://github.com/aws
https://github.com/awslabs

CodeCommitで突然403

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

http://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/troubleshooting.html#troubleshooting-macoshttps

Apache Spark

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

sourceのcsvの先頭が

x,y
0.0,0.00112248

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

VPC Lambdaからインターネットへの通信

  • Lambdaをプライベートサブネットに置く
  • パブリックサブネットにNAT Gatewayを設置
  • プライベートサブネットに0.0.0.0/0への送信先の通信をNAT Gatewayへ向けるルートテーブルを紐付ける
  • パブリックサブネットには0.0.0.0/0への送信先の通信をInternet Gatewayへ向けるルートテーブルを紐付ける

http://iryond.hatenablog.com/entry/2017/03/06/232840

ALBの注意点

ロードバランサーのVPC IDをインスタンスと一緒にする->ターゲットが見つからなくなる

Node.jsをhttpsでアクセス

ロードバランサーのリスナーを443に設定
ALBのターゲットを3000で待機

VPC内のLambdaからインターネットへアクセス

NATゲートウェイを用意してルーティングを設定する。
http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/vpc.html#vpc-internet

cfn_flipコマンド

CloudFormationでJSONとYAMLを変換

http://dev.classmethod.jp/cloud/aws/using-cloudformation-converting-tool-developed-by-aws/

ECS タスクがいつのまにか終了するときのデバッグ方法

マネジメントコンソール上でCloudWatchのログ->アクション->ロググループの作成で適当なロググループを作っておきます。
次にタスク定義のコンテナのログ設定で、ドライバーを「awslog」にします。
すると、ロググループとリージョンを設定する項目が追加されるので、自分のリージョンと先程作成したロググループを入力して、リビジョンを作成します。

http://qiita.com/niisan-tokyo/items/d53afccaff1bf0914f47

DynamoDBローカル インストール

$ wget http://dynamodb-local.s3-website-us-west-2.amazonaws.com/dynamodb_local_latest.tar.gz
$ tar xzvf dynamodb_local_latest.tar.gz
$ java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb
$ aws dynamodb list-tables --endpoint-url http://localhost:8000

確認

$ 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
    }
}

GitでElastic Beanstalkにデプロイ

$ git aws.config
$ git aws.push

デフォルトprofile変更

export AWS_DEFAULT_PROFILE=private

AWS CLI アップデート

sudo pip install -U awscli

Terraform vs. CloudFormation

I just wanted to offer the other side. I do devops, we use Terraform, and we’ve had times when Terraform took action that was not present in the plan generated before applying, in production environments. We’ve also had times when it’ll fail mid-apply, be stuck in an inconsistent state (IAM profiles and autoscaling group configurations, specifically), and require manual recovery through modifying or removing resources via the AWS console (although this might be better in the latest version).
We’ll continue to use Terraform at my day job, but I don’t recommend it to colleagues nor clients if they use only AWS resources. Simplicity is the ultimate sophistication, and adding yet another abstraction does not contribute towards that philosophy.

What are people’s thoughts on Cloudformation vs Terraform for a project that only ever expects to use AWS?

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へ変更

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

<pre><code>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;
</code></pre>

}

location = /healthcheck.txt {
access_log off;

<pre><code>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;
</code></pre>

}

<pre><code><br />“`httpd.conf
<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

ALB ターゲットにEC2が現れない

ALB作成時にVPC選択間違えないように注意。

Route53 サブドメインの移譲

http://takumicloud.jp/blog/2016/01/12/route53-subdomain-migrating/

AWSアカウント間でAMIを共有

http://qiita.com/mechamogera/items/d69b457cab2ae5c69f7a

S3のJPEGデータを更新しても変わらない

URLを以下のように変更したら直った。

Before

http://sample-bucket.s3-website-ap-northeast-1.amazonaws.com/hoge.jpg

After

http://s3-ap-northeast-1.amazonaws.com/sample-bucket/hoge.jpg

ECS

EC2インスタンス立ち上げで以下を忘れないように注意。
– AMIでecs-optimizedを選択。
– Amazon EC2 Container Service Role中のAmazonEC2ContainerServiceRoleのロール

ECR

aws ecr get-login --region us-east-1 --profile private

--profile の付け忘れに注意

SQSのメッセージ受信

1.queueを作る(非同期)
2.queueができてるかloopでsleep 1しながら確認し続ける。
3.queueをpollingしてメッセージを受信。

puts "Retrieving the first message from queue ..."
q.poll(:idle_timeout => 5) do |msg|
  puts "Retrieved the message '#{msg.body}'"
end

https://github.com/aws/aws-sdk-ruby/blob/aws-sdk-v1/samples/sqs/add_queue_message.rb

SNSでSMSをsubscribe

81-80-1234-5678 のように指定

ドメインレジストラから取得したドメインをAWSで使用

Route53でHosted zoneを作成して、発行されるNSレコードの4つのネームサーバをドメインレジストラに登録する。

AutoScalingがEC2を起動を繰り返す問題

スクリーンショット 2016-08-29 17.58.20.png

クールダウンタイムを設定すれば良かった?

CloudfrontのCNAME設定

  • CloudFront側
    • General
      • Distribution
        • Alternate Domain Names(CNAMEs): event.micoly.jp
    • Origins
      • Origin Domain Name: micoly.s3.amazonaws.com(Amazon S3 Buckets)
  • Route53
    • CNAME: event.micoly.jp: ****.cloudfront.net

無料枠クレジットの適用のされ方

クレジットが有効期限が短い方から使われる?

スクリーンショット 2016-08-29 17.35.48.png

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

AWS CLI updateできない

--ignore-installed sixをオプションにつける

sudo pip install --upgrade awscli --ignore-installed six

jp.pyがない

updateすれば良い(awc cli 1.10.411.10.56)

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/

サーバレスアーキテクチャ

S3 – (JS) -> API Gateway -> Lambda (-> DynamoDBなど)

細かいメモ

CloudFormationでスタック作成直後に遷移するCloudFormation初期画面ではすぐに反映されない。

AutoScalingの起動が失敗する

VPC IDとAutoScalingの設定で割り当てたセキュリティグループの属するVPC IDを一致させる

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

http://dev.classmethod.jp/cloud/aws/acm-verifydomain-ses/

  • 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リソースにアクセスできない場合→同期できていない可能性があるので同期し直す

参考

http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_mfa_lost-or-broken.html

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/

ElastiCacheのクラスター全体の消去

方法1. Multi-AZを解除してから消去

方法2. Replication GroupsからCreate final snapshot?をNoにして消去

直接消去しようとすると、以下のようなエラーが出る。

Cache cluster hoge1 is serving as primary for replication group hoge and cannot be deleted. To delete the entire replication group, use DeleteReplicationGroup. (Service: AmazonElastiCache; Status Code: 400; Error Code: InvalidCacheClusterState; Request ID: f5d404e4-2d13-11e6-855e-4b99d85a5fe7
Cannot delete the cache cluster because it is the only read replica for replication group hoge which has autofailover enabled or pending. You can disable autofailover and then delete this cache cluster. Alternatively, to delete the entire replication group, use DeleteReplicationGroup. (Service: AmazonElastiCache; Status Code: 400; Error Code: InvalidCacheClusterState; Request ID: 218a8218-2d14-11e6-ac3a-fdca62f1cfe6)

EC2インスタンスの消去

  1. “アタッチされた Elastic IP を解放する”の項目から”Elastic IP の解放 (‘‘)”を選択する
  2. “はい、削除する”を選択する。

#S3からファイルをコピー

-Rではなく–recursiveをつける

aws s3 cp s3://micoly/ . --recursive

AWS CLIを複数アカウントで使い分け

aws configure --profile profile-name
aws service-name function --profile profile-name

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

参考

http://lance104.hatenablog.jp/entry/2014/03/09/235221

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台でのみ実行

“`check.sh
#!/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


```bash #!/bin/bash check.sh IS_RUN=$? if [ $IS_RUN -eq 0 ]; then [バッチの実行] fi

参考

http://qiita.com/idaaki/items/a356d1785a59d4150358

Elasticache

Q: マルチ AZ をサポートするキャッシュノードのタイプは何ですか?

T1 と T2 ファミリーを除く ElastiCache がサポートするマルチ AZ 内のすべてのキャッシュノードが利用可能です。

つまり、Multi AZを設定するとt2.smallなどが選べない

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です