20200522のAWSに関する記事は20件です。

API Gateway → Lambda を実行 同期・非同期 with CloudFormation

AWS CloudFormationを用いて、API GatewayからLambdaを同期・非同期で呼び出します。

CloudFormationテンプレートと、Lambdaソースは以下のような構成にしました。構成を変える場合、LambdaのCodeUriでディレクトリを、Handlerでファイル名を変更できます。

 |
 |--apigateway.yml
 |--Makefile #なくても構わないです。コマンドを毎回打つのが面倒なので作っただけです。
 |--Lambda
      |--test
           test.py
Makefile
.PHONY: deploy
deploy:
    $(call blue , "Lambda package & deploy")
    @aws cloudformation package --template-file apigateway.yml --s3-bucket ご自身のS3バケット名 --output-template-file packaged-template.yml
    @aws cloudformation deploy --template-file packaged-template.yml --stack-name APIGateway

define blue
    @tput setaf 6 && echo $1 && tput sgr0
endef

CloudFormationテンプレート Lambda同期実行版

API GatewayとLambdaを作成します。
以下、Parameters内のlambda-roleというところを、ご自身のIAM Role名に変更してください。

apigateway.yml
AWSTemplateFormatVersion: 2010-09-09
Transform: "AWS::Serverless-2016-10-31"
Description: API Gateway Sample
Parameters:
  #Lambda
  LambdaRole:
    Type: String
    Default: lambda-role

Resources:
  #-------------------------------------------------------
  #   API Gateway
  #-------------------------------------------------------
  #RestApi
  APIGatewayRestApi:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Name: api_gateway

  #Resource
  APIGatewayResource:
    Type: AWS::ApiGateway::Resource
    Properties:
      RestApiId: !Ref APIGatewayRestApi
      ParentId: !GetAtt APIGatewayRestApi.RootResourceId
      PathPart: target_lambda

  #Method
  APIGatewayMethod:
    Type: AWS::ApiGateway::Method
    Properties:
      AuthorizationType: NONE
      HttpMethod: GET
      Integration:
        Type: AWS_PROXY
        IntegrationHttpMethod: POST
        # IntegrationResponses:
        #   - StatusCode: 202
        # PassthroughBehavior: WHEN_NO_TEMPLATES
        # RequestParameters:
        #   "integration.request.header.X-Amz-Invocation-Type": "'Event'"
        # RequestTemplates:
        #   "application/json": !Join
        #     - ""
        #     - - "#set($allParams = $input.params())\n{\n\"body-json\" : $input.json('$'),\n\"params\" : {\n#foreach($type in $allParams.keySet())\n #set($params = $allParams.get($type))\n\"$type\" : {\n #foreach($paramName in $params.keySet())\n \"$paramName\" : \"$util.escapeJavaScript($params.get($paramName))\"\n #if($foreach.hasNext),#end\n #end\n}\n "
        #       - "#if($foreach.hasNext),#end\n#end\n},\n\"stage-variables\" : {\n#foreach($key in $stageVariables.keySet())\n\"$key\" : \"$util.escapeJavaScript($stageVariables.get($key))\"\n #if($foreach.hasNext),#end\n#end\n},\n"
        #       - "\"context\" : {\n \"account-id\" : \"$context.identity.accountId\",\n \"api-id\" : \"$context.apiId\",\n \"api-key\" : \"$context.identity.apiKey\",\n \"authorizer-principal-id\" : \"$context.authorizer.principalId\",\n \"caller\" : \"$context.identity.caller\",\n \"cognito-authentication-provider\" : \"$context.identity.cognitoAuthenticationProvider\",\n \"cognito-authentication-type\" : \"$context.identity.cognitoAuthenticationType\",\n \"cognito-identity-id\" : \"$context.identity.cognitoIdentityId\",\n "
        #       - "\"cognito-identity-pool-id\" : \"$context.identity.cognitoIdentityPoolId\",\n \"http-method\" : \"$context.httpMethod\",\n \"stage\" : \"$context.stage\",\n "
        #       - "\"source-ip\" : \"$context.identity.sourceIp\",\n \"user\" : \"$context.identity.user\",\n \"user-agent\" : \"$context.identity.userAgent\",\n \"user-arn\" : \"$context.identity.userArn\",\n \"request-id\" : \"$context.requestId\",\n \"resource-id\" : \"$context.resourceId\",\n \"resource-path\" : \"$context.resourcePath\"\n }\n}"
        Uri: !Join
          - ""
          - - !Sub "arn:aws:apigateway:${AWS::Region}:lambda:path"
            - !Sub "/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:"
            - !Sub "${AWS::AccountId}:function:${TestLambdaFunction}/invocations"
      MethodResponses:
        # - StatusCode: 202 #default response status code with async invocation
        - StatusCode: 200
      ResourceId: !Ref APIGatewayResource
      RestApiId: !Ref APIGatewayRestApi

  #Deployment
  APIGatewayDeployment:
    Type: AWS::ApiGateway::Deployment
    DependsOn: 
      - APIGatewayMethod
    Properties:
      RestApiId: !Ref APIGatewayRestApi
      StageName: test

  #API Gateway needs to be given the right to invoke AWS Lambda
  APIGatewayLambdaInvokeRole:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !Ref TestLambdaFunction
      Principal: apigateway.amazonaws.com

  #-------------------------------------------------------
  #   Lambda
  #-------------------------------------------------------
  #API Gateway Target Lambda Function
  TestLambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: Lambda/test
      FunctionName: target_lambda
      Handler: target_lambda.lambda_handler
      MemorySize: 128
      Role: !Sub arn:aws:iam::${AWS::AccountId}:role/${LambdaRole}
      Runtime: python3.8
      Timeout: 900
      Environment:
        Variables:
          Key: Value

CloudFormationテンプレート Lambda非同期実行版

非同期の場合、DLQという便利な機能が使えるので、それも付け足しておきます。

以下、Parameters内のlambda-roleというところを、ご自身のIAM Role名に変更してください。

apigateway.yml
AWSTemplateFormatVersion: 2010-09-09
Transform: "AWS::Serverless-2016-10-31"
Description: API Gateway Sample
Parameters:
  #Lambda
  LambdaRole:
    Type: String
    Default: lambda-role

Resources:
  #-------------------------------------------------------
  #   API Gateway
  #-------------------------------------------------------
  #RestApi
  APIGatewayRestApi:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Name: api_gateway

  #Resource
  APIGatewayResource:
    Type: AWS::ApiGateway::Resource
    Properties:
      RestApiId: !Ref APIGatewayRestApi
      ParentId: !GetAtt APIGatewayRestApi.RootResourceId
      PathPart: target_lambda

  #Method
  APIGatewayMethod:
    Type: AWS::ApiGateway::Method
    Properties:
      AuthorizationType: NONE
      HttpMethod: GET
      Integration:
        Type: AWS
        IntegrationHttpMethod: POST
        IntegrationResponses:
          - StatusCode: 202
        PassthroughBehavior: WHEN_NO_TEMPLATES
        RequestParameters:
          "integration.request.header.X-Amz-Invocation-Type": "'Event'"
        RequestTemplates:
          "application/json": !Join
            - ""
            - - "#set($allParams = $input.params())\n{\n\"body-json\" : $input.json('$'),\n\"params\" : {\n#foreach($type in $allParams.keySet())\n #set($params = $allParams.get($type))\n\"$type\" : {\n #foreach($paramName in $params.keySet())\n \"$paramName\" : \"$util.escapeJavaScript($params.get($paramName))\"\n #if($foreach.hasNext),#end\n #end\n}\n "
              - "#if($foreach.hasNext),#end\n#end\n},\n\"stage-variables\" : {\n#foreach($key in $stageVariables.keySet())\n\"$key\" : \"$util.escapeJavaScript($stageVariables.get($key))\"\n #if($foreach.hasNext),#end\n#end\n},\n"
              - "\"context\" : {\n \"account-id\" : \"$context.identity.accountId\",\n \"api-id\" : \"$context.apiId\",\n \"api-key\" : \"$context.identity.apiKey\",\n \"authorizer-principal-id\" : \"$context.authorizer.principalId\",\n \"caller\" : \"$context.identity.caller\",\n \"cognito-authentication-provider\" : \"$context.identity.cognitoAuthenticationProvider\",\n \"cognito-authentication-type\" : \"$context.identity.cognitoAuthenticationType\",\n \"cognito-identity-id\" : \"$context.identity.cognitoIdentityId\",\n "
              - "\"cognito-identity-pool-id\" : \"$context.identity.cognitoIdentityPoolId\",\n \"http-method\" : \"$context.httpMethod\",\n \"stage\" : \"$context.stage\",\n "
              - "\"source-ip\" : \"$context.identity.sourceIp\",\n \"user\" : \"$context.identity.user\",\n \"user-agent\" : \"$context.identity.userAgent\",\n \"user-arn\" : \"$context.identity.userArn\",\n \"request-id\" : \"$context.requestId\",\n \"resource-id\" : \"$context.resourceId\",\n \"resource-path\" : \"$context.resourcePath\"\n }\n}"
        Uri: !Join
          - ""
          - - !Sub "arn:aws:apigateway:${AWS::Region}:lambda:path"
            - !Sub "/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:"
            - !Sub "${AWS::AccountId}:function:${TestLambdaFunction}/invocations"
      MethodResponses:
        - StatusCode: 202 #default response status code with async invocation
      ResourceId: !Ref APIGatewayResource
      RestApiId: !Ref APIGatewayRestApi

  #Deployment
  APIGatewayDeployment:
    Type: AWS::ApiGateway::Deployment
    DependsOn: 
      - APIGatewayMethod
    Properties:
      RestApiId: !Ref APIGatewayRestApi
      StageName: test

  #API Gateway needs to be given the right to invoke AWS Lambda
  APIGatewayLambdaInvokeRole:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !Ref TestLambdaFunction
      Principal: apigateway.amazonaws.com

  #-------------------------------------------------------
  #   Lambda
  #-------------------------------------------------------
  #API Gateway Target Lambda Function
  TestLambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: Lambda/test
      DeadLetterQueue:
        TargetArn: !GetAtt SQS.Arn
        Type: SQS
      FunctionName: target_lambda
      Handler: target_lambda.lambda_handler
      MemorySize: 128
      Role: !Sub arn:aws:iam::${AWS::AccountId}:role/${LambdaRole}
      Runtime: python3.8
      Timeout: 900
      Environment:
        Variables:
          Key: Value

  #-------------------------------------------------------
  # SQS
  #-------------------------------------------------------
  SQS:
    Type: AWS::SQS::Queue
    Properties:
      QueueName: test
      DelaySeconds: 0
      MaximumMessageSize: 262144
      MessageRetentionPeriod: 345600
      ReceiveMessageWaitTimeSeconds: 20
      VisibilityTimeout: 30
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

S3+Cloudfront+Route53でSPAを公開したときにハマったこと

tl;dr

  • やはりまだACMの証明書はバージニア北部にリージョン設定しておかないとCloudFrontに設定できない
  • S3のバケット名はドメイン名完全一致じゃないとだめ
  • S3のStatic website hostingを設定したときに出てくるエンドポイントをCloudFrontのOrigin Domain Nameに設定しないとStatic website hosting の設定を素通りする、何も効かない

やってたこと

  • S3 + CloudFront + Route53 で静的ホスティングサイトを作成する
  • アップするものはReact(create-react-app)で作成したSPAのbuildファイル
  • CIで自動的に〜とかちょっとすっ飛ばしたかったので手動でS3のバケットに挙げる

ハマったこと

やはりまだACMの証明書はバージニア北部にリージョン設定しておかないとCloudFrontに設定できない

お名前.comでドメイン取得したので、互いにサイトを行ったり来たりで取得した。
最初は四苦八苦あって証明書は取れたもののCloudFrontで設定ができない。

いろいろ調べてみると米国東部 (バージニア北部)us-east-1にリージョンを設定して証明書を取得しないといけないそう。ここでメインドメイン(example.com)の証明書を取得できていないことにも気づいたので、ワイルドカードを使ったドメイン(*.example.com)と一緒にドメインを追加して証明書を取得。

あとはCloudFrontとRoute53の設定をして完了。

S3のバケット名はドメイン名完全一致じゃないとだめ

まあこれは色んなサイトにも書いてあるし公式も説明してる感じなので調べてみてください

まあそんなこんなでルートにアクセスしたらビルド内容の表示ができました。

S3のStatic website hostingを設定したときに出てくるエンドポイントをCloudFrontのOrigin Domain Nameに設定しないとStatic website hosting の設定を素通りする、何も効かない

こいつが一番わからなかった。
前提として、SPAなので用意したバケット直下のindex.htmlを全てのアクセスに関してレスポンスしたい。
その設定がS3のStatic website hostingでできるそう。
でもいくら設定してもできなかった。

なんでかなと思ってCloudFrontとかいろいろ確認してみてやっと理解。

CloudFrontのOrigin Domain Nameに設定していたものが、example.com.s3.amazonaws.comだった。S3のStatic website hosting設定画面に表示されているエンドポイントはexample.com.s3-hoge-ap-northeast-1.amazonaws.comのようにリージョン名がついているものだった。

S3のエンドポイントをCloudFront側に設定して完了。
これで一旦Static website hostingの設定は反映されるように。

最後に

ただここからまだredirect設定(ドメインのあとのパスは残しつつレスポンスはバケット直下のindex.htmlみたいなやつ)をしないといけなくて、そこがちょっとうまく行かず。一旦ここまでをメモとして残しておく。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS LambdaとSlack incoming webhookでサイトの生存確認チェッカーを作る

主要サービスにはいろいろ監視ソフト入れて、トラフィックの異常増大や、生存確認、リソースの利用状況なんかを可視化しているケースが多いと思います。ですが、例えば自社サイト(wordpressとかが多い)はじめ、管理コストをあまりかけられないサービスなりサイトって有りますよね。そんなサイトたちをAWS LambdaとSlackのincoming webhookを使って落ちているときに通知してくれるスクリプトを書いてみました。

Slackのincoming webhookのURLを発行する

ワークスペースの設定 → APP管理 → カスタムインテグレーションへ移動
直リンクだと以下のページ
https://##yourdomain##.slack.com/apps/manage/custom-integrations

Screenshot from 2020-05-22 22-53-18.png

Incoming Webhookの項目を選択 → Slackに追加を選択 → 通知を送りたいSlackチャネルを選択 → 発行されたURLをコピーしておく
Screenshot from 2020-05-22 22-54-17.png

https://hooks.slack.com/services/xxxxxxxx/xxxxxxx/xxxxxxxxxxxxこんな感じのURLが発行されるはずである。これをメモって置きましょう。

Lambdaのクローリングコードを作成

AWS Lambdaから関数の作成を行い、python3.7で以下のコードを書く

from __future__ import print_function

import datetime
import urllib.request
import json


SITES = [
    'https://www.example.com/',
    'https://ここにチェックしたいサイトを入れてね'
    ]
DESCRIPTION = "サイトの生存確認用チェッカーからの連絡"
SLACK_WEBHOOK = 'ここにSlackのincoming webhookのURLをコピペ'
DIFF_JST_FROM_UTC = 9

def lambda_handler(event, context):
    for site in SITES:
        request = urllib.request.Request(site)
        now = datetime.datetime.now() + datetime.timedelta(hours=DIFF_JST_FROM_UTC)
        nowstr = now.strftime("%Y/%m/%d %H:%M:%S")
        try:
            with urllib.request.urlopen(request) as res:
                url = res.geturl()
                print(url)
                if not url == site :
                    raise ValueError("error!")
        except urllib.error.HTTPError as e:
            print('Check failed!')
            post_slack("<!here>\n{0}\n{1}\n※※※※※※※※\n{2}\nHTTP通信エラー\n※※※※※※※※".format(nowstr,site,DESCRIPTION))
            raise
        except urllib.error.URLError as e:
            print('Check failed!')
            post_slack("<!here>\n{0}\n{1}\n※※※※※※※※\n{2}\n URLエラー\n※※※※※※※※".format(nowstr,DESCRIPTION))
            raise
        except ValueError as e:
            print('Check failed!')
            post_slack("<!here>\n{0}\n※※※※※※※※\n{1}\n ルーティングエラー:リダイレクトされている\n※※※※※※※※".format(nowstr,DESCRIPTION))
            raise
        else:
            print('Check passed!')
            # post_slack("{0}\n{1} 成功".format(nowstr,DESCRIPTION))
            return
        finally:
            print('Check complete at {}'.format(str(datetime.datetime.now())))

def post_slack(message):

    send_data = {
        "username": "AWS Lambda",
        "text": message,
    }
    send_text = "payload=" + json.dumps(send_data)
    request = urllib.request.Request(
        SLACK_WEBHOOK, 
        data=send_text.encode("utf-8"), 
        method="POST"
    )
    with urllib.request.urlopen(request) as response:
        response_body = response.read().decode("utf-8")

上記のスクリプトをクローリングさせる

関数作成ページの上の方にあるトリガーの追加をクリック

Screenshot from 2020-05-22 23-21-28.png

CloudWatch Events/EventBridgeを選択して、いい具合にルールを作る。
今回は15分に1回テスト通知させる。もし、時間間隔を変更したいときにはスケジュール式をよしなに書いてみてください。
書き方の公式ドキュメントはこちら

Screenshot from 2020-05-22 23-22-26.png

実際に試してみる

SITESの配列のURLに存在しないページやドメインを記載してみてください。
incoming webhookを設定したSlackチャネルにエラーメッセージが飛んできたら成功です。
なお、このスクリプト、問題ないときには何も発生しません。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS CLI インストールエラー対処法まとめ

参考文献

エラー内容

$ pip install awscli

DEPRECATION: Python 2.6 is no longer supported by the Python core team, please upgrade your Python. A future version of pip will drop support for Python 2.6
The directory '/home/uorat/.cache/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
The directory '/home/uorat/.cache/pip' or its parent directory is not owned by the current user and caching wheels has been disabled. check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
Requirement already satisfied (use --upgrade to upgrade): awscli in /usr/lib/python2.6/site-packages
Requirement already satisfied (use --upgrade to upgrade): botocore==1.0.0b1 in /usr/lib/python2.6/site-packages (from awscli)
Requirement already satisfied (use --upgrade to upgrade): bcdoc<0.16.0,>=0.15.0 in /usr/lib/python2.6/site-packages (from awscli)
Requirement already satisfied (use --upgrade to upgrade): colorama<=0.3.3,>=0.2.5 in /usr/lib/python2.6/site-packages (from awscli)
Requirement already satisfied (use --upgrade to upgrade): docutils>=0.10 in /usr/lib/python2.6/site-packages (from awscli)
Requirement already satisfied (use --upgrade to upgrade): rsa<=3.1.4,>=3.1.2 in /usr/lib/python2.6/site-packages (from awscli)
Requirement already satisfied (use --upgrade to upgrade): argparse>=1.1 in /usr/lib/python2.6/site-packages (from awscli)
Requirement already satisfied (use --upgrade to upgrade): jmespath==0.7.1 in /usr/lib/python2.6/site-packages (from botocore==1.0.0b1->awscli)
Requirement already satisfied (use --upgrade to upgrade): python-dateutil<3.0.0,>=2.1 in /usr/lib/python2.6/site-packages (from botocore==1.0.0b1->awscli)
Requirement already satisfied (use --upgrade to upgrade): ordereddict==1.1 in /usr/lib/python2.6/site-packages (from botocore==1.0.0b1->awscli)
Requirement already satisfied (use --upgrade to upgrade): simplejson==3.3.0 in /usr/lib64/python2.6/site-packages (from botocore==1.0.0b1->awscli)
Requirement already satisfied (use --upgrade to upgrade): six<2.0.0,>=1.8.0 in /usr/lib/python2.6/site-packages (from bcdoc<0.16.0,>=0.15.0->awscli)
Requirement already satisfied (use --upgrade to upgrade): pyasn1>=0.1.3 in /usr/lib/python2.6/site-packages (from rsa<=3.1.4,>=3.1.2->awscli)
/usr/lib/python2.6/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:315: SNIMissingWarning: An HTTPS request has been made, but the SNI (Subject Name Indication) extension to TLS is not available on this platform. This may cause the server to present an in
correct TLS certificate, which can cause validation failures. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#snimissingwarning.
  SNIMissingWarning
/usr/lib/python2.6/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:120: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more in
formation, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning

対処法

◆ pyenv git clone

$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv

◆ bash_profileに追加

$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile

◆ pyenv バージョン指定/インストール

$ pyenv install -l
$ pyenv install 2.7.11

◆ Pythonの切り替え

$ pyenv version
$ pyenv global 2.7.11
$ python --version

aws-cli インストール

$ pip install awscli

aws-cli 番外編①

◆ python-pipを一括インストール

$ yum -y install python-pip

◆ インストール確認

$ pip -V
pip 9.0.3 from /usr/lib/python2.7/site-packages (python 2.7)

◆ aws-cli インストール

$ pip install awscli

aws-cli 番外編②

◆ get-pip.pyでインストール

$ curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
$ sudo python get-pip.py

◆ aws-cli インストール

$ pip install awscli
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSでWordPressを構築する

今回はAWSにWordPressを構築していく。以下の作業が完了していることが前提。

・Webサーバー構築
・AWSでDBサーバーを作成する

WordPress用のDBを作成

RDSにWordPress用のDBを作成する。EC2(Webサーバー)とRDS(DBサーバー)を起動したら、SSH接続して、EC2からRDSに接続する。

UbuntuからEC2にSSH接続してDBに接続
$ sudo ssh -i /home/r-saiki/ダウンロード/aws-key-webserver.pem ec2-user@18.177.125.119
[sudo] r-saiki のパスワード: 
Last login: Tue May 19 11:09:37 2020 from fs96f9c6f1.tkyc217.ap.nuro.jp

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
3 package(s) needed for security, out of 8 available
Run "sudo yum update" to apply all updates.

#DB接続
[ec2-user@ip-10-0-10-10 ~]$ mysql -h database-web.cnxaaqg6tow9.ap-northeast-1.rds.amazonaws.com -u root -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 8.0.17 Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]>

データベース作成

CREATEコマンドでWordPress用のデータベースを作成する。
DEFAULT CHARACTER SETでデフォルトの文字コードをutf8、COLLATEで比較文字コードをutf8で多言語対応の大文字小文字区別なしに指定。

MySQL [(none)]> CREATE DATABASE aws_wordpress_practice DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
Query OK, 1 row affected, 2 warnings (0.01 sec)

MySQL [(none)]> SHOW DATABASES;
+------------------------+
| Database               |
+------------------------+
| aws_wordpress_practice |
| information_schema     |
| mysql                  |
| performance_schema     |
+------------------------+
4 rows in set (0.01 sec)

ユーザー作成

次にWordPress用のユーザーを作成する。@より後ろはホスト。%はどのホストでもアクセスできるという意味。

MySQL [(none)]> CREATE USER 'aws_user'@'%' IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.01 sec)

作成したユーザーにWordPress用のデータベースにアクセスできる権限を与える。

MySQL [(none)]> GRANT ALL ON aws_wordpress_practice.* TO 'aws_user'@'%';
Query OK, 0 rows affected (0.00 sec)

FLUSH PRIVILEGESでテーブルを再ロードし、ユーザーが追加されたかを確認。

MySQL [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

MySQL [(none)]> SELECT user, host FROM mysql.user;
+------------------+-----------+
| user             | host      |
+------------------+-----------+
| aws_user         | %         |
| root             | %         |
| mysql.infoschema | localhost |
| mysql.session    | localhost |
| mysql.sys        | localhost |
| rdsadmin         | localhost |
+------------------+-----------+
6 rows in set (0.00 sec)

作成したユーザーでログインできるかを確認。

MySQL [(none)]> exit;
Bye
[ec2-user@ip-10-0-10-10 ~]$ mysql -h database-web.cnxaaqg6tow9.ap-northeast-1.rds.amazonaws.com -u aws_user -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 17
Server version: 8.0.17 Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> 

WordPressのインストール

次にWordPressをインストールして、Apacheが参照できるように設定する。
amazon-linux-extrasコマンドを使ってphpをダウンロードする。その後にphp php-mbstringをインストール。

[ec2-user@ip-10-0-10-10 ~]$ sudo amazon-linux-extras install -y php7.2
[ec2-user@ip-10-0-10-10 ~]$ sudo yum install -y php php-mbstring

WordPressの最新版をダウンロードして解凍する。

[ec2-user@ip-10-0-10-10 ~]$  wget https://ja.wordpress.org/latest-ja.tar.gz
[ec2-user@ip-10-0-10-10 ~]$ ls
latest-ja.tar.gz
[ec2-user@ip-10-0-10-10 ~]$ tar xzvf latest-ja.tar.gz
[ec2-user@ip-10-0-10-10 ~]$ ls
latest-ja.tar.gz  wordpress

ApacheがWordPressを参照できるように、/var/www/html/以下にファイルをコピーし、権限をapacheに変更する。

[ec2-user@ip-10-0-10-10 ~]$ cd wordpress
[ec2-user@ip-10-0-10-10 ~]$ sudo cp -r * /var/www/html/
[ec2-user@ip-10-0-10-10 ~]$ sudo chown apache:apache /var/www/html/ -R

Apacheを再起動する。

[ec2-user@ip-10-0-10-10 ~]$ sudo systemctl restart httpd.service
[ec2-user@ip-10-0-10-10 ~]$ sudo systemctl status httpd.service
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
  Drop-In: /usr/lib/systemd/system/httpd.service.d
           └─php-fpm.conf
   Active: active (running) since 金 2020-05-22 08:42:23 UTC; 6s ago
     Docs: man:httpd.service(8)
(以下略)

WordPressの設定

ブラウザにドメイン名もしくはIPアドレスを入力して、WordPressにアクセス。
image.png
RDSのダッシュボードにアクセスしてエンドポイントをコピーしておく。
image.png
さあ、始めましょうを選択すると以下の画面になるので、DBを作成した時の情報を入力して送信を選択。
image.png
インストール実行。
image.png
WordPress用のユーザーを作成する。入力後、WordPressをインストールを選択。
image.png
ログインを選択。
image.png
ログインする。
image.png
ログイン成功!!
image.png

終わりに

なんとかWordPressまで作成することができた。次は自分なりに環境をカスタマイズしたり、一から環境構築をしたりして、AWSをマスターしていきたい。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSの「Well-Architected Framework」をまとめてみた

こんにちは!

大変なご時世ですが、自宅のリプレイスを控えております中の人です。
大幅なスペックアップが見込める半面、利用料金の増加に耐えられるかが気になる今日この頃です。。。

image.png

弊社でも使えてたり使いきれてなかったりするAWSですが、この学習もかねて、
その設計原則である「Well-Architected Framework」について私なりにまとめてみました。

この記事のゴール

  • AWS Well-Architected Frameworkがどんなものか知る
  • AWS Well-Architected Frameworkの学習を通じて、クラウドにおける設計原則に触れてみる
  • AWS設計で使える各種サービスの名前を知る
  • 具体的にAWS Well-Architected Frameworkをどう活用するのか、活用できるのかを知る

簡単な目次

  • はじめに ~クラウドの特徴って?~
  • Well-Architected Framework (W-A)
    • 概要等
    • 一般的な設計原則
    • 運用上の優秀性
    • コスト最適化
    • 信頼性
    • パフォーマンス効率
    • セキュリティ
  • W-Aを実用するために便利なモノ・コト
  • まとめ

はじめに ~クラウドの特徴って?~

集中型と分散型

ITシステムは、歴史上、集中型と分散型を繰り返してきました。
現在のパブリッククラウドは集中型で、オンプレは分散型と捉えることができます。

  • 分散型 パーソナルコンピューター・サーバー(DC・オンプレ)
  • 集中型 大型コンピューター(旧型)、パブリッククラウド(現在)

この「前提の違い」というのは、オンプレとクラウドでの勘所の大きなと違いとなってきます。

クラウドの使い方

使い方としては、
「使いたいとき」、「使う分だけ」、「従量課金」
が基本になります。

クラウドの使い方を電気に例えると、

  • スイッチのオンオフで使える (オンプレだと自家発電から)
  • どこからでも使える (発電機の場所にあまりとらわれない)
  • 電柱・電線は共有 (自分で配線しない)
  • 使用量はこっちが決める (準備した電気が余らない)
  • 計測が容易 (利用料・量の計測基盤が提供されており、計測が簡単)

というようになるかなと思います。

Well-Architected Framework (W-A)

「違い」を踏まえた設計について

このように、オンプレとクラウドでは、そもそもの環境基盤からして違ってきますが、
「じゃ、設計の時どうすればいいのか」ということになります

それの設計原則として、AWSでは、「Well-Architected Framework (W-A)」というものを公表しています。
image.png

W-Aの概要

W-Aとは、AWSのソリューションアーキテクトが、AWSユーザーの長年に渡る多く経験との声から作り上げた
「システム設計・運用の”大局的な”考え方とベストプラクティス集」と言えます。
今でも定期的に更新されており、時代の流れに沿ったものとなっています。

参考:AWS Well-Architected

フレームワークの文章は、ホワイトペーパーとして公開されており、
そのフレームワークの中身は、『一般的な設計原則』と以下5つの『』から構成されています。
鬼滅みたい

  1. 運用上の優秀性:ビジネスの価値を提供するための監視、継続的なサポートプロセスの改善などについて
  2. コスト最適化:最も低価格でシステムを実行しビジネスの価値を提供などについて
  3. 信頼性:サービスの中断から回復、需要に対する動的なリソース調達、設定ミス等の軽減などについて
  4. パフォーマンス効率:リソースの効率的な利用、需要の変化やテクノロジーの進化に応じた対処などについて
  5. セキュリティ:リスクの評価と軽減を通したビジネス価値の提供、情報・システム・資産の保護なえどについて

それぞれの『柱』では、

  • 設計原則
  • 定義
  • (定義に対する)ベストプラクティス
  • 主要なAWSサービス
  • リソース(参考資料)

の項目が設けられています。

実際にフレームワークを活用するときは、後述の通り「ヒアリング」を基にするのですが、
まずは各項目の内容について簡単に紹介したいと思います。

一般的な設計原則

5つの『柱』の前に、一般設計原則についてです。
これに関しては、オンプレミスでの考え方をそのまま適用しづらい部分に関してまとまっている項目だと思います。

設計原則の内容は以下の通りです。

実際に稼働して計測し、確実なキャパシティを設計

スペックの試算から始めるのではなく、実際に稼働させてスペックを決める

本番環境と同じスペックおよび構成でテスト

本番環境を簡単に複製・破棄できるため、それによるテストを行い、リリース後の障害を減らす

環境構築の自動化

システム複製を自動化で行えるため、再現性を高めて人為的ミスや工数を減らし、戻しやすくする

頻繁なデプロイによるリスク軽減

ビジネスに合わせた柔軟な対応ができ、設計変更による影響リスクを軽減できる

データを収集、データに基づく意思決定

様々なメトリクス・ログ収集基盤を用いたワークロード分析と改善を進める

ゲームデーを利用し、緊急事態に備える

障害を故意に起こす「ゲームデー」を定期開催し、訓練・改善点洗い出しを行う

運用上の優秀性

次に、各『柱』についてみていきたいと思います。

運用に関する内容が詳しく描かれているのがこの項目です。

本ブログでは、「原則」を紹介し、「ベストプラクティス定義とそれに対する対応」を抜粋するという形でまとめていきたいと思います。

原則

  • 運用をコードで管理・実行
  • ドキュメントをコードと一緒に管理
  • 小規模なリリースを頻繁に実施、切り戻しの容易化
  • 定期的な運用の改善
  • 障害の予測と準備
  • 運用上すべての障害イベントを元にした情報共有と改善促進

ベストプラクティス定義とそれに対する対応

以下3つが挙げられています。

準備

システムの正常化判断基準やコード化、運用フローの標準を行うこと。

サービスとしては以下あたりが挙げられています。
image.png

オペレーション

システムおよび運用の健全性の監視方法、イベントの管理を行うこと。

この『柱』に限らないのですが、特にCloudWatchが重要視されています。
image.png

進化

ログデータ等の分析を行うこと。

分析を行うので、以下のサービスが紹介されています。
image.png

コスト最適化

コスト面の設計について書かれています。

原則

  • 使う時だけ使う、「消費モデル」の導入
  • 全体的な費用効率の測定やアラート設定
  • 費用の分析とリソースの最適化
  • アプリケーションにおけるマネージドサービスの活用 (稼働時間の削減)・・・人とサーバーに対して
  • DC廃止とマネージドサービスの活用 (リソース維持費の削減)・・・家賃、電力や管理費のイメージ

※ちょっとわかりづらかったので、勝手に改変した部分があります。

ベストプラクティス定義とそれに対する対応

費用認識

費用のモニタリング、使用状況の管理と不要リソースの削除を行う

コストにも「監視」があります。また、予算や随時管理できるようなサービスが紹介されています。
image.png

 

費用対効果の高いリソース

適切なマネージドサービス・タイプやサイズ・購入方法等の選択すること

各種マネージドサービスも紹介されていますが、購入方法ということでは以下のサービス(機能?)なんかが挙げられます。
image.png

需要と供給の一致

需要に合わせたスケールの利用

この場合のサービスはAuto Scalingになります。(種類色々ありますが)
image.png

長期的な最適化

新しいマネージドサービスの評価と検討、最適化の常時検討やレビューを行うこと。

サービスというより、AWS公式ブログやイベントなどで最新情報を仕入れ、しっかり検討することについて書かれています。

信頼性

どんなサービスも、可用性が低くては当然ダメなので、その点について書かれています。

原則

  • 復旧手順のテスト
  • 障害からの自動回復 (主要業績評価指標 (KPI) をモニタリング)
  • ⽔平⽅向のスケールによるシステム全体の可⽤性向上
  • キャパシティ推測の禁止
  • 自動化による変更の管理

ベストプラクティス定義とそれに対する対応

基盤

サービス上限の管理、NW構成の管理を行う

上限管理ではTrusted Advisor, NWであればVPCなどが挙げられます。
image.png

変更管理

システム需要の変化およびリソースのモニタリング、変更プロセスの自動化と記録を行う。

ここでもモニタリングです。また、スケーリングも当然必要になってくるので、以下サービス等が紹介されています。
image.png

障害の管理

障害を想定した設計と自動化、KPIを元にしたバックアップとリストアのテスト

自動化に関してだとCloudFormation、バックアップに関してだとS3が挙げられます。
image.png

パフォーマンス効率

ちょっと特殊な構成で書かれている「柱」だと勝手に思っています。

他項目にはないのですが、「選択」では、わりと具体的にサービスの特徴と用途の違いを述べています。
そのサービスについては、今回は抜粋して紹介いたします。

原則

  • 先進的なテクノロジーをサービスとして利用
  • 数分でグローバルに展開
  • サーバーレスアーキテクチャを使⽤
  • 頻繁な実験の実施
  • 特性を理解したサービスの選択

ベストプラクティス定義とそれに対する対応

選択

適切なサービス(コンピューティングリソース・ストレージ・DB・NW)の選択を行う。

大量の具体例が書かれていました。
例えば、

  • コンピューティングでAuto Scalingの活用有無
  • ストレージサービス使い分け (例. EBS or S3)
  • DB(SQL or NoSQL)の使い分け (例. RDS or DynamoDB)
  • NW機能の活用 (例. VPC, Route53)

のようなものです。
image.png
 

レビュー

新機能の取入れ検討を行う。

『コスト最適化の柱』でもあったように、AWS公式ブログやイベントなどで最新情報を仕入れようと書かれています。

モニタリング

パフォーマンスについての監視・検知、アクションの自動化を行う。

例のごとくCloudWatchが紹介されています。これをトリガーに、各種自動化ができます。
image.png

トレードオフ

「整合性、耐久性、 容量」に対する「時間と遅延(レイテンシー)」のトレードオフの検討を行う。

この定義は自分にとって若干分かりづらかったのですが、最終的に「整合性」「料金」「複雑性」に対しての「早さ」のトレードオフというイメージで無理やり腹落ちさせています。
例. CloudFrontを導入して、エッジロケーションを活用する(整合性は下がる。複雑性は増す。)
image.png

セキュリティ

最後の柱ですが、名前の通りセキュリティに関してです。
こちらも多くのサービスが紹介されていました。

原則

  • 認証基盤の実装
  • トレーサビリティの有効化
  • 全レイヤーへのセキュリティの適⽤(多層防御)
  • セキュリティのベストプラクティスの⾃動化
  • 転送中および保存中のデータ保護
  • データへの手入れ・アクセスの原則禁止
  • セキュリティイベントに対する準備

ベストプラクティス定義とそれに対する対応

それぞれに対応するサービスが多数ありました。

アイデンティティ管理とアクセス管理

認証の管理、人・プログラムからのアクセス制御と証跡取得を行う。

認証とアクセス制御ではIAMが要になります。
image.png

発⾒的統制

セキュリティイベントの検知・検出、モニタリング、ログの管理と分析を行う。

以下のサービスが紹介されています。モニタリングだけでなく、ログでもCloudWatchは有効です。
image.png

インフラストラクチャ保護

ソリューションの活用、多層防御の実施。

VPCが例にはなりますが、それ以外にも、多層防御を実現するAWSの各種セキュリティサービスが存在します。
image.png

データ保護

通信中及び保管中の暗号化、耐久性に応じたストレージ種類の選択を行う。

以下が挙げられます。
image.png

インシデント対応

ログの記録、イベントに対するアクションの自動化、コード化による環境の再現

自動化・コード化という意味ではCloudFormationが挙げられます。
image.png

W-Aを実用するために便利なモノ・コト

先述の通り、実際にフレームワークを活用して設計するときは、ホワイトペーパーにもある「ヒアリング項目」に対して回答していくことで、どこまでベストプラクティスに沿っているかを確認することができます。

このヒアリングシートはExcelでも配布されておりますが、それ以外にも活用できるモノ・コトは多数あります。

AWSのソリューションアーキテクトやAWSのW-A認定パートナー

ざっくり言えば、「AWSの人」「AWS販売代理店等の人」に相談することかなと思います。
W-Aと、それを元にしたヒアリングシートにのっとったレビューを受けることができるようになっています。

レビューはソリューションアーキテクト職の人とディスカッション等を行うのですが、
実施プロセスは、W-A ホワイトペーパーの1項目として明確に規定されています。

W-Aパートナーに関しては、以下を参照ください。
https://aws.amazon.com/jp/blogs/psa/aws-well-architected-partner-program/

AWS Well-Architected Tool

image.png

AWS内にある、無料のW-Aのセルフチェックサービスです。
Excelで公開されているチェックシートとは別で、レビューの実施、バージョン管理、レポート出力までがセルフでできるようになったサービスです。
最近日本語対応されたので、よりレビューしやすくなりました。

AWS Trusted Advisor

image.png
image.png

すべてではないですが、W-Aのベストプラクティスに則っているか自動チェックしてくれるサービスです。
この「すべてではない」というのは、運用関連の部分で、ここは各々次第なのではさすがにチェックできません。

指摘の具体性が高く、このサービスを見るだけで、網羅的に状況を把握したり、管理の抜け漏れを探したりできます。
そうやって自動的に評価される内容を確認し、それに沿って改善・対処を行うことで、より「ベストプラクティス」に近い使い方を目指せます。

(参考) AWS認定試験

個人的な意見ですが、各種AWS認定も、ベストプラクティスを学んだり肌で感じたりするのにいい教材の一つだと考えています。
「〇〇の場合なら◇◇サービスを活用」のように、具体的な活用事例からW-Aを理解することもできると思います(ソリューションアーキテクトとか特に)。

※参考
https://aws.amazon.com/jp/certification/certification-prep/
https://aws.amazon.com/jp/certification/certified-solutions-architect-associate/

まとめ

  • クラウドはオンプレと「勘所」が変わる
  • その「勘所」として、AWSはWell-Architected Framework (W-A) を公開している
  • W-Aには、「一般原則」と、以下5つの「柱」が存在する 
    • 運用上の優秀性:ビジネスの価値を提供するための監視、継続的なサポートプロセスの改善
    • コスト最適化:最も低価格でシステムを実行しビジネスの価値を提供
    • 信頼性:サービスの中断から回復、需要に対する動的なリソース調達、設定ミス等の軽減
    • パフォーマンス効率:リソースの効率的な利用、需要の変化やテクノロジーの進化に応じた対処
    • セキュリティ:リスクの評価と軽減を通したビジネス価値の提供、情報・システム・資産の保護
  • W-Aを活用する場合は、レビューを行うツールや体制を知っておくと便利

長くなりましたが、以上となります。

正直60ページ近いホワイトペーパーまとめるのはブログ一本じゃ無理じゃんって途中で思いましたが、
せめて、なんとなーく概要だけ知ってもらえて、なんとなーく活用方法だけでも知ってもらえればと思います。

それでは皆様、くれぐれも健康にはお気を付けくださいね。

この文章が誰かのお役に立てれば幸いです。

参考資料

AWS資料

ホワイトペーパー(2019年7月)

Black Belt「AWS Well-Architected Framework」

AWS以外

作成にあたり、以下参考にさせていただきました。
クラスメソッド様ありがとうございます。

参考にさせていただいた記事

Well-Architected Frameworkの柱「運用の優位性」を読み解いてみた
Well-Architected Frameworkの柱「コスト最適化」を読み解いてみた
Well-Architected Frameworkの柱「信頼性」を読み解いてみた
Well-Architected Frameworkの柱「パフォーマンス効率」を読み解いてみた
Well-Architected Frameworkの柱「セキュリティ」を読み解いてみた
無料のAWS Well-Architected Toolでクラウド最適化への一歩を踏み出そう

書籍

菊池修治,加藤諒,城岸直希,甲木洋介,濱田孝治,藤井元貴,渡辺聖剛,臼田佳祐,江口佳記,千葉淳 著
「みんなのAWS 〜AWSの基本を最新アーキテクチャでまるごと理解!」 (2020) 技術評論社

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS CLIコマンドがCRON実行できない場合には環境変数(認証周り)を確認する

AWS CLIシェルプログラムをCRON実行する場合

このようなS3へファイルをコピーする
シェルプログラムを作ってコマンド実行で動作したので

#!/bin/bash
aws s3 cp ファイル名 s3://backet_name/

そのままCRONへ登録し失敗する理由は大体環境変数まわりかと思います。

  • AWS IAMのクレデンシャル情報(アクセスキー、シークレットキー、リージョン情報など)を環境変数に指定する
  • aws cliのコマンド引数で直接クレデンシャル情報を指定する
  • S3へのアクセス権限を付与したIAMロールをEC2インスタンスに紐づける(未確認)

上記のいづれかの方法を取ればCRONで動作します。

ここでは、環境変数でクレデンシャル情報を指定する方法を記述します。
環境変数でクレデンシャルファイルを指定する例)

#!/bin/bash

export AWS_SHARED_CREDENTIALS_FILE=クレデンシャル情報を保存したファイル
aws s3 cp ファイル名 s3://backet_name/

クレデンシャル情報やIAMに関する詳しい内容につきましては参考情報を

参考情報:
http://dev.classmethod.jp/cloud/aws/how-to-configure-aws-cli/
http://dev.classmethod.jp/cloud/aws/awscli-configure-credential-file-via-envvar/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ECS FARGATE でzabbixを構築30分コース

背景

コンテナ間の接続検証としていずれEC2からECSへ予定のzabbixを対象にした。
ECSはdocker-compose.ymlのlinksが使えない。
ECSのデフォルト値や細かい設定は省略する。

EC2

ロードバランサーを作成

ecs-zabbix_1.PNG

  • ロードバランサー名: infra-test-web
    • AWS Certificate Managerに証明書作成済みならSSL 証明書に追加する。
    • DNS名はRoute53でCNAMEして短くする
    • infra-test-web-2099560009.ap-northeast-1.elb.amazonaws.com → ecs-zabbix.domain.com

ecs-zabbix_2.PNG

  • ターゲットグループ: infra-test-web-tg

ECS

1. タスク定義: zabbix-server&agent

  • タスク定義名: infra-test-zabbix-server
  • 互換性が必要: FARGATE

1-1. コンテナー: zabbix-server

  • コンテナ名: infra-test-zabbix-server
  • イメージ: zabbix/zabbix-server-mysql:centos-4.4.1
  • ポートマッピング: 10051 tcp
  • 環境変数
    • DB_SERVER_HOST = mysql.domain.com
    • MYSQL_DATABASE = zabbix
    • MYSQL_USER = zabbix
    • MYSQL_PASSWORD = zabbix_pwd

1-2 コンテナ: zabbix-agent

  • コンテナ名: infra-test-zabbix-agent
  • イメージ: zabbix/zabbix-agent:centos-4.4.1
  • ポートマッピング: 10050 tcp
  • 環境変数
    • ZBX_SERVER_HOST = infra-test-zabbix-server.local

サービスの作成: zabbix-server

  • サービス名: infra-test-zabbix-server
  • サービスの検出のエンドポイント infra-test-zabbix-server.local <- これが大事!ウェブコンテナから指定するエンドポイントになる

2. タスク定義: zabbix-web

  • タスク定義名: infra-test-zabbix-web
  • 互換性が必要: FARGATE

  • コンテナー

    • コンテナ名: infra-test-zabbix-web
    • イメージ: zabbix/zabbix-web-apache-mysql:centos-4.4.1
    • ポートマッピング: 80 tcp
    • 環境変数
    • DB_SERVER_HOST = mysql.domain.com <- RDSが使えて便利
    • MYSQL_DATABASE = zabbix
    • MYSQL_USER = zabbix
    • MYSQL_PASSWORD = zabbix_pwd
    • TZ = Asia/Tokyo
    • ZBX_SERVER_HOST = infra-test-zabbix-server.local

サービスの作成

ecs-zabbix_4.PNG

  • サービス名: infra-test-zabbix-web
  • ネットワーク構成: 事前に作成したロードバランサーのinfra-test-webを選択

クラスター完成

ecs-zabbix_3.PNG

確認

https://ecs-zabbix.domain.com/

ecs-zabbix_5.PNG

参考にしたスクリプト

  • docker-compose.yml
version: '2'

services:
  zabbix-server-mysql:
    image: zabbix/zabbix-server-mysql
    mem_limit: 134217728
    environment:
      - DB_SERVER_HOST=${DB_SERVER_HOST}
      - MYSQL_DATABASE=${DB_NAME}
      - MYSQL_USER=${DB_USER}
      - MYSQL_PASSWORD=${DB_USER_PASSWORD}
    logging:
      driver: awslogs
      options:
        awslogs-group: "infra-test"
        awslogs-region: "us-east-1"
        awslogs-stream-prefix: "ecs"
    ports:
      - 10051:10051

  zabbix-web-nginx-mysql:
    image: zabbix/zabbix-web-nginx-mysql
    environment:
      - ZBX_SERVER_HOST=zabbix-server-mysql
      - DB_SERVER_HOST=${DB_SERVER_HOST}
      - MYSQL_DATABASE=${DB_NAME}
      - MYSQL_USER=${DB_USER}
      - MYSQL_PASSWORD=${DB_USER_PASSWORD}
      - TZ=Asia/Tokyo
      - COMPOSE_HTTP_TIMEOUT=200
    logging:
      driver: awslogs
      options:
        awslogs-group: "infra-test"
        awslogs-region: "us-east-1"
        awslogs-stream-prefix: "ecs"
    links:
      - zabbix-server-mysql
    ports:
      - 80:80
  • .env
OS=centos
VERSION=4.4.2
DB_SERVER_HOST=mysql.domain.com
DB_NAME=zabbix
DB_USER=zabbix
DB_USER_PASSWORD=zabbix_pwd
HTTP_PORT=8080
TIME_ZONE=Asia/Tokyo

# 0 - basic information about starting and stopping of Zabbix processes;
# 1 - critical information
# 2 - error information
# 3 - warnings
# 4 - for debugging (produces lots of information)
# 5 - extended debugging (produces even more information)
LOG_LEVEL=3

参考

ECSのサービスディスカバリーが東京にやってきて、コンテナ間通信の実装が簡単になりました!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ECS FARGATE でZabbixを構築30分コース

背景

コンテナ間の接続検証としていずれEC2からECSへ予定のzabbixを対象にした。
ECSはdocker-compose.ymlのlinksが使えない。
ECSのデフォルト値や細かい設定は省略する。

EC2

ロードバランサーを作成

ecs-zabbix_1.PNG

  • ロードバランサー名: infra-test-web
    • AWS Certificate Managerに証明書作成済みならSSL 証明書に追加する。
    • DNS名はRoute53でCNAMEして短くする
    • infra-test-web-2099560009.ap-northeast-1.elb.amazonaws.com → ecs-zabbix.domain.com

ecs-zabbix_2.PNG

  • ターゲットグループ: infra-test-web-tg

ECS

1. タスク定義: zabbix-server&agent

  • タスク定義名: infra-test-zabbix-server
  • 互換性が必要: FARGATE

1-1. コンテナー: zabbix-server

  • コンテナ名: infra-test-zabbix-server
  • イメージ: zabbix/zabbix-server-mysql:centos-4.4.1
  • ポートマッピング: 10051 tcp
  • 環境変数
    • DB_SERVER_HOST = mysql.domain.com
    • MYSQL_DATABASE = zabbix
    • MYSQL_USER = zabbix
    • MYSQL_PASSWORD = zabbix_pwd

1-2 コンテナ: zabbix-agent

  • コンテナ名: infra-test-zabbix-agent
  • イメージ: zabbix/zabbix-agent:centos-4.4.1
  • ポートマッピング: 10050 tcp
  • 環境変数
    • ZBX_SERVER_HOST = infra-test-zabbix-server.local

サービスの作成: zabbix-server

  • サービス名: infra-test-zabbix-server
  • サービスの検出のエンドポイント infra-test-zabbix-server.local <- これが大事!ウェブコンテナから指定するエンドポイントになる

2. タスク定義: zabbix-web

  • タスク定義名: infra-test-zabbix-web
  • 互換性が必要: FARGATE

  • コンテナー

    • コンテナ名: infra-test-zabbix-web
    • イメージ: zabbix/zabbix-web-apache-mysql:centos-4.4.1
    • ポートマッピング: 80 tcp
    • 環境変数
    • DB_SERVER_HOST = mysql.domain.com <- RDSが使えて便利
    • MYSQL_DATABASE = zabbix
    • MYSQL_USER = zabbix
    • MYSQL_PASSWORD = zabbix_pwd
    • TZ = Asia/Tokyo
    • ZBX_SERVER_HOST = infra-test-zabbix-server.local

サービスの作成

ecs-zabbix_4.PNG

  • サービス名: infra-test-zabbix-web
  • ネットワーク構成: 事前に作成したロードバランサーのinfra-test-webを選択

クラスター完成

ecs-zabbix_3.PNG

確認

  • https://ecs-zabbix.domain.com/

  • 初期設定ではZabbix ServerのAgentは自身になっているのでzabbix_agentコンテナ名に変更。

  • Zabbixホストのエージェントインターフェース

    • DNS名: zabbix_agent
    • 接続方法: DNS

ecs-zabbix_5.PNG

参考にしたスクリプト

  • docker-compose.yml
version: "3"
services:
  zabbix_db:
    image: mysql:5.7
    environment:
      - MYSQL_DATABASE=${DB_NAME}
      - MYSQL_USER=${DB_USER}
      - MYSQL_PASSWORD=${DB_USER_PASSWORD}
      - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
  zabbix_server:
    image: zabbix/zabbix-server-mysql:${OS}-${VERSION}
    environment:
      - DB_SERVER_HOST=zabbix_db
      - MYSQL_DATABASE=${DB_NAME}
      - MYSQL_USER=${DB_USER}
      - MYSQL_PASSWORD=${DB_USER_PASSWORD}
      - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
      - ZBX_DEBUGLEVEL=${LOG_LEVEL}
    ports:
      - "10051:10051"
    links:
      - zabbix_db
  zabbix_web:
    image: zabbix/zabbix-web-apache-mysql:${OS}-${VERSION}
    environment:
      - ZBX_SERVER_HOST=zabbix_server
      - DB_SERVER_HOST=zabbix_db
      - MYSQL_DATABASE=${DB_NAME}
      - MYSQL_USER=${DB_USER}
      - MYSQL_PASSWORD=${DB_USER_PASSWORD}
      - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
      - PHP_TZ=${TIME_ZONE}
    ports:
      - ${HTTP_PORT}:80
    links:
      - zabbix_server
      - zabbix_db
  zabbix_agent:
    image: zabbix/zabbix-agent:${OS}-${VERSION}
    privileged: true
    environment:
      - ZBX_SERVER_HOST=zabbix_server
    expose:
      - "10050"
    links:
      - zabbix_server
  • .env
OS=centos
VERSION=4.4.1
#VERSION=5.0.0
DB_NAME=zabbix
DB_USER=zabbix
DB_USER_PASSWORD=zabbix
DB_ROOT_PASSWORD=zabbix
HTTP_PORT=38080
TIME_ZONE=Asia/Tokyo
LOG_LEVEL=3

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SSHにてAWSにあるインスタンスにログインできない時の対処法

AWSを学習中のものです。
ローカル環境にて、SSHを使って、AWSにあるインスタンスにログインを試みていました。

エラーの内容

ターミナル
$ ssh -i my-key.pem ec2-user@18.181.72.120
Warning: Identity file my-key.pem not accessible: No such file or directory.
ec2-user@18.181.72.120: Permission denied (publickey).

上記のようなエラーにずっと悩まされていて、やっと解決したので記録に残しておきます。

解決策

「cd .ssh」という隠しフォルダに移動する

ターミナル
$ cd .ssh

フルパスに書き換えて実行する

ターミナル
ssh -i ~/Downloads/my-key.pem ec2-user@18.181.72.120

自分はダウンロードディレクトリに my-key.pemをおきました。

SSHにログイン完了

ターミナル
Last login: Fri May 22 07:05:26 2020 from p2409178-ipbf1128funabasi.chiba.ocn.ne.jp

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/
4 package(s) needed for security, out of 11 available
Run "sudo yum update" to apply all updates.
[ec2-user@ip-10-0-1-10 ~]$ 

接続できました!
「cd .ssh」という隠しフォルダに移動する
フルパスに書き換えて実行する

SSHにてAWSにあるインスタンスにログインできない時、上記を試してみるのも、良いかもしれません。

以下、大変参考にさせていただきました。

SSHにてAWSにあるインスタンスにログインしたい

Warning: Identity file ChatSpace.pem not accessible: No such file or directory. ec2-user@13.112.68.204: Permission denied (publickey).のエラーの解決例

はじめてのssh

インフラエンジニアじゃなくても押さえておきたいSSHの基礎知識

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

EC2インスタンスのSwap領域を作成する

AWSでEC2インスタンスを立ち上げた直後ではインスタンスタイプによっては
SWAP領域が確保されていない場合があります。
※T2、T3インスタンスタイプでは確保されていません。

Swap領域が確保されていないと、メモリを使い果たしてしまった場合
OOM(Out Of Memmory) Killerが実行されます。

OSがAmazonLinux2の場合にSwap領域を1GB確保する手順を
記述します。

1.メモリ情報確認

# free -h
              total        used        free      shared  buff/cache   available
Mem:           985M         49M         60M        388K        875M        771M
Swap:            0B          0B          0B

Swapが確保されていません。

2.Swap領域の確保

Swapで利用する1GBのファイルを作成します。

# sudo dd if=/dev/zero of=/swapfile bs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 14.514 s, 74.0 MB/s

# chmod 600 /swapfile

3.Swapの有効化

#  mkswap /swapfile
Setting up swapspace version 1, size = 1024 MiB (1073737728 bytes)
no label, UUID=660eff32-62d3-4d07-b7ae-c59cbcec4153

# swapon /swapfile

4.メモリ情報確認

# free -h
              total        used        free      shared  buff/cache   available
Mem     985M         50M         58M        388K        876M        770M
Swap:          1.0G          0B        1.0G:      

1GBのSwap領域が確保されました。

5./etc/fstab編集

EC2インスタンスを再起動した場合にSwap領域を確保されるよう
/etc/fstabに、起動時にswapファイルをswap領域としてマウントする
設定を記述します。

# vi /etc/fstab
#
UUID=XXXXXXXXXX     /           xfs    defaults,noatime  1   1
/swapfile swap swap defaults 0 0

6.再起動及び確認

# reboot

再起動後

# free -h
              total        used        free      shared  buff/cache   available
Mem:           985M         48M        779M        388K        157M        791M
Swap:          1.0G          0B        1.0G

完了です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSでMastodonインスタンスを立てる

やること

  • AWS周りの設定
  • Mastodonインスタンスの構築

image.png

前提

  • AWSアカウントがある
  • CUIが扱える
  • 独自ドメインがある

当記事では、以下で構築します
- AWS ルートユーザー(12ヶ月無料期間中)
- 非Docker
- Mastodon v3.1.4
- メールサーバー非構築

実際にやってみる

AWS EC2インスタンスを作成

下記URL通りに基本進めていく

下記URLの説明と違う点

  • Ubuntu 18.04 LTS を選択
  • スペック選択は「無料期間枠の対象」となっているものを選択

http://webfood.info/mastodon-aws-tutorial/#ec2-1

SSHログイン

今回はめんどくさかったので、Windows Terminal でログイン。
Powershell で鍵のあるディレクトリに移動しログイン。

※インスタンス右クリック > 接続からコピれる
image.png

Mastodon 構築

基本的に公式ドキュメント通り
https://docs.joinmastodon.org/admin/install/

公式ドキュメント通りに curl nodejs yarn を導入。

"System packages"を導入する際、apt install -y \ ... でちゃんと導入できなかったら、1個1個順番に入れてください。
1個でも抜けると動きません(←抜けてて動かなかった人)

公式ドキュメント通りに Ruby 導入。mastodonというユーザーを作る。
公式ドキュメント通りにデータベースをつくる。

公式ドキュメント通りに行くと、Mastodon を clone するが、独自にGitで管理しながらいろいろ書き換えたいのならばフォークしておき、フォークからcloneすることをおすすめする。

clone 後もドキュメント通りに進めるが、

bundle config deployment 'true'
bundle config without 'development test'
bundle install -j$(getconf _NPROCESSORS_ONLN)
yarn install --pure-lockfile

上記の yarn install で注意。
ドキュメント通りに nodejs v12.xを入れていないとココでエラーを吐く。
吐いたときはこれで解決するので試してほしい。
yarn install時に、error : The engine "node" is incompatible with this module.

yarn installが終わったら、Mastodon のセットアップウィザードを起動させる。
ここは質問どおりに答えていけばいいだけだ。

終わり次第、公式ドキュメント通りにユーザーを切り替え nginx Let’s Encryptの設定を済ませる。

そして公式ドキュメント通りに進み、最後。

systemctl daemon-reload
systemctl start mastodon-web mastodon-sidekiq mastodon-streaming
systemctl enable mastodon-*

最後 systemctl enable mastodon-*はおそらく動かないと思うので一つ一つ指定してあげよう。
例:systemctl enable mastodon-web

上記コマンドで構築自体は終了。
ちなみに動かなかったときは sudo をつければなんとかなる。

設定したドメインに行くとアカウントの登録ができる。

アカウント周り

Mastodonのセットアップウィザード時に、SMTPサーバー等の設定をしていない人はおそらくアカウント作成してもメールが届かない。
また、シングルユーザモードで利用する人はあえてサーバーを作っていない人もいると思う。

そういったときは

ubuntu $ sudo su - mastodon
mastodon $ cd live
mastodon $ RAILS_ENV=production bundle exec bin/tootctl accounts create [USERNAME] [OPTIONS]
OK
New password: [AUTO_GENERATED_PASSWORD]

これでアカウントの作成ができる。
コマンドについてはコチラを参照→ mastodon コマンド備忘録

もちろん、ログインできたらパスワードは変えようね!

インスタンスの設定

インスタンス自体は立っているが、現状初期設定だ。なので色々変える。

まず、Mastodonにadmin権限のあるアカウントでログイン。
ユーザー設定 > 管理を開くといろいろと設定が出てくる。

image.png

  • ダッシュボード : だいたいのことが分かる
  • サイト設定 : インスタンスの名前などaboutページに表示される内容を編集できる
  • お知らせ : お知らせを掲載できる。(後術)
  • カスタム絵文字 : カスタム絵文字を追加できる(後術)
  • リレー : 連合リレーの設定(後術)

管理 > お知らせ

インスタンスのお知らせを掲載できる。
初心者UIの場合ヘッダーに、上級者UIの場合、ホームタブの上部ボタンから見ることができる。

friends.nicoやBestFriendsにあるトゥート欄の下のお知らせではない。

管理 > 連合リレー

おそらく初期設定のままだと、連合TLが一切流れてこないだろう。
他インスタンスのTLを流すには連合リレーの設定が必要。

いろいろ探してみてください

管理 > カスタム絵文字

カスタム絵文字を登録できます。
連合リレーを登録した後だと、他インスタンスの絵文字がたくさん表示されますが、使うことはできないのでご注意を。

お疲れさまでした。ここまでで一通り完了です。

おわりに

実際に運用していくと重たくなったりいろいろと問題が出てきますが、ググればだいたい出てくるのでググってください。

今後も楽しいマストドンライフを。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【AWS】EIP、パブリックIPアドレス、プライベートIPの違いとは?

はじめに

現在、AWSソリューションアーキテクトアソシエイトの資格について勉強をしています。
今回は、EIP/パブリックIPアドレス/プライベートIPの違いについて学んだのでアウトプットしていきたいと思います。

EIP/パブリックIPアドレス/プライベートIPとは?

EIP

「Elastic IP Address」の略になります。
AWSアカウントに紐づけられた静的なグローバルIPアドレスです。

特徴

  • 再起動してもIPアドレスが維持される
  • 利用していない場合に課金される

課金されるパターン

  • EIPがEC2に関連付けられているが、EC2が停止している場合
  • EIPが付与されているが、どこにも関連付けられていない場合
  • 稼働しているEC2に2つ目のEIPを関連付ける場合

パブリックIPアドレス

インスタンス起動時に自動的に割り当てられる動的なグローバルIPアドレスです。

特徴

  • ランダムに割り当てられるためIPアドレスを指定できない
  • インスタンスを再起動すると別のIPアドレスが割り当てられる
  • IPアドレスを自動で割り当てないことも可能
  • インスタンス内では確認できない。(プライベートIPアドレスのみ)

プライベートIPアドレス

インスタンス作成時に割り当てられる静的なIPアドレスです。
内部ネットワーク内で割り当てられたIPアドレスですね。

特徴

  • インスタンス作成時に必ず割り当てられる
  • インスタンス作成時にIPアドレスを指定できる
  • 再起動しても同じIPアドレスが割り当てられる
  • 内部ネットワーク内のIPアドレス

EIP/パブリックIPアドレス/プライベートIPの違い

IPの種類 静的/動的 内部/外部 端末からの接続 IP割り当て
EIP   静的 外部 OK 自動
パブリックIPアドレス       動的 外部 OK 自動
プライベートIPアドレス      静的 内部 NG 自動/手動

静的と動的の違い

種類 内容
静的(Static)   固定のIPアドレス。再起動しても変更されない。
動的(dynamic)  暫定的に割り当てられているIPアドレス。再起動したら変更される。

実際に「Amazon Linux」で作成したEC2にWindows端末から接続

・EIP

サーバー内ではEIPの確認は不可。

EIP.JPG

・パブリックIPアドレス

サーバー内ではパブリックIPアドレスの確認は不可。
1.JPG

・プライベートIPアドレス

端末からのSSHは不可。赤枠の部分がプライベートIPアドレス。
プライベートIPアドレス.jpg

参考

この1冊で合格! AWS認定ソリューションアーキテクト - アソシエイト テキスト&問題集 Kindle版

EC2 における Public IP と Elastic IPの違いに関して

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS EC2インスタンス SSH接続できない件

やりたかったこと、うまくいかなかったこと

Webアプリケーションのデプロイ先として、AWSのEC2インスタンスを使用したかった。
サーバー内の環境を構築をしようとSSH接続するが、エラーに遭遇し、接続に失敗。

ssh.command
% ssh -i cs.pem XXXX@X.XX.XXX.X
XXXX@X.XX.XXX.X: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

原因

リージョンの選択を誤っていた
スクリーンショット 2020-05-22 11.06.43.png

解決策

リージョンをアジアパシフィック[東京]を選択して、EC2インスタンスの再作成から実施

原因へのたどりつき方

1.SSH接続時のログを確認し、現状調査

ssh.command
% ssh -vvv cs.pem XXXX@X.XX.XXX.X 
OpenSSH_8.1p1, LibreSSL 2.7.3
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 47: Applying options for *
debug1: Connecting to cs.pem port 22.
ssh: Could not resolve hostname cs.pem: nodename nor servname provided, or not known

2.「Could not resolve hostname」からIPアドレスに問題がある仮説を立てる。

名前解決できていないというエラー。名前解決に関してわからない方はこちら。
今回はIPアドレスでSSH接続をしているので、「IPアドレスにそもそも問題があるのでは?」と考える。
この仮説を立てるにはインフラエンジニア時代に培ったAWSの知識を利用しているので、理解できない方はこちらを参照

3.IPアドレスに関連するリージョンの選択、ElasticIPの紐付けを確認

リージョンの確認はトップページからできるので、ElasticIPを確認するまでもなく、解決

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

いつもの公開鍵でアクセスできるEC2を立ち上げる

いつも使っている公開鍵 でアクセスできる Amazon EC2 インスタンスを立ち上げる方法について解説します。

いつも使っている公開鍵とは GitHub に登録しているものを想定しています。
また、 使用する AMI は ubuntu 18.04 のもの想定しています。
AWS コンソールのダッシュボードは 2020/05/22 に私がアクセスした時のものを想定しています。

EC2 インスタンスへのアクセスにいつもの公開鍵を使うようにすることで、AWS のダッシュボードで生成したキーペアを管理する手間を省くことができます。

GitHub に登録している公開鍵について

GitHub に登録している公開鍵は、 https://github.com/ユーザー名.keysという URL で text/plain でアクセスできます。複数の公開鍵を登録している人は複数行で出力されます。

$ curl https://github.com/kamataryo.keys
ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAFd05sWXhWHfY2ciIkghahLY+YLJKvPuRYWUVm4buBrKvDhIgYV6pj5g/M5jTwSr7lS9nx7DV/B+fGh92dOmj/7HAGaByWXTsIHdBsQnCO0Qbu8xbzTbewIYsClfVf5XWagbIHQx02PQv9mlUsBlCaJxr0ZS8gudCRDgOPil/AdlSj4RQ==
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDeivU3S06V2FFYU1a6ekotDU1jeB5F9F3Nd9XD5OSg6pSFSZVcEticSFqSadRmhvTzIKfFihLVlX3aGkEbuj9U705+TSViiSm5xz0R/00UxQMq/iY9by7r8W1oqgCkbupEdHo6ltfEAjFmrYiVKcAuWooIvKb+0DYJBUX9+xCDvaVHynifw586G/TnzBLkwpS93BcDNYYagu1u1Aaik5lXC1tSyzzKqpGaER5ZDVlMSSSa82at2mGIJsGXb/u4D7gPrmX3zgCSviCcCfyTIbk+m9nKg2FAi4uy2yJAvao4y+GpHQk+KIvcKS/os6z/KJi09CA7eTAtYyawffcijfR7
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCgz7nsId0wHKy5qL3CL9qVuiAoP7INZJ1QPvYzkhGLPhZF8DxPcmdb046kWQFYcLUixKDCVByXvv60UDBq56cNGcFxnKSkfSfyBoEXqLY4V4gMlq+gA21D0ddhK7/3kc+HHf8jaEU5wBs2K3oG9KiDnRvHvXvCjanzjDZYS6CrywLjkLKO+0KzS3NwLk2CTH+cDOoR4Vlo5q4PdlANU+XcwIYQzRC8ieiOq8zycH0m60bMCJ+5AY+xqzjrWcsKy/aAHym/Jlp1iyZEbBKV22MivTlb/hGSpaATmSJ0Hdv0D8dTLgRmoj4/nf1hjAEAjsmBPzG39ue6+dJnrV/6BBAH

起動テンプレートの作成

今回は Amazon EC2 の起動テンプレートという機能を使い、インスタンス起動時に GitHub から公開鍵を取得して登録します。

https://ap-northeast-1.console.aws.amazon.com/ec2/v2/home?region=ap-northeast-1#CreateTemplate:

EC2のダッシュボードまたは上記のリンクから起動テンプレートの作成画面に移動して、必要な情報を埋めてください。必須の項目は 起動テンプレート名 のみです。

Screenshot 2020-05-22 11.07.05.png

キーペア の項目は、起動テンプレートに含めないでください という値を選んでおくと使い回しの秘密鍵を使わせないで済むのでセキュアですね。

Screenshot 2020-05-22 11.10.49.png

ユーザーデータの設定

高度な設定 という見出しをクリックしてトグルを開くと、ユーザーデータという項目があります。EC2 の起動時に実行されるされるスクリプトをここに記述することができます。
GitHub から公開鍵を取得して認可済みの公開鍵として登録するスクリプトを記述します。

Screenshot 2020-05-22 11.17.11.png

#!/bin/bash
mkdir -p /home/ubuntu/.ssh
# 以下の URL はあなたのGitHub のユーザー名に置き換えてください
curl https://github.com/ユーザー名.keys >> /home/ubuntu/.ssh/authorized_keys
chmod 700 /home/ubuntu/.ssh
chmod 600 /home/ubuntu/.ssh/authorized_keys

シェバン(#!/bin/bash)がないと正しく実行されないので注意してください。
これでテンプレートの設定は終了です。

テンプレートから EC2 を起動する

テンプレートの起動画面 から作成したテンプレートを選択できます。

Screenshot 2020-05-22 11.32.09.png

テンプレートからインスタンスを起動すると、いつもの公開鍵でSSH接続できるものが立ち上がるはずです。

# <IPアドレス>はEC2インスタンスのものに置き換えてください
$ ssh ubuntu@<IPアドレス>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS CLI設定のアレコレ

環境

macOS

AWS CLI インストール

brew install awscli --upgrade --user

hostname doesn't match というエラーが出た場合は?
=> 確認: Python のバージョンは 2.7.9 以上か

アクセスキーの作成

AWS CLIには
使用している環境でAWS認証情報が設定されている必要がある。

AWSの認証情報を設定するには、使用するIAMユーザーにてアクセスキーを作成する必要がある。
ダッシュボードのここ。

スクリーンショット 2020-05-22 10.35.58.png

AWS Access Key IDAWS Secret Access Keyが発行されるので保存する。

コマンド一発設定(既に設定してある場合は上書きされる)

$ aws configureを実行すると
AWS CLI によってアクセスキーシークレットアクセスキーAWSリージョン出力形式、以上4つの情報の入力が求められる。これらは自動的にdefaultという名前のプロファイル設定群に保存される。(既に設定してある場合は上書きされる)

手動設定(複数プロファイル管理)

  • ~/.aws以下のconfigとcredentialsファイルで確認可能。
  • 手動修正するなどして、複数プロファイル管理も可能。
$ aws configure
AWS Access Key ID [None]: ?*****
AWS Secret Access Key [None]: ?*****
Default region name [None]: ap-northeast-1
Default output format [None]: json

AWS認証プロファイルの設定

AWS認証プロファイルの設定を効かせます。

$ export AWS_PROFILE=don.suwa3.me

現在のセッションにのみ適用されます。

$ env
AWS_PROFILE=don.suwa3.me

わたしはセッションごとに忘れずexportする運用をしています
理由
- 仕事用と個人用でAWS CLIを複数アカウント運用しているため(本当はダメかも)
- 環境変数をbash_profileに固定してしまうと、あとでそのことを忘れそう

ツールでディレクトリごとAWS認証プロファイル設定ができるものもあるらしいです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS CloudFormationを使ってみた

はじめに

  • AWS CloudFormationとは、VPC, Subnet, EC2Instance等のリソースを一括で構築したいときに、yamlファイルに設定を記述して、構築をオートメーション化するサービスである。つまりVPC, Subnet, SecurityGroup, ...などと、何回もマネージメントコンソール上でポチポチする必要がない。
  • yamlじゃなくてjsonでもOK

このCloudFormationによるインフラ構築をAWS CLIを用いて行ってみました。

前提知識

  • VPC, EC2, SecurityGroup, etc.
  • S3
  • AWS CLI
  • 但し、それほど深い知識は必要ない。

Key pairの作成

AWSのkey pairを事前に作成しておく。すでにある場合は問題ない。

yaml fileの作成

aws_cf.yaml(ファイル名は任意)でVPC, Subnet, EC2Instance等のリソースの設定を記述。
自分が作成したものをGitHubにpushしているので、その内容を簡単に解説する。(ほぼしていないが)

これは最初に必ず書く

AWSTemplateFormatVersion: '2010-09-09'
Resources:

VPC

  VPC1:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      Tags:
      - Key: Name
        Value: VPC1

InternetGateway

  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
      - Key: Name
        Value: VPC1-IGW
  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC1
      InternetGatewayId: !Ref InternetGateway

RouteTable

  FrontendRouteTable:
    Type: AWS::EC2::RouteTable
    DependsOn: AttachGateway
    Properties:
      VpcId: !Ref VPC1
      Tags:
      - Key: Name
        Value: VPC1-FrontendRoute
  FrontendRoute:
    Type: AWS::EC2::Route
    DependsOn: AttachGateway
    Properties:
      RouteTableId: !Ref FrontendRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

Subnet


  FrontendSubnet:
    Type: AWS::EC2::Subnet
    DependsOn: AttachGateway
    Properties:
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: us-west-2a
      MapPublicIpOnLaunch: 'true'
      VpcId: !Ref VPC1
      Tags:
      - Key: Name
        Value: VPC1-FrontendSubnet
  FrontendSubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref FrontendSubnet
      RouteTableId: !Ref FrontendRouteTable

SecurityGroup

  SecurityGroup1:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !Ref VPC1
      GroupDescription: Enable some access via user defined port
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 22
        ToPort: 22
        CidrIp: 0.0.0.0/0
      - IpProtocol: tcp
        FromPort: 80
        ToPort: 80
        CidrIp: 0.0.0.0/0
      - IpProtocol: tcp
        FromPort: 8000
        ToPort: 8000
        CidrIp: 0.0.0.0/0
      - IpProtocol: tcp
        FromPort: 8888
        ToPort: 8888
        CidrIp: 0.0.0.0/0
      SecurityGroupEgress:
      - IpProtocol: -1
        FromPort : 0
        ToPort : 65535
        CidrIp: 0.0.0.0/0
      Tags:
      - Key: Name
        Value: Template-SecurityGroup

Interface of EC2

  EC2Interface:
    Type: AWS::EC2::NetworkInterface
    Properties:
      SubnetId: !Ref FrontendSubnet
      GroupSet:
        - !Ref SecurityGroup1
      SourceDestCheck: true

EC2

KeyNameの所は、AWSに登録した公開鍵のKey pairの名前

  EC2Instance1:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: t2.micro
      ImageId: ami-09dd2e08d601bff67
      KeyName: id_rsa_oga
      NetworkInterfaces:
        - NetworkInterfaceId: !Ref EC2Interface
          DeviceIndex: 0
      BlockDeviceMappings:
        - DeviceName: "/dev/sda1"
          Ebs:
            VolumeSize: 15
            VolumeType: gp2
      Tags:
        - Key: Name
          Value: Template-Instance

Elastic IP of EC2

  EC2ControlPortAddress:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc
  EC2AssociateControlPort:
    Type: AWS::EC2::EIPAssociation
    Properties:
      AllocationId: !GetAtt EC2ControlPortAddress.AllocationId
      NetworkInterfaceId: !Ref EC2Interface

AWS CLIを用いたstack作成

stackとはざっくり言うと、上記で解説したaws_cf.yamlに記述しているVPC, EC2などのリソースの集合のこと。
これをAWS CLIを用いて立ち上げ、その後破棄する。

# S3上にyamlファイルを転送
aws s3 mb s3://cf-templates-oga
aws s3 cp ./aws_cf.yaml s3://cf-templates-oga/aws_cf.yaml

# cf-oga1という名前でstack作成
aws cloudformation create-stack --stack-name cf-oga1 --template-body https://cf-templates-oga.s3-us-west-2.amazonaws.com/aws_cf.yaml

# stackを破棄、これを実行するとstackに紐づいているVPC, EC2などのリソースもすべて消える。
aws cloudformation delete-stack --stack-name cf-oga1

もちろんマネージメントコンソールからでもできるが、command line上からやりたかった。

その他

SSH接続するために、Elastic IPのIP addressをcommand lineを通して確認する。

# IP addressを含むEC2の一覧を表示する
aws ec2 describe-addresses

参考文献

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LaravelでS3を操作する時はアクセスキー&シークレットキーではなくIAMロールを使うこと

LaravelからS3を使用する際はStorageファサードでS3を操作することが多いと思う。
その際に私がググった限りでは、ほとんどがアクセスキーとシークレットキーをソースコードにべた書きしているケースばかりだった。
しかし、こちらはアンチパターンなので、ec2で上記を行う場合はIAMロールを使用して、アクセスキー等はAWS側に隠ぺいしてもおう。

ec2にIAMロールを割り当てる手順は転がっているので、ここでは割愛。

Laravel側

config/filesystems.php

    's3' => [
        'driver' => 's3',
        'key' => env('AWS_ACCESS_KEY_ID'),
        'secret' => env('AWS_SECRET_ACCESS_KEY'),
        'region' => env('AWS_DEFAULT_REGION'),
        'bucket' => env('AWS_BUCKET'),
        'url' => env('AWS_URL'),
        'endpoint' => env('AWS_ENDPOINT'),
    ],

.env

    AWS_ACCESS_KEY_ID=
    AWS_SECRET_ACCESS_KEY=
    AWS_DEFAULT_REGION=ap-northeast-1
    AWS_BUCKET=<<バケット名>>

こう記載すると403エラーでS3にアクセスできなくなるので、必ず上記のように空にすること
.env

    AWS_ACCESS_KEY_ID=null
    AWS_SECRET_ACCESS_KEY=null

開発環境はec2じゃなくてローカルだよ~という人

その場合はキーを記載しましょう

.env

    AWS_ACCESS_KEY_ID=<<アクセスキー>>
    AWS_SECRET_ACCESS_KEY=<<シークレットキー>>
    AWS_DEFAULT_REGION=ap-northeast-1
    AWS_BUCKET=<<バケット名>>

ちなみに①

IAMロール割り当てはインスタンス内部でアクセスキー等をちゃんと持っている。
Laravelはfilesystems.phpのkeyとsecretが空だったときは、こちらを読み込むようになっているので、接続できるということですね。

aws configure list

          Name                    Value             Type    Location
          ----                    -----             ----    --------
       profile                <not set>             None    None
    access_key     ****************XXXX         iam-role    
    secret_key     ****************XXXX         iam-role    

ちなみに②

S3はaws-sdk-phpを使用かつ上記をすることでIAMロール割り当てで接続できるが、
他のAWSリソースの中には、aws-sdk-phpではダメでaws-sdk-php-laravelを使用しないと接続できないものがあるらしい。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

『Amazon Web Services 基礎からのネットワーク&サーバー構築』(4)

前回のおさらい

サブネットのなかにサーバーを構築し、SSH接続できるようにした。

今回の目的

構築したサーバーにWebサーバーソフトをインストールし、Webサーバーとしてインターネットに公開する。

大まかな流れ

Apacheのインストール

確認作業

ファイアウォール設定

DNSサーバー構成

まとめ

Apacheのインストール

「サーバーをWebサーバーとして機能させたい。」
→「Webサーバーソフト」をインストールする。
→今回はApache HTTP Serverを使う。

(手順)
1、サーバーにSSH接続
  $ ssh -i my-key.pem ec2-user@[パブリックIP]

2、Apacheをインストール
  $ sudo yum -y install httpd
  yum:管理者コマンド
  -y:ユーザーの確認なしにすぐインストールする指定
  httpd:Apacheを構成する実行ファイル名

3、Apache起動
  $ sudo systemctl start httpd.service
  systemctl:指定したコマンド(ここではhttpd)を(start,stop,restart)するコマンド。

4、サーバーが起動する時、Apacheも自動起動するようにする
  $ sudo systemctl enable httpd.service
  systemctl:自動起動について(enable, disable,list-unit-files)するコマンド。

確認作業

正しく構成されたかどうか
$ sudo systemctl list-unit-files -t service
(httpd.serviceなどがenabledになってる)

サーバー上で実行中のプロセスを確認する
$ ps -ax
ps:実行中のプロセスを確認できる。
-a:すべてのプロセス
-x:他の端末に結び付けられているプロセス
httpdを確認したいときは
$ ps -ax | grep httpd
PID(プロセス番号):プロセスを区別するための番号

ネットワークの待ち受け状態を確認する
$ sudo lsof -i -n -P
Apache:Port80(HTTPのウェルノウンポート)

ファイアウォール設定

今の状態では「ポート22番だけ通して、それ以外は通さない」という設定をしている。
よってポート80の要求が到達しない。
なのでポート80を開ける。

DNSサーバー構成

TCP/IPの世界において、相手先を確認するのは、あくまでIPアドレスである。
ドメイン名でアクセスしても最終的にはIPアドレスに変換する。
この変換する仕組みを「DNS」という。
(手順)
1、「VPC領域」の「DNSホスト名」を有効化する。
2、「Webサーバー」インスタンスの「パブリックDNS」と「プライベートDNS」が確認できる。(前者はインターネットから参照できるDNS名であり、後者はVPC内でしか参照できないDNS名である。)

DNSサーバーの動きを見る
「DNS→IPアドレス」
$ nslookup [パブリックDNS名]

「IPアドレス→DNS」
$ nslookup [パブリックIPアドレス]

*DNSのウェルノウンポートは53である。

まとめ

・サーバーにApacheを入れることにより、Webサーバーにできた。
・ファイアウォールの設定でポート80(HTTP)も通せるようにした。
・IPアドレスだけでなくDNS名でもアクセスできるようになった。

次は「HTTP」の理解を深めようと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【AWS】W-A(AWS Well-Architected Framework)とは?

はじめに

現在、AWS-SAAを学習しております。
今回は、W-A(AWS Well-Architected Framework)についての内容をアウトプットしていきたいと思います。
(ざっくりとしたメモレベルになります。)

W-A(AWS Well-Architected Framework)とは?

クラウド最適化への課題と不安に対する解決方法として整理されたクラウド活用のベストプラクティス集になります。

いわゆる、クラウドに関するノウハウが集まったフレームワーク集です。

具体的には

  • サービス開始から10年以上の経験によって作られたノウハウがベースになっている
  • 常に進化し続けている
  • クラウド活用の設計原則、質問と回答形式(チェックリスト)をまとめたベストプラクティス集

になります。

フレームワーク(5つの柱)

  • 運用上の優秀性
  • セキュリティ
  • 信頼性
  • パフォーマンス効率
  • コスト最適化

運用上の優秀性

「いかに安全に効率よく運用していくか?」というフレームワークになります。

  • ビジネス価値を提供するためのシステムの実行とモニタリング
  • 継続的に運用プロセスと手順を改善すること

話題としては、「日常業務をうまく管理するための定義」「イベントへの対応」等です。

セキュリティ

AWS上に構築されたシステムを守ることにフォーカスしているフレームワークになります。

話題としては、「データの機密性」や「権限管理」等になります。

信頼性

「障害の防止」「障害からの迅速な復旧」にフォーカスしているフレームワーク。

例えば、

  • インフラストラクチャまたはサービスの中断からの復旧のための能力
  • 需要に合わせて動的にコンピューティングリソースを取得する能力

などです。

パフォーマンス効率

コンピューティングリソースの効率的な使用にフォーカスしているフレームワーク。

例えば、

  • ワークロードへの需要に応じた適切なリソースタイプの選択
  • パフォーマンスモニタリング

等が話題としてあります。

コスト最適化

不要なコストの回避に焦点を当てているフレームワーク。

例えば、

  • 最適なリソースタイプが選択されているか?
  • 費用が発生する箇所を把握できているか?

等が話題としてあります。

まとめ

  • W-A(AWS Well-Architected Framework)
    クラウド活用のためのベストプラクティス集

  • 運用上の優秀
    いかに継続的に運用プロセスと手順を改善できるのか?に焦点を当てたフレームワーク

  • セキュリティ
    システムを保護することに焦点を当てたフレームワーク

  • 信頼性
    「障害防止」「障害からの迅速な復旧」に焦点を当てたフレームワーク

  • パフォーマンス効率
    効率的にコンピューティングリソースを利用することに焦点を当てたフレームワーク

  • コスト最適化
    不要なコストの管理に焦点を当てたフレームワーク

参考

書籍
この1冊で合格! AWS認定ソリューションアーキテクト - アソシエイト テキスト&問題集

AWS公式
AWS Well-Architected

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む