CloudFormation であら便利に静的サイトを作る

cloudpack あら便利カレンダー 2017 の18日目です。

AWS で静的ウェブサイトといえば S3 + CloudFront ですが、その構成を CloudFormation で作る際にあら便利な Tips を入れていこうという記事です。

とりあえず起動してみる

AWS コンソールにログインした状態で、このリンクから Stack を起動できます。

Stack が起動したら、 OutputsURL にアクセスすれば CloudFront/S3 に置かれた静的ページが閲覧できるはずです。

このテンプレートが置いてあるバケットは誰でも List/Get できるので、

$ aws s3 sync s3://cfn-staticweb-example/ .

すれば CloudFormation テンプレートとカスタムリソース用の Lambda ファンクションのソースが入った zip が落ちてきます。そのあとに aws cloudformation create-stack コマンドで起動するもよし、内容を見るも改造するもよしです。

さらに、このファイル一式を生成しているコードは y13i/cfn-staticweb-example にあります。 Serverless Framework を使いつつ、 serverless deploy はせず、 serverless package して出力されたファイルを一部改変して S3 バケットに上げるということをしています。

CFn でどんなあら便利があるの?

CloudFront の利用する・しないの切り替え

CloudFront Distribution は作成にかなり時間が掛かります。このテンプレートでは CloudFront を使わないことも選べるようにしました。

CloudFormation の Conditions を使い、 UseCloudFront という Parametertrue の時のみ Distribution を作成します。さらに S3 Bucket Policy で読み取りを許可する参照元は

  • UseCloudFronttrue

    • CloudFront からのみ可(Origin Access Identity を使用)
  • UseCloudFrontfalse

    • どこからでも可

切り替わるようにしています。

CloudFront の各種パラメーターの切り替え

ACM (AWS Certificate Manager) で発行した証明書を AcmCertificateArn パラメーター指定した場合は Distribution で ViewerCertificate として使用するようにしています。

指定しない場合(値が空文字)の場合は AWS::NoValue 擬似要素を使って、そもそも ViewerCertificate が指定されていないように振る舞うようになっています。

同様に、 Distribution Alias も Parameter で指定された場合のみ設定するテンプレートになっています。

Origin Access Identity の作成

Origin Access Identity は普通には CloudFormation で作成できません!

なんで対応していないのか疑問に思うところですが、文句を言ってもしかたないので Custom Resource使って Lambda Function に作成させています。

インデックスドキュメントの生成

CloudFormation でサポートされている S3 のリソースは BucketBucketPolicy のみです。バケットの内容物は CloudFormation では管理できません。

しかし、前項と同様にカスタムリソースを使えばどうにでもなります。

ここでは、 Parameter で受け付けた IndexDocumentTitleIndexDocumentBodyejs テンプレートに流し込むという処理をして HTML を生成し、バケットに置くという処理をさせてみました

まとめ

Lambda とその周辺環境がそこそこ枯れてきたことで、 Lambda-backed Custom Resource がだいぶ使いやすくなったと感じます。つまり、 CloudFormation の使い勝手も増しているということです。

地味ながら進化を続ける CFn をあら便利に使っていきましょう。

続きを読む

CodeStarバンザイ!数クリックで始めるCI/CDパイプライン

CodeStarを使ってCI/CDパイプラインを構築してみたので、紹介します。

CodeStarとは?

AWSのマネージドサービスであるCodePipeline、CodeCommit、CodeBuild、CodeDeployを使ってCI/CDパイプライン+実行環境をさくっと構築してくれるサービスらしい。

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

よしっ、動かしてみるぞ!!

1.プロジェクト作成

マネジメントコンソールからCodeStarを選び、「start a project」をポチッ。
するとプロジェクトのテンプレートを選択する画面が表示される。

カテゴリは、Web application、Web service、Alexa Skill、Static Websiteから、
言語は、Ruby、Node.js、Java、Python、PHP、HTML 5から、
実行環境は、Beanstalk、EC2、Lambdaから選択できる。
※もちろん存在しない組み合わせもあります。

今の時代っぽいWeb Application×Node.js×Lambdaなんてのも選択できるんですね。

うーん、ここはCodeBuildも使ってみたいし「Web Application×Java Spring×EC2」を選択。

使う1.png

そして、プロジェクト名を入力。インスタンスタイプを設定して。ポチッ、ポチッ。

使う2.png

。。。
はいっ、CI/CDパイプライン構築の作業はこれで終わり。

そして、待つこと10分。
CodePipeline、CodeCommit、CodeBuild、CodeDeployと、これを統合的に確認するためのダッシュボードがいい感じにできちゃいました。
もちろんjavaのwebアプリケーションも起動しています。

ダッシュボード

使う4修正.png

CodePipeline

使う8.png

CodeCommit

使う5.png

CodeBuild

使う6.png

CodeDeploy

使う7.png

デプロイされたjavaのwebアプリケーション

12.png

2.CI/CDパイプライン実行

ここからが本番。
gitへの接続情報をIAMで確認(ユーザ⇒認証情報⇒AWS CodeCommit の HTTPS Git 認証情報「生成」)し、code commit上のソースコードをcloneする。
するとこんなものが落ちてきます。

tree
.
├── README.md
├── appspec.yml
├── buildspec.yml
├── pom.xml
├── scripts
│   ├── install_dependencies
│   └── start_server
└── src
    └── main
        ├── java
        │   └── com
        │       └── aws
        │           └── codestar
        │               └── projecttemplates
        │                   ├── HelloWorldAppInitializer.java
        │                   ├── configuration
        │                   │   ├── ApplicationConfig.java
        │                   │   └── MvcConfig.java
        │                   └── controller
        │                       └── HelloWorldController.java
        ├── resources
        │   └── application.properties
        └── webapp
            ├── WEB-INF
            │   └── views
            │       └── index.jsp
            └── resources
                ├── gradients.css
                ├── set-background.js
                ├── styles.css
                └── tweet.svg

ふむふむ、なるほど。
ここは手っ取り早くCI/CDパイプラインを確認するため、index.jspをちょこっと修正。
そして、code commitにpush。
code commit上で、変更した内容も確認できます。

使う11.png
すると。。。

使う9.png

パイプラインが動き出したーーー
どうやら動きとしては、こんなことをやっているみたい。

  • Source : 新たしいコードがpushされると、code commitからソースコードを取得しS3に格納。
  • Build : S3からソースコードを取得しビルド。そしてビルドしたモジュールをS3に格納。
  • Application : S3に格納されたモジュールをEC2にデプロイ。

待つこと5分。デプロイまで成功。
そして、先程の画面を確認してみると。。。

使う10.png

変わった!
簡単!!

これを使えば

  • Java、Rubyなどメジャーな言語を利用したCI/CDパイプラインを爆速で構築できる。
  • Jenkinsから開放される。

がしかし。。

  • 東京リージョンにはまだ来ていない。
  • CodeStarというかcode commit側の問題になるが、pull requestが使えない。。

本番用のアプリケーション開発環境・実行環境として利用するのは、まだまだ難しいような気もしますが、
pocくらいであればこれで十分かもしれませんね。

続きを読む

AWS独学メモ

頑張って学んでいきます。

サービス俯瞰

コンピューティング関連

サービス名 概要
EC2 仮想サーバー
EC2 Container Service Doker(アプリ実行環境構築ツール)運用サービス
EC2 Container Regstry Dokerイメージ保存・共有サービス。
Elastic Beanstalk .NET/PHP/Python/Ruby/Node.jsアプリを自動でAWSにデプロイ。
Lambda クライアントからのリクエスト発生時に任意プログラミング起動。イベント駆動型サービス。
Auto Scaling CPU使用率等、事前決定条件に応じ、EC2インスタンス増減
Elastic Load Balancing トラフィックに応じ、複数EC2インスタンスに負荷分散

ストレージ・コンテンツ配信

サービス名 概要
S3 ファイルサーバ。画像格納したり。
CloudFront コンテンツ配信ネットワーク。利用者から近い場所から効率よく配信
EBS EC2データを保持するストレージ。EC2のHDD,SSDのような役割。
Elastic File System EC2共有ファイルストレージ
Glacier 低価格ストレージ。仕様頻度低いけど長期保存のバックアップ用。
Import / Export Snowball ペタバイト級の大容量転送サービス。
Storage Gateway オンプレミスとAWSを接続

DB関連

サービス名 概要
RDS DB(MySQL/Oracle/SQL Server/PostgreSQL/Aurora)が利用できる
Database Migration Service 最小限停止時間でDBを移行。オンプレミスのDBサーバからの移行等に用いる
DynamoDB NoSQLデータベスサービス構築/運用。
ElastiCache クラウドでのメモり内キャッシュの管理サービス
Redshift ビッグデータを分析

ネットワーク

サービス名 概要
VPC プライベートネットワーク構築サービス。
Direct Connect オンプレミスのネットワークとAWSのVPCネットワークを直接接続。
Route 53 DNS(ドメイン名とIPアドレスを対応)

開発者用ツール

サービス名 概要
CodeCommit プライベートGit
CodeDeploy 開発アプリを実行環境に自動配置
CodePipeline 継続的デリバリ使用したアプリのリリース

開発ツール

サービス名 概要
CloudWatch AWSリソース監視サービス
CloudFormation テンプレート利用したリソースの作成と管理
CloudTrail ユーザアクティビティとAPI使用状況確認
Config リソースのイベントリ変更の追跡
OpsWorks Chef利用し操作の自動化
Service Catalog 標準化製品の作成と使用
Trusted Advisor パフォーマンスとせきゅりてぃの最適化

セキュリティ

サービス名 概要
IAM AWS認証
Directory Service Active Directoryのホスティングと管理
Inspector アプリのセキュリティ分析
CloudHSM 暗号鍵管理の専用ハードウェア
Key Management Service 暗号鍵作成と管理
WAF 攻撃から保護するファイアウォール

分析

サービス名 概要
EMR Hadoopフレームワーク
Data Pipeline オーケストレーションサービス
Kinesis リアルタイムストリーミングデータとの連携
Machine Learning 機械学習
QuickSight 高速ビジネスインテリジェンスサービス

モバイルサービス

サービス名 概要
Mobile Hub モバイルアプリの構築/テスト/監視
API Gateway RESTful APIの構築/管理
Cofnito ユーザID及びアプリデータの同期
Device Farm iOS/Android/FireOSアプリのテスト
Mobile Analytics アプリ分析の収集/表示/エクスポート
Mobile SDK モバイルソフトウェアの開発キット

アプリケーションサービス

サービス名 概要
AppStream ストリーミングサービス
CloudSearch マネージド型検索サービス
Elastic Transcorder メディアと動画変換
SES Eメール送受信
SNS プッシュ通知サービス
SQS メッセージキューサービス
SWF アプリ同士を連携ワークフローサービス

大企業向け

サービス名 概要
WorkSpaces クラウド上仮想デスクトップパソコンサービス
WorkMail セキュリティ保護、企業向けEメール及びカレンダー
WorkDocs ファイル共有サービス

S3について

用語

用語 意味
バケット データの入れ物
オブジェクト 格納ファイル

ステップ

  1. バケット作成
  2. オブジェクト格納

EC2について

用語

用語 意味
EC2 仮想サーバ。オンプレミスのWindowsサーバやUNIXサーバに相当。
インスタンス 1台の仮想サーバ
EBS(Elastic Block Store) サーバのHDDに相当する仮想ディスク
AMI(Amazon Machine Image) サーバにインストールするOSやミドルウェアやアプリのイメージ。新インスタンスを複数生成時、AMIを利用。
yum パッケージ管理システム
scp(secure copy) SSH機能を用いて、安全にファイル転送する

EC2にSSH接続した

参考ページ1
参考ページ2

ミドルウェアをインストール

yum更新
$ sudo yum -y update
httpdインストール
$ sudo yum  install -y httpd
httpd起動
$ sudo service httpd start
httpd自動起動を確認
$ sudo chkconfig --list httpd
httpd自動起動を設定
$ sudo chkconfig  httpd on
$ sudo chkconfig  httpd off

scp(コンテンツをアップロードする)

【現在ここで躓き中!】
→ 突破!!

参考ページ1

HTTPコンテンツをコピー

HTTPコンテンツのコピー

$ sudo cp /home/ec2-user/index.html /var/www/html/

【現在ここで躓き中!】index.htmlへアクセスできない

続きを読む

AWS S3 Storage Inventory の出力をダウンロードする

やりたいこと

AWS S3 には定期的にバケット内のファイル一覧を出力する Storage Inventory という機能がある。
この機能の出力は マニフェストファイル + データファイル(複数件) という構成になっている。
このままでは扱いが少々面倒なので、一つのファイルにまとめて出力させたい。

コード

言語は Python 3。boto3が必要。

# download_inventory.py
import sys
import json
import gzip
import shutil
import boto3

s3 = boto3.client('s3')

def download_inventory(manifest_bucket, manifest_prefix, outfile):
    checksum_key = manifest_prefix + '/manifest.checksum'
    manifest_key = manifest_prefix + '/manifest.json'

    print('Manifest: s3://{}/{}'.format(manifest_bucket, manifest_key))
    print('Manifest checksum: s3://{}/{}'.format(manifest_bucket, checksum_key))

    checksum_res = s3.get_object(
            Bucket=manifest_bucket,
            Key=checksum_key)
    checksum = checksum_res['Body'].read().decode('utf-8').strip()

    manifest_res = s3.get_object(
            Bucket=manifest_bucket,
            Key=manifest_key,
            IfMatch=checksum)
    manifest_body = manifest_res['Body'].read()

    manifest = json.loads(manifest_body.decode('utf-8'))
    outfile.write((manifest['fileSchema'] + 'n').encode('utf-8'))
    for entry in manifest['files']:
        destbucket = manifest['destinationBucket'].replace('arn:aws:s3:::', '', 1)
        print('Inventory: s3://{}/{}'.format(destbucket, entry['key']))
        inventory_res = s3.get_object(
                Bucket=destbucket,
                Key=entry['key'],
                IfMatch=entry['MD5checksum'])

        with gzip.open(inventory_res['Body']) as f:
            shutil.copyfileobj(f, outfile)

if __name__ == '__main__':
    if len(sys.argv) != 4:
        sys.exit('Usage: python download_inventory.py <output> <manifest bucket> <manifest prefix>')

    with open(sys.argv[1], 'wb') as outfile:
        download_inventory(sys.argv[2], sys.argv[3], outfile)
        print('Saved: ' + sys.argv[1])

使い方

python download_inventory.py 出力先ファイル名 バケット名 マニフェストファイルが存在するバケット名 マニフェストファイルのキープレフィックス

例: マニフェストファイルが s3://mybucket/someprefix/2017-06-22T00-02Z/manifest.json に存在する場合は次の通り。

python download_inventory.py output mybucket someprefix/2017-06-22T00-02Z

インベントリの内容は output に出力される。

続きを読む

:beginner: Amazon EC2 Simple Systems Manager (SSM) エージェントのインストール

:beginner:
Amazon EC2 Systems Managerを使用するためのエージェントを導入するまでの手順です。
内容としては初心者向けになっています。

前提条件

SSMエージェントの導入対象インスタンスからS3へのアクセス(HTTPS)が出来る必要があります。

Simple Systems Manager 用の管理ポリシーを追加

SSMを使用したいインスタンスに割り当てているIAMロールへSSMの管理ポリシーをアタッチする。

ロールがない場合は作成する。
2017-06-21-14-20-20.png

「AmazonEC2RoleforSSM」を選択し「ポリシーのアタッチ」を実施する。
2017-06-21-14-23-37.png

2017-06-21-14-26-28.png

Simple Systems Manager エージェントのインストール

:warning: Amazon Linux、RHEL、および CentOS 64 ビット の 東京リージョンの場合の手順

新規インスタンスの場合はユーザーデーターに以下を追加で定義する。

#!/bin/bash
cd /tmp
sudo yum install -y https://amazon-ssm-ap-northeast-1.s3.amazonaws.com/latest/linux_amd64/amazon-ssm-agent.rpm

既に稼働中のインスタンスの場合はログイン後に以下のコマンドを実行する。

sudo yum install -y https://amazon-ssm-ap-northeast-1.s3.amazonaws.com/latest/linux_amd64/amazon-ssm-agent.rpm
[ec2-user@ip-10-0-2-141 ~]$ sudo yum install -y https://amazon-ssm-ap-northeast-1.s3.amazonaws.com/latest/linux_amd64/amazon-ssm-agent.rpm
Loaded plugins: priorities, update-motd, upgrade-helper
amazon-ssm-agent.rpm                                            | 6.0 MB  00:00:00
Examining /var/tmp/yum-root-Mncwuv/amazon-ssm-agent.rpm: amazon-ssm-agent-2.0.822.0-1.x86_64
Marking /var/tmp/yum-root-Mncwuv/amazon-ssm-agent.rpm to be installed
Resolving Dependencies
amzn-main/latest                                                | 2.1 kB  00:00:00
amzn-updates/latest                                             | 2.3 kB  00:00:00
--> Running transaction check
---> Package amazon-ssm-agent.x86_64 0:2.0.822.0-1 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

=======================================================================================
 Package                Arch         Version             Repository               Size
=======================================================================================
Installing:
 amazon-ssm-agent       x86_64       2.0.822.0-1         /amazon-ssm-agent        17 M

Transaction Summary
=======================================================================================
Install  1 Package

Total size: 17 M
Installed size: 17 M
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : amazon-ssm-agent-2.0.822.0-1.x86_64                                 1/1
amazon-ssm-agent start/running, process 7104
  Verifying  : amazon-ssm-agent-2.0.822.0-1.x86_64                                 1/1

Installed:
  amazon-ssm-agent.x86_64 0:2.0.822.0-1

Complete!
[ec2-user@ip-10-0-2-141 ~]$

Simple Systems Manager エージェントの起動確認

[ec2-user@ip-10-0-2-141 ~]$ sudo status amazon-ssm-agent
amazon-ssm-agent start/running, process 7104
[ec2-user@ip-10-0-2-141 ~]$

ちなみにAmazon Linux の場合 Upstartでの管理になります。

[ec2-user@ip-10-0-2-141 ~]$ sudo initctl list |grep amazon-ssm-agent
amazon-ssm-agent start/running, process 7104
[ec2-user@ip-10-0-2-141 ~]$

Simple Systems Manager への登録確認

EC2 の「SYSTEM MANAGER共有リソース」の「マネージドインスタンス」を選択します。

エージェントをインストールしたインスタンスが登録されていることが確認できます。
2017-06-21-15-11-56.png

続きを読む

IAMでクロスアカウントスイッチロール設定メモ

軽くテストしたので個人的な備忘録です。

★クロスアカウントスイッチロールすると嬉しいこと

複数のAWSアカウント間を認証画面介さず行き来できる
個人用IAMアカウント作るのは一か所でよくアカウント毎でなくなる
SDKつかってるような一部のツールではスイッチできないものもあるがawscliくらいならスイッチロールでいける
スイッチ先で権限を限定してスイッチ元でアカウントの増減を制御できるので
別会社間のメンバーの増減のアカウント管理のやり取りが生じなくてたぶんべんり

アカウント番号はサポート画面の右上に出てる。

★参考

Swith Roleで複数のAWSアカウント間を切替える – Qiita
超簡単!今すぐ使える「クロスアカウントアクセス」 | Developers.IO
AWS Black Belt Techシリーズ AWS IAM
【小ネタ】複数のSwitch Roleでのクロスアカウントアクセスをブラウザのブックマークで管理する | Developers.IO

一番したのやつ履歴が5こくらいまでできえることに憤慨している人は幸せになれそう。

★実際のクロスアカウントスイッチロール実装手順の簡易なメモ

0.テストするアカウントを2つようい

アカウント1
※スイッチ元
Account Number 1234zzzzzzzz

アカウント2
※スイッチ先
アカウント番号 5678xxxxxxxx

1.スイッチ先でロールを作成する

※お客様先にスイッチする場合お客様作業

IAMサービスを選択してロールを作る

新しいロールの作成
 >ロールの選択(クロスアカウントアクセスのロールで外部IDの使用を許可しないほうを選択)
  (※外部ID許可とはldapやadなどのIAMクレデンシャルでないID連携を許可するものと思われ)
  >このアカウントにアクセスできる IAM ユーザーの AWS アカウントの ID を入力(スイッチ元のIDを入力)
   (MFAが必要にチェックはデバイスやアプリの用意が可能な場合に入れる)
   >ポリシーのアタッチ(既存から選ぶのでカスタムにしたいならあらかじめ調べておく)
    (とりあえず試験用なので適当な権限にする(arn:aws:iam::aws:policy/AdministratorAccess ))
    >ロール名を入力:mygroup-admin

2.スイッチ元でロールを設定する

とりあえずユーザとグループを作る

グループ:mygroup
ユーザ:とりあえず二人くらいを作成

グループのインラインポリシーを作成しスイッチ先のアカウントとロールを設定する
ポリシー名:switch-to-otheraccount-name

{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": "sts:AssumeRole",
    "Resource": "arn:aws:iam::5678xxxxxxxx:role/mygroup-admin"
  }
}

3.スイッチ元で自分のユーザで入りなおしてから右上からスイッチロールを選択してスイッチする

アカウント:5678xxxxxxxx
ロール:mygroup-admin

お客様先にスイッチする場合、
・スイッチ元のアカウントIDをお伝えする
・作成したロール名とわたる先のアカウント名とアカウントIDを聞いて設定
・スイッチロールしてみる
・スイッチ履歴は5個くらいしか残らないので便利なリンクを作っておく

ということになります。

★証跡を追えるようにするためにスイッチ元でCloudTrailの設定

見た感じすでに設定済みな模様でござったのでリンク先をどうぞ。S3もみたところ数年前からログがあった。
Amazon Web Services ブログ: 【AWS発表】 AWS CloudTrail – AWS APIコールの記録を保存
AWSの操作履歴を記録するCloudTrailを試してみた « サーバーワークス エンジニアブログ

★アカウントのエイリアスの設定

あんまり関係ないがIDだと視認性が微妙なので設定したほうがよさそう(なくてもいい)

AWS アカウント ID とその別名 – AWS Identity and Access Management

変えたたらサブドメインがアカウント番号からエイリアス名になる(アカウント番号でもアクセスできるまま)
https://my-alias.signin.aws.amazon.com/console

★アカウント設定(パスワードポリシー)

ISMS的なアレ(または顧客要望)にのっとって適宜。
Account settingsから実施。

Minimum password length: x(x文字を要する)
Require at least one non-alphanumeric character(記号を要する)
Allow users to change their own password (自分で更新する)
Enable password expiration
Password expiration period (in days): xx(xx(日)で期限がきれる)

★ルートアカウントでアクセスしない

スイッチロールの設定時にrootアカウントにアクセスできるように設定しなければ
メニューにスイッチロールでないので物理的にルートアカウントにアクセスは不可能。
クラスメソッドのリンクが詳しい(rootでも設定するといけるけどやらないほうがいい))
単に運用上パスワード変えて限定共有する、クレデンシャル無効化する、MFAデバイス用意等。
あとCloudTrail的に個人IAMで操作したほうが証跡が追いやすい。

★クレデンシャルの書き方

たぶん以下のようになる。

[account2]
role_arn = arn:aws:iam::5678xxxxxxxx:role/mygroup-admin
source_profile = account1
region=us-xxxx-x

★スイッチロールのポリシーアタッチされてるグループにいるユーザをcliでだす

$ aws iam get-group --group-name mygroup --profile account1|jq -c -r '.Users[].UserName'

以上

続きを読む