iPhone 7 の本体交換について返金されました

kheiakiyama.hateblo.jp

上記記事の続報です。

経緯

「圏外」の問題に対する iPhone 7 修理プログラム - Apple サポート
2017/12 に本体交換後、2018/2 に上記アナウンスが出ました。
自分では判断つきませんが、関連ありそうな問題に見えます。

この問題に関してすでに有償で修理をされた方には、Apple からメールでご連絡を差し上げた上で返金手続きをさせていただきます。この問題に関係があると思われる修理を有償で行ったにもかかわらず、2018 年 3 月末までに Apple からメールで連絡がない場合は、お手数ですが Apple へお問い合わせください。

ということなのでしばらく静観していました。

2018/3/10 にこの件について Apple Support からメールが届き、「返金リクエストしてください」とのこと。

返金リクエストのやり方

サポートに連絡

チャットで行いました。
Web もありますが、以前利用したときの感想として iPhone アプリのほうが出来がよかったのでアプリで行いました。

Apple サポート

Apple サポート

  • Apple
  • ユーティリティ
  • 無料

問い合わせ内容の選択肢に「返金リクエスト」にあたるものがないため、一番下に出てくる「さらにヘルプが必要な場合」から自分で内容を記載して連絡します。
サポートと繋がった際は、Apple Support から届いたメール全文を貼れば伝わります。

サポート担当者からの確認

修理・交換の事実確認が行われました。
自分の場合は Apple 銀座店で行ったため、その旨を伝えました。

この後はサポート担当者は返金処理の担当ではないらしく、別の担当者から電話がかかってきます。

返金サポート担当者からの電話

支払った金額を確認するための情報提供を促されました。
シリアル番号と金額が両方確認できる情報がないか聞かれたため、自分の場合は以下2つのドキュメントが Apple ID アカウントのメルアドに以前送られていたので、それを送りました。

  • Genius Bar サービス見積書およびサービス確認書
  • Apple Ginzaからの領収書

このファイルの確認をしてもらった時点で、返金処理を承認できる立場の人にエスカレーションされました。

返金処理承認者からの電話

自分だけかもしれませんが、ハンズフリーで待機できなくてツラかったです。

ここでは返金をどう受け取るかの方法を選択します。
支払いに使ったクレジットカードへの返金 or 銀行振り込みが選択肢です。
電話で銀行口座を伝えることにかなりの抵抗があったのですが、クレジットカードの返金は数ヶ月かかると言われたのであきらめて銀行振り込みにしてもらいました。
一応エスカレーションされたものの、電話が一度切れていたため、電話口に出ている人が Apple の人かは保証されません。
なので、どうやってカスタマーである自分が相手を信用できるか、という方法を考えてモヤモヤしてました。
電話ではムリなので、振り込み先の連絡についてもシステム上で行えるようにしてほしいものです。

結果的には3日後に振り込まれました。

あとがき

自分の場合は iPhone 7 故障からの iPhone 7 の同色同スペックに交換していましたが、iPhone 8iPhone X に交換していればその費用ももってもらえたのでしょうか?
だとしたら惜しいことをしました。

なぜか返金処理承認者の方との電話でだけ上記現象が出てました。
もしまた修理・交換になった場合は2段階認証の載せ換えと指紋登録が非常に煩わしいので勘弁してもらいたいです。

どんな相手でもストレスゼロ!  超一流のクレーム対応

どんな相手でもストレスゼロ! 超一流のクレーム対応

Azure Function Proxy を使って静的サイトをカスタムドメインかつHTTPSのホスティングする

キーワードを詰め込んだら長いタイトルになりました。

静的サイトのホスティング方法

Azure で静的サイトをホスティングするにはいくつか方法があります。

  • Azure Web App
  • Azure CDN + Blob Storage
  • Azure Function Proxy + Blob Storage

大まかに3つあります。

Azure Web App

オーソドックスな方法です。
カスタムドメインを適用するには Shared プラン以上が必要なので、日本リージョンで運用するには大体月1000円以上かかります。(公式:App Service 料金)
このパターンについてはギョームで使っているのでそのうち別媒体で書きます。

Azure CDN + Blob Storage

費用はアクセスが少なければ月数十円で済むでしょう。

なぜ Blob Storage の手前に CDN を挟む必要があるかというと、以下の記事が大変よくまとまっています。

Azure BlobでのWebサイト公開がつらい

Blob Storage のツラみを CDN でどうにかしてやろうということです。
CDNSSL 証明書の面倒を見てくれるということで大変ありがたいです。
スケーラビリティも言うことなしでしょう。

しかし CDN で URL Rewrite するルールの適用が4時間以上かかるということで、待つのがかったるいです。
この記事を書いている間は絶賛待機中なのですが、待っている間に Function で試したところ動いたのでもういいかというところが今ココです。

Azure Function Proxy + Blob Storage

こちらも費用はアクセス次第ですが数十円から運用可能です。

Blob Storage で管理しやすいように管理するコンテンツの URL を Function Proxy でいい感じに整えるという役割分担です。
カスタムドメインSSL 終端は Azure Function が担当します。
なお、今回の例では SSL証明書 は Let's Encrypt を使っているので無料です。

実現方法

ということで本題。

完成品

まずは成果物です。

kheiakiyama's CV

(2018/7/8 追記: こちらの記事で Blob の Static Website によるホスティングに変更済み)

コンテンツは何でもいいですが、Jekyll で作成したレジュメっぽいものを置いています。

GitHub - kheiakiyama/kheiakiyama.github.com at 12dc107f19cdea04a73fd72ec877c2e1f57acf13

余談ですが Octopress はどこに行ったんでしょうね。

GitHub から Blob Storage へのデプロイ

Web App には GitHub からの継続的デプロイ方法が提供されていますが、Blob ではもちろんありません。
そこで Travis CI を使っています。

kheiakiyama.github.com/.travis.yml at 12dc107f19cdea04a73fd72ec877c2e1f57acf13 · kheiakiyama/kheiakiyama.github.com · GitHub

デバッグ用コード多めです。
(上のリンクを開いた前提で)やっていることをざっくり書くと以下のとおりです。

  • Jekyll のビルド
  • .NET Core のインストール
  • AzCopy のインストール
  • AzCopy で Jekyll の成果物を Blob にコピー

Travis CI の権限周りがよくわからなかったので .NET Core のインストールはコピーしてきて手元で動かすだけという雑な作りになっています。

また、AzCopy で set-content-type しないと Blob 側の配信がすべて application/octet-stream になるという悲しい現象が起きるため、拡張子ごとにコピーするというイケてないコードになっています。
Function でヘッダーを上書きするのもありますが、Blob の時点で動作確認できる方が原因切り分けの面で有利なので Blob で実現しています。
コンテンツの一部ファイルが削除された場合など考慮することが他にもありますが、まずはこれで。

Azure Function の実装

proxies.json は以下のとおりです。

{
    "$schema": "http://json.schemastore.org/proxies",
    "proxies": {
        "blob-route": {
            "matchCondition": {
                "route": "/"
            },
            "backendUri": "http://{your_storage}.blob.core.windows.net/{container}/index.html"
        },
        "blob-index": {
            "matchCondition": {
                "route": "/index.html"
            },
            "backendUri": "http://{your_storage}.blob.core.windows.net/{container}/index.html"
        },
        "blob-asserts": {
            "matchCondition": {
                "route": "/assets/{*file}"
            },
            "backendUri": "https://{your_storage}.blob.core.windows.net/{container}/assets/{file}"
        },
        "letsencrypt": {
            "matchCondition": {
                "route": "/.well-known/acme-challenge/{*rest}"
            },
            "backendUri": "https://%WEBSITE_HOSTNAME%/api/letsencrypt/{rest}"
        }
    }
}

Blob Storage から取得したいファイルを Proxy する以外では Let's Encrypt の承認プロセスのための API を Proxy しています。
このあたりは 公式の Wiki に書いてある通りに書いただけです。

Proxy 以外にも api/letsencrypt/{rest} の部分を実装する必要があります。
上述の公式の Wiki を参考に C# か NodeJS の内容をコピペしましょう。

余談ですが Azure ポータルと App Service Editor を両方開きながら相互に読み書きしたところ proxies.json が消えるハプニングが起きました。ローカルに適宜バックアップしながら作業を進めるのが無難です。

Azure Function でカスタムドメインSSL の設定

カスタムドメイン公式 でも見てください。

Let's Encrypt の導入については Azure Function でも Web App でも上記の Proxy 部分以外に差はありません。
How to install · sjkp/letsencrypt-siteextension Wiki · GitHub

公式の手順を参考に粛々と作業を進めましょう。
英語がニガテな方は以下サイトを参考にするとよさそうです。

Azure Web Apps に Let's Encrypt を使って簡単に SSL を導入する - えむにわリソース

無事完了すると SSL 証明書が割り当てられ、カスタムドメインSSL バインディングされた状態になります。

f:id:khei-fuji:20180212164429p:plain

https://{your_site}.scm.azurewebsites.net/.well-known/acme-challenge/{*rest} のリダイレクトでエラーになった場合は Function Proxy の実装が上手くいっていないと思われます。
一つずつ見直しましょう。

参考にした記事

最後に

Proxy は書き換え直後にすぐ動くので使っていて気持ちいいです。
最初に上げた通り、実現方法のパターンはいくつかありますが、要件に合わせて適切に使っていきたいものです。

Azureテクノロジ入門 2018

Azureテクノロジ入門 2018

Azure 系エンジニアから見た GAE 〜Google App Engine編〜

前回に続き GCP。今回は Google App Engine こと GAE。
スケーリングが柔軟なWebアプリケーションの PaaS で、Azure でいうと Web AppsAWS では AWS Elastic Beanstalk のはず。
Heroku を卒業したサービスが仮想マシンベースのサービスに引っ越すか、このへんに引っ越すイメージ。

Google App Engine

料金

全般

App Engine の料金  |  App Engine Documentation  |  Google Cloud Platform

価格 - App Service | Microsoft Azure

GAE の料金体系は、インスタンス(CPU+メモリ)とデータストア、ネットワークトラフィック、あとはコンポーネントによって定義されており、見積もり泣かせな細かい設定となっている。

Azure の Web App 同様、強力なプラットフォームを利用できる代わりにベースの料金はそれなりにかかる模様。
(Azure App Servie ではCPU時間リミットがある無料プランや、プロダクションでは月1万円欠けるスタンダードプランなどがある)

GCP: Instance classes

(B or F) + 数字 の組み合わせでインスタンスが表現される。
数字が CPU 性能で 4_1G 以外は CPU 性能に合わせてメモリ量が増える。
B と F の違いはこの後出てくるスケーリングのタイプによって変わる。

カスタマイズしたインスタンス

フレキシブル環境という仕組みがあり、CPU とメモリのサイズをアプリケーションに合わせてカスタマイズできる。

無料枠

各リソースごとに無料枠が設定されており、たとえばフロントエンドインスタンスは 1日28時間分が無料となっているため、1インスタンスで足りるサービスならインスタンスについては無料でサービスできる。
なにかサービスつくりたい。

開発

全般

GAE ではアプリケーションに関する設定は各種 yaml ファイルで定義する。
app.yaml によるアプリの設定  |  App Engine flexible environment for Java docs  |  Google Cloud Platform

このあたりは GCP の哲学としてコードに残すのだ、という意志を感じる。

スケーリング

オートスケール

インスタンスクラスでいうところの F について。
GAE にはスケーリングのパターンがいくつかある。
オーソドックスな CPU 使用率トリガー以外に、レイテンシの時間をトリガーにできる。
リクエストを受けたキューがインスタンスに流す待ち時間が 500ms を超えたらスケールアウトするなど。

スケールインも細かい制御ができるのが他のクラウドと比べたときの特徴。
インスタンス数をロックするのも可能だが、無料枠の恩恵を受けられないので個人のサービスとしては迷うところか。

マニュアルスケール

オートスケールせずにインスタンス数を固定するのも可能。
この場合は B のインスタンスクラスとなる。

参考

App Engine Scaling Config - Qiita

上がまとまっていて参考になった。
動かすアプリケーションによって経験則による設定値がありそう。

デプロイ

デプロイはわりと時間がかかる。
オーソドックスな以下の app.yaml でも 10分〜15分くらいはかかった印象。

runtime: nodejs
env: flex

あとはスケーリングの変更を行った場合のデプロイは反映されるまでにかなり時間がかかったので詳しい動きを知りたい。
デフォルト設定で負荷をかけて10台くらいにスケールした後、manual_scaling で2台にするのにかなり時間がかかった。元の設定のスケールイン値に基いて2台になるのかも。

ホスティング

よくある Web の PaaS と同じ。

プロジェクトに複数のサービスがある場合は個別に FQDN が払い出される。
gcloud app deploy app.yaml service1.yaml service2.yaml でデプロイ。

カスタムドメインも普通に使える。

よくわかってないところ

シークレット情報としての環境変数

環境変数app.yaml に書く以外の方法が用意されていない。
API Token などのシークレット情報をどこに置けばいいかがわからない。
Azure Web App や Heroku だとクラウドリソースのメタデータとして設定するが、yaml 以外に設定値を持たない GAE でどうすればいいかがわからない。

調べた限りだと Data Store を使ったりCloud Storage を使っている 回避策を取っている模様。
app.yaml.gitignore するのはなしだろうなあ。
GAE は歴史が長いサービスなので、機能がないということはきっとこの先も機能提供されないのだろう。

サービスの落とし方

よくわかりませんでした。
アプリケーションを無効にして、インスタンスを削除すればOKですかね。
請求を後で確認。

最後に

基本的な部分を触っただけなので、まだ試したいことがいろいろ残っている感じ。
思いつくだけでも

  • 複数ドメイン利用するプロジェクトでどうアプリケーションコードを分割するのか
  • スケジューリングジョブ
  • npmComposer, Nuget などのデプロイジョブ
  • 継続的デプロイ

ここまで個別にサービスを見てきたけど、どこかで小さいアプリケーション書いて動かしたほうが足りない部分がわかってよさそう。
時間を取れるときにやりたい。

Azure 系エンジニアから見た GCP 〜Cloud Storage編〜

先週に引き続き GCP を見ていく。

前回は仮想マシン相当の Google Compute Engine だった。
Azure 系エンジニアから見た GCP 〜Google Compute Engine編〜 - ぐだぐだ言ってないでコードを書けよ、ハゲ。

今回はファイルストレージ相当の Cloud Storage。
Azure では Blob Storage、AWS では S3 にあたる。

Cloud Storage

料金

全般

Azure Storage Blob の価格 | Microsoft Azure

Google Cloud Storage の料金体系  |  Cloud Storage ドキュメント  |  Google Cloud Platform

アクセス頻度に基いてどのタイプを使うか選択する。
Azure は単リージョンに置いたとき(LRS)と複数リージョン(GRS)に置いたときで容量課金が純粋に倍になるが、GCP はそうでもない。
GCP ではマルチリージョンで細かいリージョン指定ができないので、東京のように高いリージョンは使われていなくて、結果的に料金が安く見えてるのかもしれない。

マルチリージョンでないプランならリージョンを指定できる。

余談だが Azure の料金プランは V2 ができつつある関係ですごく複雑になっていて見通しがよくないのでつらい。

SLA

細かい話だが SLA に関する対処は横並びっぽい。

料金プランの適用範囲

Azure だとストレージアカウント単位で料金プランを選ぶが、GCP では料金プランを意味する「ストレージ クラス」をオブジェクト単位で指定できるようになっている。
バケットで指定する料金プラン(ストレージクラス)は、あくまでもオブジェクトの料金プランのデフォルトという位置づけ。
特定のオブジェクトのプランを後から変更するのも可能。

オブジェクトのストレージ クラスの変更  |  Cloud Storage ドキュメント  |  Google Cloud Platform

リクエスト課金

リクエスト課金の部分はアクセス元のプロジェクトに払わせることができる。
Azure Blob にはなかったはず。

アクセス

アクセス権限を細かいレベルで管理できるのは想像がつくので特に見てない。
静的サイトのホスティングも普通にできる。

https://storage.googleapis.com/(Bucket_Name)/(Object_Name)

バージョニング

バージョニングを有効にすると、ファイルをアップロードしたときに前バージョンが残る。
最新以外のファイルを操作するにはコンソール(Webのポータル)ではできず、cli ツールである gsutil を使う必要がある。

Azure だとバージョニングはなくて、スナップショットで取ることができる。

Creating a Snapshot of a Blob | Microsoft Docs

スナップショットは明示的取らないといけないので、有効にしておけば自動的に取れる GCP とどっちがいいかは良し悪しか。

GCP Console 周り

今回も Console でいいなと思った部分があった。

調べながら使うというところがすごくカバーされているのを感じる。
Google検索を持ってるから、どこで脱落しているかなどが手に取るようにわかっているのだろう。

あとがき

わかりやすくて機能が少ないサービスは軽く流していけるが、GAE みたいなサービスをどうやって見ていこうかちょっと迷う。
GCP は数年前に見たときのイメージで Go や Java, Python あたりが一級市民てイメージがあるので、ちょっとは書ける Python かこれからの Go を書きながら検証していくしかないのかな。Java は知らん。

Azure 系エンジニアから見た GCP 〜Google Compute Engine編〜

昨年は Microsoft Azure をある程度キャッチアップできた気がするので、今年は Google Computer Platform をキャッチアップしていきます。
今回は公式チュートリアルの最初にあった GCE を見て気になったところをメモしてます。

GCE について

管理

GCP でははじめにプロジェクトを作成し、リソースはプロジェクトの中で作成します。
インスタンス単位で ssh 公開鍵を登録するのはもちろん可能ですが、プロジェクトで ssh 公開鍵を作成し、GCE の各インスタンスではデフォルトではプロジェクトの公開鍵を利用できるため、厳格なポリシーがなければこれで事足ります。

ネットワーク - プライベートアドレス

Azure では内部IP範囲が他の仮想ネットワークと重ならないようにデフォルト指定されます。
これは複数の仮想ネットワークをピアリング接続する可能性を考慮してのことだと思われます。

一方 GCP ではリージョンでデフォルトのIPが決まっていて、別のプロジェクトで作成したプライベートIPの範囲とは重なります。
割り切りですね。

このあたりは好みが分かれるな気がします。

ネットワーク - セキュリティグループ

Azure で言うところの NSG, AWS でいうところのセキュリティグループについて。
Azure ではルールセットである NSG を作成し、VMのネットワークインターフェースかサブネットにアタッチします。

GCP ではネットワーク全体かサブネットかタグにアタッチします。
VMインスタンスがタグを持つことで、特定のインスタンス向けのルールを作成できます。
プラットフォームが役割としてのタグを強制するのは、個人的には好きな対応です。

オートスケール

インスタンスグループという機能によってオートスケールを実現しています。

コンテナ

Azure では Docker コンテナを動かす Web App for Container というサービスがあります。
GCP では GCE でコンテナ機能が実装されていて、驚きました。
現段階ではアルファ版 ということなので、今後どうなるかわかりませんが、注目です。

インスタンスグループにローリングアップデート機能などもあるため、いろいろ捗りそうです。

GCP 全般について

ゾーン

GCP ではリソースを作成するときにゾーンを指定します。
ゾーンは {大陸}-{方角}{NO} となっているので、そのゾーンがどの国を意味しているのかはググって解決してました。
それでいて 料金 ページでは国が表示されるので「このリソースを作るといくらかかるんだっけ?」という気持ちになりました。

ポータル

Azure ポータルは遅いので、そこが快適な GCP は気持ち良いです。
Azure-CLI を使うという手はもちろんありますが、ここは見習って欲しいところ。

おわりに

次はストレージかデータストアあたりを見ていくはず、たぶん。

Amazon Echo はじめた感想

2017/11/27 に Echo 招待リクエストを投げて、2018/1/10 に招待が来て、1/13 に開封した。

Amazon Musicペルソナ4のサントラをかけながら書いている。
音質がよい。

セットアップ

結論、iPhone アプリからセットアップすべき。

Alexa のリスニング能力について

かなりよい。

現在提供されているスキルについて

プライム会員は Amazon Music でサントラ聴いてればいいのでないか。

音楽+25分ポモドーロのアプリは、スキル:集中タイム のこと。

Azure で Alexa 連携する

まだ何もできてない。

スキル作る人へ

「話しかけ方の例」は必須では。

よし、開発するぞ!と意気込んだところ、サクッと開発者アカウント周りでやってしまった気がするので、これから開発する人は下の記事を一読しながら登録したほうがよい。

Alexa 開発者アカウントのハマりどころ - Qiita

ということで買ってやっていきましょう。

Amazon Echo (Newモデル)、チャコール (ファブリック)

Amazon Echo (Newモデル)、チャコール (ファブリック)

Azure PaaS のメンテナンスについて

API Management のメンテナンス?

Azure というか全体的に Intel CPU が入ってるサーバーでは年始から再起動祭りとなっていました。

マイクロソフト、CPUの脆弱性対策でAzureの計画メンテを前倒し、全リージョンの仮想マシンを今朝から強制再起動。Googleは対策済みと発表 - Publickey

ちょうど今日(1/4)19時頃 API Management を触っていたのですが、15分ほどサービスが停止していて使えないタイミングがありました。

f:id:khei-fuji:20180104193004p:plain

デプロイしていた API Management は Developer Tier だったため、SLA はありません。
料金 - API Management | Microsoft Azure

確信はありませんが、もしかすると今回のメンテナンスによる再起動だったかもしれません。
という出来事から PaaS に思いを馳せていました。

PaaS のメンテナンスについて

Azure では IaaS メンテナンスでは、その上で稼働している PaaS のサービスについてメンテナンスのアナウンスは来ません。
これは PaaS のサービスは SLA の範囲内で稼働する設計になっているためです。

今回の API Management は Developer より上の Tier では SLA が設定されています。
アーキテクチャを調べてませんが、Azure の可用性セットで組まれて冗長化されたサーバーが同時に再起動しないようにしているのでしょう。

他にも例を挙げると、Application Gateway は1インスタンスのみで動かすと、VM再起動のタイミングでサービス停止します。
高可用性を求める場合は2インスタンス以上のデプロイをするものとされています。

Application Gateway に関してよく寄せられる質問 | Microsoft Docs

では PaaS にはメンテナンスがないのかというと、そういうわけでもありません。
たとえば機能の変更によるアナウンスがあります。
App Service で PHP 5.5 をサポート終了するときはこういったアナウンスが出ています。
Retirement of the PHP 5.5 runtime from App Service

これはアプリケーションレイヤーで対応が必要になる場合があります。
(もっとも IaaS であってもサポート終了するミドルウェアには追随していくものでしょうが・・・)

まとめ

PaaS ではメンテナンスというよりは強制的なマイグレーションが発生します。
サービスも多く学習コストがかかりますが、一つ一つのコストは低めに作られているので、サービスに合わせて取り入れていきたいものです。