環境:
Xcode7.0.1
Beta 版と GM をインストールしたら重複して表示されるようになってしまった。
iOSシミュレータを削除するには Xcode > Window > Devices
から削除できる。
削除したいデバイスがたくさんあって個別に面倒な場合は
~/Library/Developer/CoreSimulator
のCoreSimulatorディレクトリごと削除して再起動でもよいらしい(試してない)。
環境:
Xcode7.1
例えば iOSシミュレータにインストールした、あるアプリのDocumentsディレクトリは以下のようになる。
~/Library/Developer/CoreSimulator/Devices/CC8FA744-B3C2-4689-839F-33B504F6168A/data/Containers/Data/Application/3E4EBE82-0BC7-405E-B143-5F40B03EBBA8/Documents
デバイスID、アプリIDの部分がランダムな文字列になっていて、パスからは何のアプリなのか判別できない。
このパスはアプリで以下コードを実行することで確認することができる。
// swift3 print(NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last!)
最後に使用したシミュレータのデバイスで、最後にインストールしたアプリのDocumentsディレクトリは以下のコマンド一発でFinderを開くことができる。
$ cd ~/Library/Developer/CoreSimulator/Devices/ && cd `ls -t | head -n 1`/data/Containers/Data/Application && cd `ls -t | head -n 1`/Documents && open
~/Library/Developer/CoreSimulator/Devices
各シミュレータのディレクトリは以下のようにランダムな文字列の名前となっていて、これを見ただけでは、どのデバイスと紐付いているのかわからない。
このディレクトリがどのデバイスと紐付いているかはXcode > Window > Devices
の Identifier で確認できる。
または以下コマンドからでも確認できる。
$ instruments -s devices Known Devices: mbp [502448C4-0A7D-5D96-8EAA-3FE2C32D9C5B] Apple TV 1080p (9.0) [33BE56A7-BB99-4A45-88E2-3C9C482EDB45] Apple Watch - 38mm (2.0) [1F3FB32B-2C35-4951-B1D6-C797CEDC2A65] Apple Watch - 42mm (2.0) [D0E0AA11-7276-4C76-BBFA-2B2571EC13E3] iPad 2 (9.1) [003458F4-881A-44C9-9E73-815F50790117] iPad Air (9.1) [CFA403BF-2738-4FF9-A32B-0520D0D8E167] iPad Air 2 (9.1) [C402142B-130E-4456-B579-E2C032BAFB8C] iPad Pro (9.1) [01D9E203-1D49-4342-B642-B2FC82C54CB4] iPad Retina (9.1) [05637EC1-2820-4AB2-BE24-5D8BF7B76DE3] iPhone 4s (9.1) [8FB284BC-7022-4E3F-9D59-41299CFBB3AC] iPhone 5 (9.1) [05F41E8B-0C60-4917-B706-DAB2A5C683B8] iPhone 5s (9.1) [F46048FE-9455-4814-93DF-F5CFCFEE06EA] iPhone 6 (9.1) [951E310E-D37C-4EF1-83EA-68FFA8233CC0] iPhone 6 Plus (9.1) [7839119B-EE08-4E39-94C4-9991EC6C804D] iPhone 6s (9.1) [F5B6F4BB-EEC0-404E-80EA-B200433ACC47] iPhone 6s (9.1) + Apple Watch - 38mm (2.0) [C67B741D-279E-4DF0-840A-8EE151B75756] iPhone 6s Plus (9.1) [63933384-7F47-444F-82EE-A3BA10D6A769] iPhone 6s Plus (9.1) + Apple Watch - 42mm (2.0) [D275AF10-7558-4BED-9B9D-75C65CD7D983]
これで紐付けはわかるが Finder でそのディレクトリまで掘っていくのが面倒くさい。
そこでディレクトリを一発で開くことができるツールを使ってみた。
シミュレータ一覧と、シミュレータ内のアプリフォルダが表示されるので選択すれば Finder でディレクトリを開くことができる。
バイナリのダウンロードはこちら
https://github.com/tue-savvy/SimulatorManager/releases
こちらはシミュレータにインストールされたアプリ一覧が表示される。
だが、たまに上手く動かないときがある・・・
ちなみに各iOSシミュレータのログディレクトリは以下にある。
~/Library/Logs/CoreSimulator
環境: Swift2.0
アプリ内にデータを保存する場合、どこに保存するのかを調べた。
だいたい以下のディレクトリ(またはこれらの中に作成したサブディレクトリ)のどれかに保存することになるようだ。
Documents/
Library/
Library/Application Support/
Library/Caches/
tmp/
保存するデータの内容によって使い分ける必要がある。
Apple のガイド
https://developer.apple.com/jp/documentation/FileSystemProgrammingGuide.pdf
から引用する。
Documents/
ユーザが生成したデータを保存するために使います。ファイル共有の機能により、ユーザはこのディレクトリ以下にアクセスできます。したがって、ユーザに見せても構わないファイルのみ置いてください。 このディレクトリの内容はiTunesによってバックアップされます。
–
ユーザデータはDocuments/以下に置いてください。これは一般に、ユーザに積極的に見せるファイルです。ユーザが自由に作成、インポート、削除、編集する対象です。たとえば描画アプリケーションの場合、ユーザが作成するグラフィックファイルがこれに当たります。テキストエディタであればテキストファイルが該当します。動画/音声アプリケーションの場合、ユーザが後で試聴するためにダウンロードしたファイルもこれに当たります。
Documents/およびApplication Support/以下のファイルは、自動的にバックアップの対象にな ります。NSURLIsExcludedFromBackupKeyキーを指定して -[NSURL setResourceValue:forKey:error:]を実行することにより、バックアップ対象から除外できます。いつでも再生成またはダウンロードできるファイルは、この対象から外してください。大容量のメディアファイルの場合、これは特に重要です。ダウンロードした動画や音声は、バックアップ対象に含めないようにしてください。
Library/
Library/Application Support/
Library/Caches/
これは、ユーザのデータファイル以外のファイル用の最上位ディレクトリです。通常、標準的なサブディレクトリを用意し、いずれか適当な場所に保存します。iOSアプリケーションは通常、Application Support およびCachesというサブディレクトリを使いますが、独自のサブディレクトリを作成しても構いません。 ユーザに見せたくないファイルはLibraryサブディレクトリ以下に置いてください。ユーザデータのファイル保存用に使ってはなりません。 Libraryディレクトリの内容は、Cachesサブディレクトリ以下を除き、 iTunesによるバックアップの対象になります。
–
データキャッシュファイルはLibrary/Caches/ディレクトリ以下に置きます。キャッシュデータは、一時データよりは長期間にわたって残しておきたいけれども、補助ファイルほどではない場合に有用です。一般にキャッシュデータは、なくてもアプリケーションの動作に影響しませんが、性能改善の効果が期待できます。例として、データベースのキャッシュファイルや、一時的でいつでもダウンロード可能なデータなどがあります。なお、ディスク空間を確保するため、システムがCaches/ディレクトリを消去することがあるので、必要ならばいつでも生成し直し、あるいはダウンロードできるようになっていなければなりません。
tmp/
このディレクトリは、アプリケーションを次に起動するまで保持する必要のない一時ファイルを書き込むために使用します。不要になったファイルは削除しなければなりません。もっとも、アプリケーションが動作していないときに、システムがこのディレクトリ以下をすべて消去することがあります。 iTunesはこのディレクトリの内容をバックアップしません。
–
一時データはtmp/ディレクトリに置いてください。一時データとは、長期間にわたって保存しておく必要がないデータのことです。使い終わったら削除して、デバイス上の空間を消費し続けないようにしなければなりません。システムは、アプリケーションが動作していない間、定期的にここにあるファイルを消去します。したがって、一度停止した後、ファイルが残っていることを前提として処理してはなりません。
–
まとめると以下のようになる。
Documents/ ・ユーザが作成したデータ(テキスト、写真)、再作成が不可能なデータなど重要なデータを保存するディレクトリ。 ・ユーザに見せたくないファイル(設定ファイルとか)はここに置かない。 ・iTunes、iCloud バックアップ対象。 Library/ ・ユーザのデータファイル以外を保存するディレクトリ。自分でサブディレクトリを用意して保存する。 ・ユーザに見せたくないファイルはここに置く。 ・iTunes、iCloud バックアップ対象(Caches ディレクトリを除く)。 Library/Caches/ ・一時的なデータを保存するディレクトリ。システムが自動削除する可能性がある。 ・後から再度ダウンロードして復旧可能なデータを置くこと。 ・iTunes、iCloud バックアップ対象外。 Library/Preferences/ ・アプリの設定を保存するディレクトリ。NSUserDefaults のデータはここに保存される。 tmp/ ・一時的なデータを保存するディレクトリ。アプリが動作してないときにシステムが自動削除する可能性がある。 ・iTunes、iCloud バックアップ対象外。 ・使い終わったらアプリ側で削除して容量削減に務める。
tmp/
とLibrary/Caches/
の使い分けについてどちらのディレクトリも一時ファイルの保存先として使うが、システムによるファイル削除のタイミングが違う。
ディレクトリ | 非アクティブ中のシステムによる削除 | アクティブ中のシステムによる削除 | ガイド記載の使用例 |
---|---|---|---|
tmp/ | ◯ | × | 次のアプリの起動で保持する必要のないファイル |
Caches/ | ◯ | ◯ | ダウンロードコンテンツ等 |
NSSearchPathForDirectoriesInDomains
関数を使う。
またはNSHomeDirectory()
でホームディレクトリを取得してそれに連結してもよい。
Documents
ディレクトリ
let path: String = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] print(path) // /Users/xyk/Library/Developer/CoreSimulator/Devices/B9D56604-82C8-4752-A4D8-51292D8F625A/data/Containers/Data/Application/73FBC4AB-EA27-4ECF-A1FA-9389A25DD2CD/Documents // または let path: String = NSHomeDirectory() + "/Documents" // または let path: NSURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
Library
ディレクトリ
let path: String = NSSearchPathForDirectoriesInDomains(.LibraryDirectory, .UserDomainMask, true)[0] print(path) // /Users/xyk/Library/Developer/CoreSimulator/Devices/B9D56604-82C8-4752-A4D8-51292D8F625A/data/Containers/Data/Application/7A7E5AA5-9ED9-4CE3-8559-90A946227DF8/Library // または let path: String = NSHomeDirectory() + "/Library" // または let path: NSURL = NSFileManager.defaultManager().URLsForDirectory(.LibraryDirectory, inDomains: .UserDomainMask)[0]
Library/Caches
ディレクトリ
let path: String = NSSearchPathForDirectoriesInDomains(.CachesDirectory, .UserDomainMask, true)[0] print(path) // /Users/xyk/Library/Developer/CoreSimulator/Devices/B9D56604-82C8-4752-A4D8-51292D8F625A/data/Containers/Data/Application/3959DFC8-25A6-47C4-B246-FE8304B17864/Library/Caches // または let path: String = NSHomeDirectory() + "/Library/Caches" // または let path: NSURL = NSFileManager.defaultManager().URLsForDirectory(.CachesDirectory, inDomains: .UserDomainMask)[0]
Library/Application Support
ディレクトリ
let path: String = NSSearchPathForDirectoriesInDomains(.ApplicationSupportDirectory, .UserDomainMask, true)[0] print(path) // /Users/xyk/Library/Developer/CoreSimulator/Devices/B9D56604-82C8-4752-A4D8-51292D8F625A/data/Containers/Data/Application/9E25C963-2F4B-4985-BA9B-B9DADF52E9EC/Library/Application Support // または let path: String = NSHomeDirectory() + "/Library/Application Support" // または let path: NSURL = NSFileManager.defaultManager().URLsForDirectory(.ApplicationSupportDirectory, inDomains: .UserDomainMask)[0]
tmp/
ディレクトリ
let path: String = NSTemporaryDirectory() print(path) // /Users/xyk/Library/Developer/CoreSimulator/Devices/B9D56604-82C8-4752-A4D8-51292D8F625A/data/Containers/Data/Application/6572ECC7-D57A-40C0-8E0E-E52AC8F64012/tmp/ // NSHomeDirectory()と違ってパス末尾にスラッシュが含まれる。~/tmp/
–
NSFileManager
クラスを使う。
よく使いそうな操作メソッドの定義。
// NSFileManager // 存在チェック public func fileExistsAtPath(path: String) -> Bool // ディレクトリ作成 public func createDirectoryAtPath(path: String, withIntermediateDirectories createIntermediates: Bool, attributes: [String : AnyObject]?) throws // ファイル作成 public func createFileAtPath(path: String, contents data: NSData?, attributes attr: [String : AnyObject]?) -> Bool // 削除 public func removeItemAtPath(path: String) throws
ファイルパス(StringまたはNSURL)を指定して NSData として書き込む。
// NSData public func writeToFile(path: String, atomically useAuxiliaryFile: Bool) -> Bool public func writeToFile(path: String, options writeOptionsMask: NSDataWritingOptions) throws public func writeToURL(url: NSURL, atomically: Bool) -> Bool public func writeToURL(url: NSURL, options writeOptionsMask: NSDataWritingOptions) throws
ファイルパス(StringまたはNSURL)から NSData として読み込む。
// NSData public init?(contentsOfFile path: String) public init(contentsOfFile path: String, options readOptionsMask: NSDataReadingOptions) throws public init?(contentsOfURL url: NSURL) public init(contentsOfURL url: NSURL, options readOptionsMask: NSDataReadingOptions) throws
UIImage
をUIImagePNGRepresentation
でNSDataに変換してから書き込み。
UIImagePNGRepresentation(image)?.writeToFile(imagePath, atomically: true) UIImagePNGRepresentation(image)?.writeToURL(imageURL, atomically: true)
ファイルパスから UIImage として読み込む。
// UIImage public init?(contentsOfFile path: String)
文字列のファイルパスをNSURLに変換して扱う場合、fileURLWithPath:
を使うこと。
let url = NSURL(fileURLWithPath: NSTemporaryDirectory() + "dummy.txt") // 以下は正しくない // let url = NSURL(string: NSTemporaryDirectory() + "dummy.txt")
環境: Xcode 7.0.1
Swift2.0
Carthage(カーセージって読むみたい)というライブラリ管理ツールを使ってみた。
CocoaPods と比べると
・CocoaPods では Static Library のlibPods.a
を静的リンクしていたが 、Carthage はxcodebuild
コマンドを使ってビルドした Dynamic Framework (iOS8以降)を実行時に動的にリンクする
・CocoaPods のように.xcworkspace
のようなスキームは生成されない、ライブラリは自分でプロジェクトに追加しなければならないが.xcodeproj
のまま扱える
・ビルドが早い
などの違いがあるらしい。
homebrew でインストールできる。
$ brew update $ brew install carthage
確認
$ carthage version 0.8.0
Cartfile
というファイルを作成して、使用したいライブラリを記述していく。
GitHub レポジトリと version を指定する。
$ cat Cartfile github "Alamofire/Alamofire" >= 3.0.0
依存関係があればそれも含めてダウンロードし、そしてビルド& framework を行う。
$ carthage update *** Fetching Alamofire *** Checking out Alamofire at "3.0.0" *** xcodebuild output can be found in /var/folders/ml/2hwc26zx5b30jf3k4tp_kzj00000gn/T/carthage-xcodebuild.h6xNwA.log *** Building scheme "Alamofire watchOS" in Alamofire.xcworkspace *** Building scheme "Alamofire OSX" in Alamofire.xcworkspace *** Building scheme "Alamofire iOS" in Alamofire.xcworkspace
watchOS
、OSX
、iOS
各プラットホーム分作成された。
iOS のみでよければ--platform
で指定すればよい。
$ carthage update --platform iOS
コマンド実行後は以下のようなディレクトリ構成となった。
作成された framework を Xcode のTarget > General > Linked Frameworks and Binaries
に追加する。
+ ボタンから追加するか Finder からドラッグ&ドロップでも追加できる。
import Alamofire
早速 import して実行してみたところ、ビルドは成功するがシミュレータ起動直後に以下のエラーが発生した。
dyld: Library not loaded: @rpath/Alamofire.framework/Alamofire Referenced from: /Users/xyk/Library/Developer/CoreSimulator/Devices/B9D56604-82C8-4752-A4D8-51292D8F625A/data/Containers/Bundle/Application/304560B9-432C-4A5D-BCEF-B2328D84DED1/AlamofireSample.app/AlamofireSample Reason: image not found
ググってみるとTarget > General > Embedded Binaries
にも追加するらしい。
これでエラーは解消された。
むしろはじめからEmbedded Binaries
の方に追加するほうがよいかも。Linked Frameworks and Binaries
にも同時に追加されるし。
ライブラリを使う分にはここまでの手順で OK だが、アプリを AppStore にサブミットするためには、さらに以下のワークアラウンドを行う必要があるらしい。
Build Phases
の + ボタンをクリックしNew Run Script Phase
を選択し
/usr/local/bin/carthage copy-frameworks
を入力。またInput Files
に
$(SRCROOT)/Carthage/Build/iOS/Alamofire.framework
を入力。
環境: Xcode7 GM
iOS9 対応で行った作業メモ。
HTTPS 接続にする必要あり。今回はとりあえずHTTPを許可するようにInfo.plist
に以下の手順で追加する。
NSAppTransportSecurity
を Dictionary で追加。NSAllowsArbitraryLoads
をBooleanで追加し、YESを設定。openURL
、canOpenURL
のようなメソッドでカスタムURLスキームを呼び出す場合、Info.plist
に登録しなければ使えないようになった。
admob SDK を使ってるのだが、アプリ起動時に以下のような許可されてないスキームのエラーが出るようになった。
-canOpenURL: failed for URL: "itms-books://" - error: "This app is not allowed to query for scheme itms-books" -canOpenURL: failed for URL: "kindle://home" - error: "This app is not allowed to query for scheme kindle"
Info.plist
に以下の手順で追加する。
LSApplicationQueriesSchemes
を Array で追加。item 0
が追加されるので String でitms-books
を入力。item 1
を追加し String でkindle
を入力。これで再度起動してみると、スキームが許可されてないエラーから、スキーム起動失敗のエラーに変わった。
これはスキームで起動させるアプリがインストールされていないためなので問題なし。
-canOpenURL: failed for URL: "itms-books://" - error: "(null)" -canOpenURL: failed for URL: "kindle://home" - error: "(null)"
ここまでの作業でInfo.plist
は以下のようになった。
実機でアプリを起動しようとしたら admob SDK で以下のエラーが出た。
ld: '/.../Google-Mobile-Ads-SDK/GoogleMobileAdsSdkiOS-7.4.1/GoogleMobileAds.framework/GoogleMobileAds(GADGestureIdUtil.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture armv7 clang: error: linker command failed with exit code 1 (use -v to see invocation)
とりあえず Bitcode をオフにすることでビルドが通るようになった。
Target -> Build Settings -> Build Options -> Enable Bitcode を NO に変更。
選択行(複数行可)を上に移動
選択行(複数行可)を上に移動
超使う。ソースコード上の定義にジャンプしたり、戻ったり。
トラックパッドの左右スワイプでも同様なことができるがデカいファイル上で行うと固まったりするので、上のコマンドでやるほうがよい。
ビルド
ビルド&シミュレータ起動。
クリーン
ビルドのキャンセル。
プロジェクトナビゲーター表示。左ペインのソースコードツリーのこと。
Command(⌘) + 2,3,4,5… で左ペインをメニューをそれぞれ表示する。
現在、開いているファイルのプロジェクトナビゲーター上の位置に移動して表示。
現在開いているファイルに対して検索を行う。
全ファイルに対して検索を行う。
さらに検索窓の上の 「Find」部分を「Replace」に入れ替えることで置換用窓が現れる。
これを使えば全ファイルを対象に一括置換が可能。置換前にプレビューで確認できるので安心して置換できる。
ファイル名でインクリメンタル絞り込みを行いつつ検索する。
現在開いているウインドウを分割して2つのファイルを表示する。(画面分割形式 は Assistant Editor の設定で指定できる)
ウィンドウを閉じるにはCmd + Enter
。表示と違うので注意。
Utilities の表示・非表示。画面右ペインのこと。
Command(⌘) + Option(⌥) + 2,3,4,5… で右ペインをメニューをそれぞれ表示する。
画面左ペインの表示・非表示。
Scheme 編集画面を開く。
Target を切り替える。
ブレイクポイントを枠外にドラッグで移動させて離すと削除される。
これ知らずに右クリックから Delete Breakpoint で削除してて面倒くさいと思ってた・・
環境:
Xcode 6.1
iOS 8.1 Simulator
結論から言うと Xcode 6.1 と iOS 8.1 Simulator の環境で、 iOS Simulator の言語設定に対応したローカライズファイルLocalizable.strings
を用意しても反映されないバグがあるらしい。
ワークアラウンドとして iOS Simulator 側の言語設定はなく、Xcode の Edit Scheme -> Run -> Option -> Application Language で言語設定すればいけた。
参考:
xcode - iOS 8.1 Simulator Localization broken (NSLocalizedString) - Stack Overflow
http://stackoverflow.com/questions/26504304/ios-8-1-simulator-localization-broken-nslocalizedstring
iOS8のシミュレーターでLocalizationのテストをする
http://www.rizastar.com/blog_xcode/ios8-simulator-localization-test/
ローカライズについてはこの資料が分かりやすかった。
Xcode のローカライズ処方箋 #yhios
http://www.slideshare.net/tomohirokumagai54/xcode-yhios
環境:
Mac
aws-cli 1.7.0
eb-cli 3.0.10
Ruby 2.1.5
Rails 4.2.0
VPC からの環境構築は今回はじめてやるので理解が間違ってるところがあるかもしれない。
IAM でユーザ作成し、「Administrator Access」権限を付与、AWS CLI のaws configure
コマンドでregion
、aws_access_key_id
、aws_secret_access_key
を設定しておくこと。
VPC を作成する。
$ aws ec2 create-vpc --cidr-block 10.0.0.0/16 { "Vpc": { "InstanceTenancy": "default", "State": "pending", "VpcId": "vpc-d42ae5b1", "CidrBlock": "10.0.0.0/16", "DhcpOptionsId": "dopt-9ed4cafc" } }
VPC に Name タグを追加する。
$ aws ec2 create-tags --resources vpc-d42ae5b1 --tags Key=Name,Value="vpc blog"
VPC の作成と一緒に
も作成される。これらの関係性は以下の図のようになっている。
VPC のセキュリティ - Amazon Virtual Private Cloud
http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/VPC_Security.html
Route Table(main) を確認する。
$ aws ec2 describe-route-tables --filters "Name=vpc-id,Values=vpc-d42ae5b1" ... "RouteTableId": "rtb-f072a695", "VpcId": "vpc-d42ae5b1", ...
Route Table(main) に Name タグを追加する。
$ aws ec2 create-tags --resources rtb-f072a695 --tags Key=Name,Value="rtb blog main"
ACL を確認する。
$ aws ec2 describe-network-acls --filters "Name=vpc-id,Values=vpc-d42ae5b1" ... "NetworkAclId": "acl-2ace1b4f", "VpcId": "vpc-d42ae5b1", ...
ACL に Name タグを追加する。
$ aws ec2 create-tags --resources acl-2ace1b4f --tags Key=Name,Value="acl blog"
VPC セキュリティグループ(default)を確認する。
$ aws ec2 describe-security-groups --filters "Name=vpc-id,Values=vpc-d42ae5b1" ... "GroupName": "default", "VpcId": "vpc-d42ae5b1", "OwnerId": "123456789012", "GroupId": "sg-bdc574d8" ...
VPC セキュリティグループに Name タグを追加する。
$ aws ec2 create-tags --resources sg-bdc574d8 --tags Key=Name,Value="sg blog default"
VPC 内の RDS に外部から接続できるようにするため。
参考: VPC の DNS サポートを更新する
# 有効にする $ aws ec2 modify-vpc-attribute --vpc-id vpc-d42ae5b1 --enable-dns-hostnames # 確認 $ aws ec2 describe-vpc-attribute --vpc-id vpc-d42ae5b1 --attribute enableDnsHostnames { "VpcId": "vpc-d42ae5b1", "EnableDnsHostnames": { "Value": true } }
3つのサブネットを作成する。
3つともパブリックサブネットとする。
2つ目、3つ目は DB 用として使うので availability-zone を分ける。
自分のアカウントではap-northeast-1a
、ap-northeast-1c
の2つが使用可能となっている。
$ aws ec2 create-subnet --vpc-id vpc-d42ae5b1 --cidr-block 10.0.0.0/24 --availability-zone ap-northeast-1a { "Subnet": { "VpcId": "vpc-d42ae5b1", "CidrBlock": "10.0.0.0/24", "State": "pending", "AvailabilityZone": "ap-northeast-1a", "SubnetId": "subnet-f23be885", "AvailableIpAddressCount": 251 } } $ aws ec2 create-subnet --vpc-id vpc-d42ae5b1 --cidr-block 10.0.1.0/24 --availability-zone ap-northeast-1a { "Subnet": { "VpcId": "vpc-d42ae5b1", "CidrBlock": "10.0.1.0/24", "State": "pending", "AvailabilityZone": "ap-northeast-1a", "SubnetId": "subnet-ff3be888", "AvailableIpAddressCount": 251 } } $ aws ec2 create-subnet --vpc-id vpc-d42ae5b1 --cidr-block 10.0.2.0/24 --availability-zone ap-northeast-1c { "Subnet": { "VpcId": "vpc-d42ae5b1", "CidrBlock": "10.0.2.0/24", "State": "pending", "AvailabilityZone": "ap-northeast-1c", "SubnetId": "subnet-d721d58e", "AvailableIpAddressCount": 251 } }
サブネットに Name タグを追加する。
$ aws ec2 create-tags --resources subnet-f23be885 --tags Key=Name,Value="subnet public blog web" $ aws ec2 create-tags --resources subnet-ff3be888 --tags Key=Name,Value="subnet public blog db1" $ aws ec2 create-tags --resources subnet-d721d58e --tags Key=Name,Value="subnet public blog db2"
インターネットゲートウェイ(IGW)を作成する。
$ aws ec2 create-internet-gateway { "InternetGateway": { "Tags": [], "InternetGatewayId": "igw-85d63ce0", "Attachments": [] } }
IGW に Name タグを追加する。
$ aws ec2 create-tags --resources igw-85d63ce0 --tags Key=Name,Value="igw blog"
VPC に IGW をアタッチする。
$ aws ec2 attach-internet-gateway --internet-gateway-id igw-85d63ce0 --vpc-id vpc-d42ae5b1
確認する。
$ aws ec2 describe-internet-gateways --internet-gateway-id igw-85d63ce0 { "InternetGateways": [ { "Tags": [ { "Value": "igw blog", "Key": "Name" } ], "InternetGatewayId": "igw-85d63ce0", "Attachments": [ { "State": "available", "VpcId": "vpc-d42ae5b1" } ] } ] }
デフォルトでサブネットが紐付くメインルートテーブルとは別に新たにカスタムルートテーブルを作成する。
こちらをパブリックサブネット用のルートテーブルとして使用する。
$ aws ec2 create-route-table --vpc-id vpc-d42ae5b1 { "RouteTable": { "Associations": [], "RouteTableId": "rtb-2073a745", "VpcId": "vpc-d42ae5b1", "PropagatingVgws": [], "Tags": [], "Routes": [ { "GatewayId": "local", "DestinationCidrBlock": "10.0.0.0/16", "State": "active", "Origin": "CreateRouteTable" } ] } }
ルートテーブルに Name タグを追加する。
$ aws ec2 create-tags --resources rtb-2073a745 --tags Key=Name,Value="rtb blog public"
$ aws ec2 create-route --route-table-id rtb-2073a745 --destination-cidr-block 0.0.0.0/0 --gateway-id igw-85d63ce0
作成した3つのサブネットに設定されているメインルートテーブルから、新たに作成したパブリックサブネット用ルートテーブルに切り替える。
$ aws ec2 associate-route-table --route-table-id rtb-2073a745 --subnet-id subnet-f23be885 { "AssociationId": "rtbassoc-70924015" } $ aws ec2 associate-route-table --route-table-id rtb-2073a745 --subnet-id subnet-ff3be888 { "AssociationId": "rtbassoc-73924016" } $ aws ec2 associate-route-table --route-table-id rtb-2073a745 --subnet-id subnet-d721d58e { "AssociationId": "rtbassoc-7d924018" }
VPC 環境構築はここまで。
ここからは RDS の環境構築を行う。
以前の投稿も参考に。
DB パラメーターグループmydbparamgroup
を作成する。
$ aws rds create-db-parameter-group \ --db-parameter-group-name mydbparamgroup \ --db-parameter-group-family mysql5.6 \ --description "for myinstance" { "DBParameterGroup": { "DBParameterGroupName": "mydbparamgroup", "DBParameterGroupFamily": "mysql5.6", "Description": "for myinstance" } }
DB パラメーターグループのキャラクタセット関連のパラメータを更新する。
$ aws rds modify-db-parameter-group --db-parameter-group-name mydbparamgroup --parameters \ ParameterName=character_set_client,ParameterValue=utf8mb4,ApplyMethod=immediate \ ParameterName=character_set_connection,ParameterValue=utf8mb4,ApplyMethod=immediate \ ParameterName=character_set_database,ParameterValue=utf8mb4,ApplyMethod=immediate \ ParameterName=character_set_results,ParameterValue=utf8mb4,ApplyMethod=immediate \ ParameterName=character_set_server,ParameterValue=utf8mb4,ApplyMethod=immediate \ ParameterName=collation_connection,ParameterValue=utf8mb4_general_ci,ApplyMethod=immediate \ ParameterName=collation_server,ParameterValue=utf8mb4_general_ci,ApplyMethod=immediate \ ParameterName=skip-character-set-client-handshake,ParameterValue=0,ApplyMethod=pending-reboot { "DBParameterGroupName": "mydbparamgroup" }
続いて、init_connect パラメータを更新する。
$ aws rds modify-db-parameter-group --generate-cli-skeleton > init_connect.json
出力されたファイルを以下のように編集する。
{ "DBParameterGroupName": "mydbparamgroup", "Parameters": [ { "ParameterName": "init_connect", "ParameterValue": "SET SESSION time_zone = CASE WHEN POSITION('rds' IN CURRENT_USER()) = 1 THEN 'UTC' ELSE 'Asia/Tokyo' END;", "Description": "", "Source": "", "ApplyType": "", "DataType": "", "AllowedValues": "", "IsModifiable": true, "MinimumEngineVersion": "", "ApplyMethod": "immediate" } ] }
そして DB パラメータグループを更新する。--cli-input-json
オプションでファイルを指定。
$ aws rds modify-db-parameter-group --cli-input-json file://init_connect.json # 終わったら不要なので削除 $ rm init_connect.json
DB サブネットグループmydbsubnetgroup
を作成する。
DB 用に用意した2つのサブネットsubnet public blog db1
、subnet public blog db2
を設定する。
$ aws rds create-db-subnet-group \ --db-subnet-group-name mydbsubnetgroup \ --db-subnet-group-description "DB SubnetGroup for myinstance" \ --subnet-ids subnet-ff3be888 subnet-d721d58e { "DBSubnetGroup": { "Subnets": [ { "SubnetStatus": "Active", "SubnetIdentifier": "subnet-d721d58e", "SubnetAvailabilityZone": { "Name": "ap-northeast-1c" } }, { "SubnetStatus": "Active", "SubnetIdentifier": "subnet-ff3be888", "SubnetAvailabilityZone": { "Name": "ap-northeast-1a" } } ], "DBSubnetGroupName": "mydbsubnetgroup", "VpcId": "vpc-d42ae5b1", "DBSubnetGroupDescription": "DB SubnetGroup for myinstance", "SubnetGroupStatus": "Complete" } }
DB用 VPC セキュリティグループmyrds
を作成する。
ちなみに DB セキュリティグループと呼ばれるものがあるが、これは VPC 内ではない RDS に適用するもの。
昔の EC2-Classic Platform のアカウントのみ使える。
$ aws ec2 create-security-group \ --group-name myrds \ --description "RDS security group" \ --vpc-id vpc-d42ae5b1 { "GroupId": "sg-14c77671" }
DB用 VPC セキュリティグループに Name タグを追加する。
$ aws ec2 create-tags --resources sg-14c77671 --tags Key=Name,Value="sg blog rds"
RDS MySQL に外部から接続するために Inbound のルールを追加する。
$ aws ec2 authorize-security-group-ingress --group-id sg-14c77671 --protocol tcp --port 3306 --cidr 0.0.0.0/0
myinstance
とする。myrds
の2つを追加する。$ aws rds create-db-instance \ --db-instance-identifier myinstance \ --allocated-storage 5 \ --db-instance-class db.t2.micro \ --engine MySQL \ --engine-version 5.6.22 \ --master-username bloguser \ --master-user-password bloguser1234567890 \ --db-name blogdb \ --db-parameter-group-name mydbparamgroup \ --db-subnet-group-name mydbsubnetgroup \ --vpc-security-group-ids sg-bdc574d8 sg-14c77671 \ --storage-type standard \ --availability-zone ap-northeast-1a \ --no-multi-az \ --region ap-northeast-1 \ --publicly-accessible \ --no-auto-minor-version-upgrade
コマンドを実行すると RDS インスタンスの作成がはじまる。しばらく時間がかかるので待つ。
インスタンスの作成が完了したら、以下コマンドでエンドポイントを確認する。
$ aws rds describe-db-instances --db-instance-identifier myinstance | jq '.DBInstances[].Endpoint' { "Port": 3306, "Address": "myinstance.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com" }
PublicIp、PublicDnsName は以下コマンドで確認できる。
GUI 管理コンソールでは、EC2 Dashboard -> Network interfaces から確認できる。
$ aws ec2 describe-network-interfaces --filters "Name=description,Values=RDSNetworkInterface" ... "Description": "RDSNetworkInterface", "Association": { "PublicIp": "54.92.100.249", "PublicDnsName": "ec2-54-92-100-249.ap-northeast-1.compute.amazonaws.com", "IpOwnerId": "amazon-rds" }, ...
上で調べた Endpoint または PublicIp、PublicDnsName のいずれかをホストに指定して MySQL に接続できるか確認する。
$ mysql -h myinstance.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -P 3306 -u bloguser -p -D blogdb $ mysql -h ec2-54-65-198-252.ap-northeast-1.compute.amazonaws.com -P 3306 -u bloguser -p -D blogdb $ mysql -h 54.65.198.252 -P 3306 -u bloguser -p -D blogdb
RDS 環境構築はここまで。
サンプルとしてブログアプリケーションを作成する。
DB には MySQL を使う。ローカル環境に MySQL インストール済み。
$ bundle exec rails new blog -d mysql --skip-bundle $ cd blog # アプリケーションサーバとして Puma を選択するので Gemfile に追加 $ echo "gem 'puma'" >> Gemfile # gem インストール $ bundle install --path vendor/bundle
scaffold コマンドでアプリの雛形を作成する。
$ bin/rails generate scaffold article title:string content:string
config/routes.rb
Rails.application.routes.draw do resources :articles root 'articles#index' end
config/application.rb
config.time_zone = 'Tokyo' config.active_record.default_timezone = :local
ローカル環境の MySQL に対してマイグレーションを実行する。
$ bin/rake db:create && bin/rake db:migrate
ローカル環境でアプリを起動して MySQL にデータ登録、画面にデータ表示できるか確認する。
$ bin/rails s
本番用の DB 設定を修正する。
config/database.yml
production: adapter: mysql2 encoding: utf8mb4 database: <%= ENV['RDS_DB_NAME'] %> username: <%= ENV['RDS_USERNAME'] %> password: <%= ENV['RDS_PASSWORD'] %> host: <%= ENV['RDS_HOSTNAME'] %> port: <%= ENV['RDS_PORT'] %>
Git リポジトリを作成してソースコード一式を add & commit する。
$ git init && git add -A && git commit -m "first commit"
Rails アプリケーション作成まここまで。
ここからは Elastic Beanstalk の環境構築を行う。
以前の投稿も参考に。
先ほど作成した Rails プロジェクトのディレクトリ内で以下手順を行う。
eb init
コマンドでアプリケーション枠を作成する。SSH キーペアは作成してアップロード済み。
$ eb init blog \ --platform "Ruby 2.1 (Puma)" \ --keyname aws-eb
.gitignore が更新されるので add & commit する。
$ git commit -am "updated .gitignore"
EC2 インスタンスのタイムゾーンを日本に変更するため、カスタマイズ設定ファイルを準備する。
.ebextensions
ディレクトリを作成する。
$ mkdir -p .ebextensions/scripts
Timezone を設定するシェルスクリプトを作成する。
.ebextensions/scripts/timezone.sh
#!/bin/bash cp -f /usr/share/zoneinfo/Japan /etc/localtime sed -i -e 's/ZONE=.*$/ZONE="Asia\/Tokyo"/' /etc/sysconfig/clock sed -i -e 's/UTC=.*$/UTC=false/' /etc/sysconfig/clock echo 'ARC=false' >> /etc/sysconfig/clock
.ebextensions ディレクトリ直下に config ファイルを作成する。
この config ファイルはデプロイする度に実行される。
タイムゾーン設定は初回の EC2 インスタンス作成時のみ実行すればよいので、test コマンドを使って2回目以降は実行されないようにした。
.ebextensions/01_timezone.config
container_commands: 01-change_timezone: test: '[ ! -f /root/.not-a-new-instance.txt ]' command: bash .ebextensions/scripts/timezone.sh 02-create_check_file: test: '[ ! -f /root/.not-a-new-instance.txt ]' command: touch /root/.not-a-new-instance.txt
ここまでできたら Git に add & commit する。
$ git add -A && git commit -m "add extensions"
eb create
コマンドでインスタンスの作成を行う。オプションについてはこちら。
blog-production
とする。vpc blog
)を指定する。subnet public blog web
)を指定する。elbpublic
とpublicip
を設定する。sg blog default
)を指定する。com-example-blog-production
を設定する。
sample オプションをつける理由:
eb create
コマンドを実行すると、環境構築 -> Rails アプリデプロイ -> DB マイグレーションまで行われるが、config/database.yml の DB 関連のパラメータは環境変数から取得するようなっており、まだ環境変数は未設定なのでパラメータが取得できず、DBマイグレーションに失敗してしまう。
しかし、eb setenv
による環境変数の設定はeb create
実行後でなければできない。
ワークアラウンドとして、1発目のデプロイでは--sample
オプションを与えて、カレントディレクトリの Rails プロジェクトではなく、サンプルアプリケーションをデプロイさせる方法で回避する。
$ eb create blog-production \ --sample \ --cname com-example-blog-production \ --instance_type t2.micro \ --region ap-northeast-1 \ --tier webserver \ --vpc.ec2subnets subnet-f23be885 \ --vpc.elbsubnets subnet-f23be885 \ --vpc.id vpc-d42ae5b1 \ --vpc.securitygroups sg-bdc574d8 \ --vpc.publicip \ --vpc.elbpublic Environment details for: blog-production Application name: blog Region: ap-northeast-1 Deployed Version: None Environment ID: e-3qvcc2mas3 Platform: 64bit Amazon Linux 2014.09 v1.2.0 running Ruby 2.1 (Puma) Tier: WebServer-Standard-1.0 CNAME: com-example-blog-production.elasticbeanstalk.com Updated: 2015-02-18 08:19:01.355000+00:00 Printing Status: INFO: createEnvironment is starting. INFO: Using elasticbeanstalk-ap-northeast-1-123456789012 as Amazon S3 storage bucket for environment data. INFO: Created security group named: sg-cac677af INFO: Created load balancer named: awseb-e-3-AWSEBLoa-19XNPJOJ2L4UJ INFO: Created security group named: sg-d2c677b7 INFO: Created Auto Scaling launch configuration named: awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingLaunchConfiguration-1JJZT8EC6TQTN INFO: Waiting for EC2 instances to launch. This may take a few minutes. INFO: Created Auto Scaling group named: awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingGroup-XQ9W5EU82FGI INFO: Created Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:123456789012:scalingPolicy:6c971967-dbd5-420c-b396-3e9077ca17c5:autoScalingGroupName/awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingGroup-XQ9W5EU82FGI:policyName/awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingScaleUpPolicy-1QMQK2YUBBKEQ INFO: Created Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:123456789012:scalingPolicy:ec062391-358f-4296-af75-71b20f5d1677:autoScalingGroupName/awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingGroup-XQ9W5EU82FGI:policyName/awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingScaleDownPolicy-6YRVJB2IR2C2 INFO: Created CloudWatch alarm named: awseb-e-3qvcc2mas3-stack-AWSEBCloudwatchAlarmHigh-O9GN3OBFYQK3 INFO: Created CloudWatch alarm named: awseb-e-3qvcc2mas3-stack-AWSEBCloudwatchAlarmLow-18E1BGLOHWKS INFO: Added EC2 instance 'i-f59d7eed' to Auto Scaling Group 'awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingGroup-XQ9W5EU82FGI'. INFO: Application available at com-example-blog-production.elasticbeanstalk.com. INFO: Successfully launched environment: blog-production
画面確認
$ eb open # http://com-example-blog-production.elasticbeanstalk.com
eb setenv
コマンドで環境変数を設定する。
$ eb setenv \ SECRET_KEY_BASE=`bin/rake secret` \ RDS_DB_NAME=blogdb \ RDS_USERNAME=bloguser \ RDS_PASSWORD=bloguser1234567890 \ RDS_HOSTNAME=myinstance.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com \ RDS_PORT=3306 INFO: Environment update is starting. INFO: Updating environment blog-production's configuration settings. INFO: Successfully deployed new configuration to environment. INFO: Environment update completed successfully.
確認
$ eb printenv Environment Variables: AWS_SECRET_KEY = None RDS_PORT = 3306 RAILS_SKIP_ASSET_COMPILATION = false BUNDLE_WITHOUT = test:development RDS_PASSWORD = bloguser1234567890 SECRET_KEY_BASE = 72ecc50883dd60d2668c5074053c5aae9c7acf5409eccab206053b2cf8e7039871d86ab349fa99cf208350ecbec5091dbd22a3f274b2cb242747d860f5fd6b93 RACK_ENV = production PARAM5 = None PARAM4 = None PARAM3 = None PARAM2 = None PARAM1 = None RDS_USERNAME = bloguser RDS_DB_NAME = blogdb RAILS_SKIP_MIGRATIONS = false AWS_ACCESS_KEY_ID = None RDS_HOSTNAME = myinstance.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com
ここでカレントディレクトリの Rails プロジェクトをデプロイする。
$ eb deploy INFO: Environment update is starting. INFO: Deploying new version to instance(s). INFO: New application version was deployed to running EC2 instances. INFO: Environment update completed successfully.
画面確認。
$ eb open
アプリ画面が表示されることを確認。
とりあえず適当なデータを1件登録してみる。
ここで Beanstalk で作成した EC2 インスタンスのタイムゾーンと RDS に保存されたレコードの時間を確認する。
まず、EC2 インスタンスの PublicDns, PublicIp を確認する。
# 環境名 blog-production でフィルタする $ aws ec2 describe-instances --filters "Name=tag-value,Values=blog-production" | jq '.Reservations[].Instances[] | {PublicDnsName,PublicIpAddress}' # またはインスタンスID指定 # $ aws ec2 describe-instances --instance-ids i-f59d7eed --filters "Name=tag-value,Values=blog-production" | jq '.Reservations[].Instances[] | {PublicDnsName,PublicIpAddress}' { "PublicDnsName": "ec2-54-65-4-37.ap-northeast-1.compute.amazonaws.com", "PublicIpAddress": "54.65.4.37" }
EC2 インスタンスの SSH ログインしてタイムゾーンを確認。
$ ssh -i ~/.ssh/aws-eb ec2-user@54.65.4.37 [ec2-user@ip-10-0-0-189 ~]$ date 2015年 2月 18日 水曜日 17:34:28 JST
RDS MySQL にコマンド接続して、セッションの現在時間、テーブルの登録データの日時を確認。
$ mysql -h myinstance.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -P 3306 -u bloguser -p -D blogdb mysql> select now(); +---------------------+ | now() | +---------------------+ | 2015-02-18 17:41:00 | +---------------------+ 1 row in set (0.01 sec) mysql> select * from articles; +----+-------+---------+---------------------+---------------------+ | id | title | content | created_at | updated_at | +----+-------+---------+---------------------+---------------------+ | 1 | foo | bar | 2015-02-18 17:35:40 | 2015-02-18 17:35:40 | +----+-------+---------+---------------------+---------------------+ 1 row in set (0.01 sec) mysql> \q
次回以降のデプロイでは DB マイグレーションが自動実行されないように環境変数RAILS_SKIP_MIGRATIONS
を false から true に変更しておく。
$ eb setenv RAILS_SKIP_MIGRATIONS=true
ここまでで環境構築からアプリデプロイまでの工程が完了した。
ここからは、ここまで作成してきたもの削除して元に戻す作業を行う。
ELB、EC2 などの Beanstalk リソース群のすべてを削除する。
$ eb terminate The environment "blog-production" and all associated instances will be terminated. To confirm, type the environment name: blog-production INFO: terminateEnvironment is starting. INFO: Deleted CloudWatch alarm named: awseb-e-3qvcc2mas3-stack-AWSEBCloudwatchAlarmLow-18E1BGLOHWKS INFO: Deleted CloudWatch alarm named: awseb-e-3qvcc2mas3-stack-AWSEBCloudwatchAlarmHigh-O9GN3OBFYQK3 INFO: Deleted Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:123456789012:scalingPolicy:ec062391-358f-4296-af75-71b20f5d1677:autoScalingGroupName/awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingGroup-XQ9W5EU82FGI:policyName/awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingScaleDownPolicy-6YRVJB2IR2C2 INFO: Deleted Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:123456789012:scalingPolicy:6c971967-dbd5-420c-b396-3e9077ca17c5:autoScalingGroupName/awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingGroup-XQ9W5EU82FGI:policyName/awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingScaleUpPolicy-1QMQK2YUBBKEQ INFO: Waiting for EC2 instances to terminate. This may take a few minutes. INFO: Deleted Auto Scaling group named: awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingGroup-XQ9W5EU82FGI INFO: Deleted Auto Scaling launch configuration named: awseb-e-3qvcc2mas3-stack-AWSEBAutoScalingLaunchConfiguration-1JJZT8EC6TQTN INFO: Deleted load balancer named: awseb-e-3-AWSEBLoa-19XNPJOJ2L4UJ INFO: Deleted security group named: sg-d2c677b7 INFO: Deleted security group named: sg-cac677af INFO: Deleting SNS topic for environment blog-production. INFO: terminateEnvironment completed successfully.
データも削除されるので注意!
# スナップショットは作らず削除 $ aws rds delete-db-instance --db-instance-identifier myinstance --skip-final-snapshot # スナップショットを作ってから削除 $ aws rds delete-db-instance --db-instance-identifier myinstance \ --no-skip-final-snapshot \ --final-db-snapshot-identifier myinstance-final-snapshot
インスタンス削除が完了するまで待つ。
DB パラメーターグループmydbparamgroup
を削除する。
$ aws rds delete-db-parameter-group --db-parameter-group-name mydbparamgroup
DB サブネットグループmydbsubnetgroup
を削除する。
$ aws rds delete-db-subnet-group --db-subnet-group-name mydbsubnetgroup
VPC セキュリティグループmyrds
を削除する。
$ aws ec2 delete-security-group --group-id sg-14c77671
$ aws ec2 delete-subnet --subnet-id subnet-f23be885 $ aws ec2 delete-subnet --subnet-id subnet-ff3be888 $ aws ec2 delete-subnet --subnet-id subnet-d721d58e
$ aws ec2 delete-route-table --route-table-id rtb-2073a745
$ aws ec2 detach-internet-gateway --internet-gateway-id igw-85d63ce0 --vpc-id vpc-d42ae5b1
$ aws ec2 delete-internet-gateway --internet-gateway-id igw-85d63ce0
$ aws ec2 delete-vpc --vpc-id vpc-d42ae5b1
同時に
も削除される。
ちなみにコマンドから削除する場合は、親の VPC から削除することはできず、上記のように子の方から順に依存関係を解除しないとその親は削除できない。
一方、GUIの管理コンソールから削除する場合は、親の VPC から削除することが可能で、その下に紐付くものすべて削除される(インスタンスが残っている場合などは無理)。
環境:
Mac
aws-cli 1.7.0
jq 1.4
RDS MySQL(5.6.22)
RDS MySQL の文字コードとタイムゾーンの設定を行ったのでその手順メモ。
操作はすべて aws-cli のコマンドラインで行う。
RDS MySQL の文字コードおよび照合順序はデフォルトの状態でインスタンスを立ち上げると以下のようになる。
mysql> show global variables like 'character\_set\_%'; +--------------------------+--------+ | Variable_name | Value | +--------------------------+--------+ | character_set_client | latin1 | | character_set_connection | latin1 | | character_set_database | latin1 | | character_set_filesystem | binary | | character_set_results | latin1 | | character_set_server | latin1 | | character_set_system | utf8 | +--------------------------+--------+ 7 rows in set (0.01 sec) mysql> show global variables like 'collation%'; +----------------------+-------------------+ | Variable_name | Value | +----------------------+-------------------+ | collation_connection | latin1_swedish_ci | | collation_database | latin1_swedish_ci | | collation_server | latin1_swedish_ci | +----------------------+-------------------+
登録するデータとして絵文字が含まれるので utf8mb4 を使えるように設定を行う。
RDS の設定値を変更するにはDB パラメーターグループを通して行う。
まずは、mysql5.6 用の DB パラメーターグループの雛形を元にして新規の DB パラメーターグループをrds create-db-parameter-group
コマンドで作成する。
mydbparamgroup
とする。$ aws rds create-db-parameter-group --db-parameter-group-name mydbparamgroup --db-parameter-group-family mysql5.6 --description "for myinstance" { "DBParameterGroup": { "DBParameterGroupName": "mydbparamgroup", "DBParameterGroupFamily": "mysql5.6", "Description": "for myinstance" } }
続いて作成した DB パラメーターグループのキャラクタセット関連のパラメータの初期値をrds describe-db-parameters
コマンドで確認する。
ParameterValue はすべて未設定となっている。
$ aws rds describe-db-parameters --db-parameter-group-name mydbparamgroup \ | jq '.Parameters[] | select(.ParameterName | contains("character") or contains("collation")) | { Description,DataType,Source,IsModifiable,ParameterName,ParameterValue,ApplyType }' { "Description": "Don't ignore character set information sent by the client.", "DataType": "boolean", "Source": "engine-default", "IsModifiable": true, "ParameterName": "character-set-client-handshake", "ParameterValue": null, "ApplyType": "static" } { "Description": "The character set for statements that arrive from the client.", "DataType": "string", "Source": "engine-default", "IsModifiable": true, "ParameterName": "character_set_client", "ParameterValue": null, "ApplyType": "dynamic" } { "Description": "The character set used for literals that do not have a character set introducer and for number-to-string conversion.", "DataType": "string", "Source": "engine-default", "IsModifiable": true, "ParameterName": "character_set_connection", "ParameterValue": null, "ApplyType": "dynamic" } { "Description": "The character set used by the default database.", "DataType": "string", "Source": "engine-default", "IsModifiable": true, "ParameterName": "character_set_database", "ParameterValue": null, "ApplyType": "dynamic" } { "Description": "The file system character set.", "DataType": "string", "Source": "engine-default", "IsModifiable": true, "ParameterName": "character_set_filesystem", "ParameterValue": null, "ApplyType": "dynamic" } { "Description": "The character set used for returning query results to the client.", "DataType": "string", "Source": "engine-default", "IsModifiable": true, "ParameterName": "character_set_results", "ParameterValue": null, "ApplyType": "dynamic" } { "Description": "The server's default character set.", "DataType": "string", "Source": "engine-default", "IsModifiable": true, "ParameterName": "character_set_server", "ParameterValue": null, "ApplyType": "dynamic" } { "Description": "The collation of the connection character set.", "DataType": "string", "Source": "engine-default", "IsModifiable": true, "ParameterName": "collation_connection", "ParameterValue": null, "ApplyType": "dynamic" } { "Description": "The server's default collation.", "DataType": "string", "Source": "engine-default", "IsModifiable": true, "ParameterName": "collation_server", "ParameterValue": null, "ApplyType": "dynamic" } { "Description": "Ignore character set information sent by the client.", "DataType": "boolean", "Source": "engine-default", "IsModifiable": true, "ParameterName": "skip-character-set-client-handshake", "ParameterValue": null, "ApplyType": "static" }
DB パラメーターグループのキャラクタセット関連のパラメータをrds modify-db-parameter-group
コマンドで更新する。
character_set_filesystem
、character_set_system
以外のキャラクタセットはutf8mb4
を設定する。utf8mb4_general_ci
にする。skip-character-set-client-handshake
は TRUE にするとクライアント側が要求してきたキャラクタセットは無視して強制的にサーバ側のcharacter-set-server
で指定したキャラクタセットで応答するようになるらしい。$ aws rds modify-db-parameter-group --db-parameter-group-name mydbparamgroup --parameters \ ParameterName=character_set_client,ParameterValue=utf8mb4,ApplyMethod=immediate \ ParameterName=character_set_connection,ParameterValue=utf8mb4,ApplyMethod=immediate \ ParameterName=character_set_database,ParameterValue=utf8mb4,ApplyMethod=immediate \ ParameterName=character_set_results,ParameterValue=utf8mb4,ApplyMethod=immediate \ ParameterName=character_set_server,ParameterValue=utf8mb4,ApplyMethod=immediate \ ParameterName=collation_connection,ParameterValue=utf8mb4_general_ci,ApplyMethod=immediate \ ParameterName=collation_server,ParameterValue=utf8mb4_general_ci,ApplyMethod=immediate \ ParameterName=skip-character-set-client-handshake,ParameterValue=0,ApplyMethod=pending-reboot { "DBParameterGroupName": "mydbparamgroup" }
DB パラメータグループに反映されたかrds describe-db-parameters
コマンドで確認してみる。
$ aws rds describe-db-parameters --db-parameter-group-name mydbparamgroup \ | jq '[ .Parameters[] | select(.ParameterName | contains("character") or contains("collation")) | { key: .ParameterName, value: .ParameterValue } ] | from_entries' { "character-set-client-handshake": null, "character_set_client": "utf8mb4", "character_set_connection": "utf8mb4", "character_set_database": "utf8mb4", "character_set_filesystem": null, "character_set_results": "utf8mb4", "character_set_server": "utf8mb4", "collation_connection": "utf8mb4_general_ci", "collation_server": "utf8mb4_general_ci", "skip-character-set-client-handshake": "0" }
create-db-instance
コマンドで RDS MySQL インスタンスを作成する。
myinstance
とする。$ aws rds create-db-instance \ --db-instance-identifier myinstance \ --allocated-storage 5 \ --db-instance-class db.t2.micro \ --engine MySQL \ --engine-version 5.6.22 \ --master-username bloguser \ --master-user-password bloguser1234567890 \ --db-name blogdb \ --db-parameter-group-name mydbparamgroup \ --storage-type standard \ --no-multi-az \ --region ap-northeast-1 \ --publicly-accessible \ --no-auto-minor-version-upgrade
コマンドを実行すると RDS インスタンスの作成がはじまる。しばらく時間がかかるので待つ。
default VPC
内に作成される。default VPC security group
が設定される。default
が設定される。インスタンスの作成が完了したら、rds describe-db-instances
コマンドでエンドポイントを確認する。
$ aws rds describe-db-instances --db-instance-identifier myinstance ... "Endpoint": { "Port": 3306, "Address": "myinstance.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com" }, ...
PublicIp、PublicDnsName はec2 describe-network-interfaces
コマンドで確認できる。
GUI 管理コンソールでは、EC2 Dashboard -> Network interfaces から確認できる。
$ aws ec2 describe-network-interfaces --filters "Name=description,Values=RDSNetworkInterface" ... "Description": "RDSNetworkInterface", "Association": { "PublicIp": "54.92.100.249", "PublicDnsName": "ec2-54-92-100-249.ap-northeast-1.compute.amazonaws.com", "IpOwnerId": "amazon-rds" }, ...
RDS MySQL に外部から接続するためにdefault VPC security group
に Inbound のルールを追加する。
セキュリティグループ ID を確認。
$ aws rds describe-db-instances --db-instance-identifier myinstance ... "VpcSecurityGroups": [ { "Status": "active", "VpcSecurityGroupId": "sg-xxxxxxxx" } ], ...
ec2 authorize-security-group-ingress
コマンドで追加する。
$ aws ec2 authorize-security-group-ingress --group-id sg-xxxxxxxx --protocol tcp --port 3306 --cidr 0.0.0.0/0
上で調べた Endpoint または PublicIp、PublicDnsName のいずれかをホストに指定して MySQL に接続する。
$ mysql -h myinstance.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -P 3306 -u bloguser -p -D blogdb
MySQL に接続できたら、キャラクタセットの設定を確認する。
mysql> show create database blogdb\G *************************** 1. row *************************** Database: blogdb Create Database: CREATE DATABASE `blogdb` /*!40100 DEFAULT CHARACTER SET utf8mb4 */ 1 row in set (0.01 sec) mysql> show variables like 'character\_set\_%'; +--------------------------+---------+ | Variable_name | Value | +--------------------------+---------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8mb4 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | utf8mb4 | | character_set_system | utf8 | +--------------------------+---------+ mysql> show global variables like 'character\_set\_%'; +--------------------------+---------+ | Variable_name | Value | +--------------------------+---------+ | character_set_client | utf8mb4 | | character_set_connection | utf8mb4 | | character_set_database | utf8mb4 | | character_set_filesystem | binary | | character_set_results | utf8mb4 | | character_set_server | utf8mb4 | | character_set_system | utf8 | +--------------------------+---------+ mysql> show variables like 'collation%'; +----------------------+--------------------+ | Variable_name | Value | +----------------------+--------------------+ | collation_connection | utf8_general_ci | | collation_database | utf8mb4_general_ci | | collation_server | utf8mb4_general_ci | +----------------------+--------------------+ mysql> show global variables like 'collation%'; +----------------------+--------------------+ | Variable_name | Value | +----------------------+--------------------+ | collation_connection | utf8mb4_general_ci | | collation_database | utf8mb4_general_ci | | collation_server | utf8mb4_general_ci | +----------------------+--------------------+
global variables は指定通り utf8mb4 になっているが、session の variables は utf8 になっている箇所がある・・・
MySQL クライアント側のキャラクタセットがどうなっているか調べてみる。
今、手元の Mac にインストールした MySQL(Server version: 5.6.19 Homebrew)から接続しているので、そのローカルの MySQL にログインする。
$ mysql -uroot mysql> show variables like 'character\_set\_%'; +--------------------------+--------+ | Variable_name | Value | +--------------------------+--------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | utf8 | | character_set_system | utf8 | +--------------------------+--------+ mysql> show global variables like 'character\_set\_%'; +--------------------------+--------+ | Variable_name | Value | +--------------------------+--------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | utf8 | | character_set_system | utf8 | +--------------------------+--------+ mysql> show variables like 'collation%'; +----------------------+-----------------+ | Variable_name | Value | +----------------------+-----------------+ | collation_connection | utf8_general_ci | | collation_database | utf8_general_ci | | collation_server | utf8_general_ci | +----------------------+-----------------+ mysql> show global variables like 'collation%'; +----------------------+-----------------+ | Variable_name | Value | +----------------------+-----------------+ | collation_connection | utf8_general_ci | | collation_database | utf8_general_ci | | collation_server | utf8_general_ci | +----------------------+-----------------+
character_set_client
など、すべて utf8 になっていたのでこれが原因だろう。クライアント側でキャラクタセットを指定して再度、RDS MySQL に接続してみる。
コマンドラインのオプションで--default-character-set
を指定する。
$ mysql --default-character-set=utf8mb4 -h myinstance.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -P 3306 -u bloguser -p
再度、キャラクタセットの設定を確認する。
mysql> show variables like 'character\_set\_%'; +--------------------------+---------+ | Variable_name | Value | +--------------------------+---------+ | character_set_client | utf8mb4 | | character_set_connection | utf8mb4 | | character_set_database | utf8mb4 | | character_set_filesystem | binary | | character_set_results | utf8mb4 | | character_set_server | utf8mb4 | | character_set_system | utf8 | +--------------------------+---------+ mysql> show global variables like 'character\_set\_%'; +--------------------------+---------+ | Variable_name | Value | +--------------------------+---------+ | character_set_client | utf8mb4 | | character_set_connection | utf8mb4 | | character_set_database | utf8mb4 | | character_set_filesystem | binary | | character_set_results | utf8mb4 | | character_set_server | utf8mb4 | | character_set_system | utf8 | +--------------------------+---------+ mysql> show variables like 'collation%'; +----------------------+--------------------+ | Variable_name | Value | +----------------------+--------------------+ | collation_connection | utf8mb4_general_ci | | collation_database | utf8mb4_general_ci | | collation_server | utf8mb4_general_ci | +----------------------+--------------------+ mysql> show global variables like 'collation%'; +----------------------+--------------------+ | Variable_name | Value | +----------------------+--------------------+ | collation_connection | utf8mb4_general_ci | | collation_database | utf8mb4_general_ci | | collation_server | utf8mb4_general_ci | +----------------------+--------------------+
今度はセッションの設定も utf8mb4 となった。
一応、skip-character-set-client-handshake
を TRUE の場合もやってみた。
DB パラメータグループを更新する。
$ aws rds modify-db-parameter-group --db-parameter-group-name mydbparamgroup --parameters \ ParameterName=skip-character-set-client-handshake,ParameterValue=1,ApplyMethod=pending-reboot
変更を反映させるためにrds reboot-db-instance
コマンドで RDS インスタンスの再起動させる。
$ aws rds reboot-db-instance --db-instance-identifier myinstance
同じように RDS MySQL に接続してキャラクタセットを確認したところ、クライアント側で要求したキャラクタセットは無視されて、すべて utf8mb4 となることが確認できた。
※追記:タイムゾーンの設定が可能になり以下で設定できる。init_connectを使ったワークアラウンドは不要になった
$ aws rds modify-db-parameter-group --db-parameter-group-name mydbparamgroup --parameters \ ParameterName=time_zone,ParameterValue=Asia/Tokyo,ApplyMethod=immediate
Amazon Web Services ブログ: Amazon RDS (MySQL, MariaDB)がlocal time zoneをサポートしました
http://aws.typepad.com/aws_japan/2015/12/amazon-rds-local-timezone-support.html
--
以下、タイムゾーンの変更ができなかった頃のワークアラウンド
RDS MySQL のタイムゾーンを JST にしたいが、現時点ではタイムゾーンの変更はできず、デフォルトの UTC となっている。
調べてみるとワークアラウンドとして、init_connect
変数を使って接続毎にタイムゾーンを設定する方法があるようなので、それをやってみる。
以下を参考にさせてもらった。
AWS - RDS(MySQL)でJSTを使う たった1つの冴えたやり方 - Qiita
http://qiita.com/j3tm0t0/items/089ef96ba131df079ca4
MySQL,RDS - RDS(MySQLエンジンにてタイムゾーンを変更する方法を整理) - Qiita
http://qiita.com/mitzi2funk/items/4726986e8288b1599786
» AWS RDSのタイムゾーンについて Tech Fun.cc
http://techfun.cc/aws/aws-rds-timezone.html
init_connect
で単純にSET SESSION time_zone = 'Asia/Tokyo';
とやるのでは問題が発生するとのこと。
RDS 管理用のrdsadmin
というユーザがいて、このユーザが何かする時に Timezone が UTC 以外だと不具合が発生してしまうみたい。
以下のようにrdsadmin
ユーザ以外の接続時のみ Timezone を変更するようにすればよい。
SET SESSION time_zone = CASE WHEN POSITION('rds' IN CURRENT_USER()) = 1 THEN 'UTC' ELSE 'Asia/Tokyo' END;
# ローカル Mac の現在時間 $ date 2015年 2月17日 火曜日 01時27分19秒 JST # RDS MySQL に接続 $ mysql -h myinstance.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -P 3306 -u bloguser -p # 現在時間、タイムゾーン確認 mysql> select now(); +---------------------+ | now() | +---------------------+ | 2015-02-16 16:27:51 | +---------------------+ mysql> show variables like '%time_zone'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | system_time_zone | UTC | | time_zone | UTC | +------------------+-------+ mysql> show global variables like '%time_zone'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | system_time_zone | UTC | | time_zone | UTC | +------------------+-------+
UTC となっている。ローカルは JST なので当然ながら時間はズレている。
init_connect
変数を設定DB パラメータグループのinit_connect
変数を更新する。
SET 文を aws-cli の直接コマンドに埋め込むのではなく、ファイルに書いてそれをアップロードする方法で行う。
まずはテンプレートとなるファイルを--generate-cli-skeleton
オプションで出力させる。
$ aws rds modify-db-parameter-group --generate-cli-skeleton > init_connect.json
出力されたファイルを以下のように編集する。
{ "DBParameterGroupName": "mydbparamgroup", "Parameters": [ { "ParameterName": "init_connect", "ParameterValue": "SET SESSION time_zone = CASE WHEN POSITION('rds' IN CURRENT_USER()) = 1 THEN 'UTC' ELSE 'Asia/Tokyo' END;", "Description": "", "Source": "", "ApplyType": "", "DataType": "", "AllowedValues": "", "IsModifiable": true, "MinimumEngineVersion": "", "ApplyMethod": "immediate" } ] }
そしてDB パラメータグループを更新する。--cli-input-json
オプションでファイルを指定。
$ aws rds modify-db-parameter-group --cli-input-json file://init_connect.json # 終わったら不要なので削除 $ rm init_connect.json
設定が反映されるまで待つ。
反映されたら再度 RDS MySQL に接続して確認してみる。
# ローカル Mac の現在時間 $ date 2015年 2月17日 火曜日 01時38分03秒 JST # RDS MySQL 接続 $ mysql -h myinstance.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -P 3306 -u bloguser -p # 現在時間、タイムゾーン確認 mysql> select now(); +---------------------+ | now() | +---------------------+ | 2015-02-17 01:38:18 | +---------------------+ mysql> show variables like '%time_zone'; +------------------+------------+ | Variable_name | Value | +------------------+------------+ | system_time_zone | UTC | | time_zone | Asia/Tokyo | +------------------+------------+ mysql> show global variables like '%time_zone'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | system_time_zone | UTC | | time_zone | UTC | +------------------+-------+
このセッションのtime_zone
がAsia/Tokyo
になっているのが確認できた。
default VPC security group
に追加した Inbound ルールをec2 revoke-security-group-ingress
コマンドで取り消す。
$ aws ec2 revoke-security-group-ingress --group-id sg-xxxxxxxx --protocol tcp --port 3306 --cidr 0.0.0.0/0
RDS インスタンスmyinstance
をrds delete-db-instance
コマンドで削除する(データも消えるので注意!)。
# スナップショットは作らず削除 $ aws rds delete-db-instance --db-instance-identifier myinstance --skip-final-snapshot # スナップショットを作ってから削除 $ aws rds delete-db-instance --db-instance-identifier myinstance \ --no-skip-final-snapshot \ --final-db-snapshot-identifier myinstance-final-snapshot
インスタンス削除が完了するまで待つ。
DB パラメーターグループmydbparamgroup
をrds delete-db-parameter-group
コマンドで削除する。
$ aws rds delete-db-parameter-group --db-parameter-group-name mydbparamgroup
以上。
DB パラメータグループの JSON データから jq コマンドで目的のデータを抽出するためにいろいろ試行錯誤しながら試した。
記録しておかないと次に再現できないのでメモしておく。
元 JSON データ
{ "Parameters": [ { "Description": "Controls whether user-defined functions that have only an xxx symbol for the main function can be loaded", "DataType": "boolean", "AllowedValues": "0,1", "Source": "engine-default", "IsModifiable": false, "ParameterName": "allow-suspicious-udfs", "ApplyType": "static" }, { "Description": "The MySQL installation base directory.", "DataType": "string", "IsModifiable": false, "Source": "system", "ParameterValue": "/rdsdbbin/mysql", "ParameterName": "basedir", "ApplyType": "static" }, ... ] }
上記の元データから jq コマンドを使って、あるパラメータに特定の文字列を含むものだけを抽出して出力してみる。
jq コマンドはjq '.'
、jq '.Parameters[]'
のようにシングルクォートで囲ったフィルタ式を渡すことで実行する。
ParameterName に"character"を含むものを抽出する。
.Parameters[]
で Parameters の配列の全ての要素を取り出して出力する。.Parameters
とは違う。contains()
で()内の入力値に部分一致するかどうかの真偽値を返す。select()
で ()内の条件が真になれば、その要素を出力する、偽であれば何も返さない。$ aws rds describe-db-parameters --db-parameter-group-name mydbparamgroup \ | jq '.Parameters[] | select(.ParameterName | contains("character"))'
下は上と同じように動作する、別の書き方。
$ aws rds describe-db-parameters --db-parameter-group-name mydbparamgroup \ | jq '.Parameters[] | select(contains({ParameterName: "character"}))'
出力結果:
{ "Description": "Don't ignore character set information sent by the client.", "DataType": "boolean", "AllowedValues": "0,1", "Source": "engine-default", "IsModifiable": true, "ParameterName": "character-set-client-handshake", "ApplyType": "static" } { "Description": "The character set for statements that arrive from the client.", "DataType": "string", "IsModifiable": true, "AllowedValues": "big5,dec8,cp850,hp8,koi8r,latin1,latin2,swe7,ascii,ujis,sjis,hebrew,tis620,euckr,koi8u,gb2312,greek,cp1250,gbk,latin5,armscii8,utf8,cp866,keybcs2,macce,macroman,cp852,latin7,utf8mb4,cp1251,cp1256,cp1257,binary,geostd8,cp932,eucjpms", "Source": "user", "ParameterValue": "utf8mb4", "ParameterName": "character_set_client", "ApplyType": "dynamic" } ...
{}
を利用することで、JSON の内容を組み替えたオブジェクトを生成して出力してる。
$ aws rds describe-db-parameters --db-parameter-group-name mydbparamgroup \ | jq '.Parameters[] | select(.ParameterName | contains("character")) | { desc: .Description, name: .ParameterName, value: .ParameterValue }'
出力結果:
{ "desc": "Don't ignore character set information sent by the client.", "name": "character-set-client-handshake", "value": null } { "desc": "The character set for statements that arrive from the client.", "name": "character_set_client", "value": "utf8mb4" } ...
[]
で囲んで配列を作成from_entries
で key-value のペアからオブジェクトへ変換$ aws rds describe-db-parameters --db-parameter-group-name mydbparamgroup \ | jq '[ .Parameters[] | select(.ParameterName | contains("character")) | { key: .ParameterName, value: .ParameterValue} ] | from_entries'
出力結果:
{ "character-set-client-handshake": null, "character_set_client": "utf8mb4", "character_set_connection": "utf8mb4", "character_set_database": "utf8mb4", "character_set_filesystem": null, "character_set_results": "utf8mb4", "character_set_server": "utf8mb4", "skip-character-set-client-handshake": "0" }
"character"または、"collation"を含むものを抽出。or
を使う。
$ aws rds describe-db-parameters --db-parameter-group-name mydbparamgroup \ | jq '.Parameters[] | select(.ParameterName | contains("character") or contains("collation"))' # 上と同じ $ aws rds describe-db-parameters --db-parameter-group-name mydbparamgroup \ | jq '.Parameters[] | select(contains({ParameterName: "character"}) or contains({ParameterName: "collation"}))'
今までものをすべて組み合わせたもの。
desc, name, value のみ
$ aws rds describe-db-parameters --db-parameter-group-name mydbparamgroup \ | jq '.Parameters[] | select(.ParameterName | contains("character") or contains("collation")) | { desc: .Description, name: .ParameterName, value: .ParameterValue }' { "desc": "Don't ignore character set information sent by the client.", "name": "character-set-client-handshake", "value": null } { "desc": "The character set for statements that arrive from the client.", "name": "character_set_client", "value": "utf8mb4" } ...
key-value 形式
$ aws rds describe-db-parameters --db-parameter-group-name mydbparamgroup \ | jq '[ .Parameters[] | select(.ParameterName | contains("character") or contains("collation")) | { key: .ParameterName, value: .ParameterValue } ] | from_entries' { "character-set-client-handshake": null, "character_set_client": "utf8mb4", "character_set_connection": "utf8mb4", "character_set_database": "utf8mb4", "character_set_filesystem": null, "character_set_results": "utf8mb4", "character_set_server": "utf8mb4", "collation_connection": "utf8mb4_general_ci", "collation_server": "utf8mb4_general_ci", "skip-character-set-client-handshake": "0" }
参考:
jq Manual
http://stedolan.github.io/jq/manual/
軽量JSONパーサー『jq』のドキュメント:『jq Manual』をざっくり日本語訳してみました | Developers.IO
http://dev.classmethod.jp/tool/jq-manual-japanese-translation-roughly/
ゼロから始めるjqチュートリアル - JSONを解析/自在に出力する
http://blog.serverfrog.jp/jq-tutorial/
jq コマンドを使う日常のご紹介 - Qiita
http://qiita.com/takeshinoda@github/items/2dec7a72930ec1f658af