SINKCAPITAL
SINKCAPITAL
employment company Blog
Snowflakeにterraformを導入する方法
tech

背景

 今回データ基盤構築のお手伝いをさせていただいているクライアント様の中で、 新規にSnowflakeをご利用される方がいらっしゃり備考録の意味もこめ調査した内容をまとめさせていただいています。 SnowflakeはGCPやAWSといった特定クラウドサービスに縛られないサードパーティツールで、 SQLのみで全ての管理を行うことができるという特徴を持っています。 そのため今回terraformはGCPやAWSなどにおけるインフラ管理というより、DB管理ツール的な意味合いが強くなっています。

Snowflakeにterraformを導入すべきか

 インフラではなくDB管理としてterraform有効なのかでいうと、 個人的にはterraform等で管理することによりインフラと同様「コスト・スピード・リスク」などの面で優れていると考えています。

  • コスト:デプロイ時にかかる工数が大幅に減少
  • スピード:デプロイスピードが向上する
  • リスク:デプロイフローがシステム的に担保され、またDBの最新状態がコードで表現されている。

ただSnowflakeのSQLで全て管理できると行った特性から、 AWS・GCPなどのクラウドサービスと比較すると上記メリットはそこまで大きくないように感じました。 例えばCI/CDがなくてもSQLをGitHubなどで管理することで、 デプロイは手動実行になりますが「DBの最新状態がコードで表現されている」状態は保つことができ、 DBの状況がわからないといったリスクは回避できるのではないかと思われます。
 ただ一方でroleの権限などを細かく設定する必要がある点においては、 moduleなどでテンプレート化できる点が大きくterraform側のメリットとしてあるかと思われます。

全体構成

CI/CDの構成

 今回特定クラウドサービスに依存したサービスではなく、 またコード自体はGitHubにて管理していたためGitHub Actionsを用いました。 GitHub Actionsにはシークレット情報を格納する機能があるので、 ユーザー名などは基本的にそちらに格納して用いています。

github_actions
 
name: snowflake_deploy
on: pull_request

env:
  TERRAFORM_VERSION: '1.3.0'
  TERRAFORM_FOLDER: 'terraform' 
  SNOWFLAKE_USER: ${{ secrets.SNOWFLAKE_USER }}
  SNOWFLAKE_PASSWORD: ${{ secrets.SNOWFLAKE_PASSWORD }}
  SNOWFLAKE_ACCOUNT: ${{ secrets.SNOWFLAKE_ACCOUNT }}
  SNOWFLAKE_REGION: "ap-northeast-1.aws"

jobs:
  test_job:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

      - name: Configure aws credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_TERRAFORM_ANALYTICS_USER_ACCESS_KEY }}
          aws-secret-access-key: ${{ secrets.AWS_TERRAFORM_ANALYTICS_USER_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-1
          
      - name: setup terraform
        uses: hashicorp/setup-terraform@v1.3.2
        with:
          terraform_version: ${{ env.TERRAFORM_VERSION }}

      - name: terraform init
        id: init
        working-directory: ${{ env.TERRAFORM_FOLDER }}
        run: |
          terraform init
          
      - name: terraform apply
        id: apply
        working-directory: ${{ env.TERRAFORM_FOLDER }}
        run: |
          terraform apply -no-color -auto-approve -parallelism=50

サンプルにおけるシステム構成

 今回サンプルにおいてはSnowflake内部にdabtabase・schema・tableを構築し、 SnowflakeのtaskによってAmazon S3からtableにデータ連携を行う構成で考えています。

snowflake

terraformのフォルダ構成

 フォルダ構成としては以下のようなものを考えており、 module化するかどうかは主に以下の観点で考えています。

  • 複数のresourceを作成するかどうか
  • 他のデータベースでも汎用的に利用するかどうか

また基本的にリソースの作成と権限付与を同時に行っていますが、 snowflakeではfutureという「特定リソース配下の今後作成するリソースへの権限付与」を行うことができ、 そのためtaskなどでは権限付与を行わずに利用できる状態となっています。

.
├── module
│   ├── database        databaseの作成及び権限の設定
│   │   ├── main.tf
│   │   └── variables.tf
│   ├── stage           stage・integration・file formatの作成及び権限の設定
│   │   ├── main.tf
│   │   └── variables.tf
│   └── task            procedure・taskの作成
│       ├── main.tf
│       └── variables.tf
├── backend.tf          terraformの設定ファイル(stateファイルの置き場など)
├── main.tf             各種モジュール呼び出し+schema・tableの作成
└── variables.tf

module・tfファイルについて

  フォルダ内部のtfファイルの概要をご説明しようと思います。

main.tf

 こちらは各種モジュール呼び出しとschema・tableの作成を行っています。 システム構成図と照らし合わせるとそれぞれ大きな枠から作成していっていることがわかります。

###########################################
# database
###########################################
module database {
  source = "./module/database"
  ...
}

###########################################
# raw schema
###########################################
resource snowflake_schema schema {
  database = module.database.database_name
  name     = "SCHEMA_NAME"
  comment  = "COMMENT"

  is_transient        = false
  is_managed          = false
  data_retention_days = 1
}

###########################################
# table
###########################################
resource snowflake_table table {
  database            = module.database.database_name
  schema              = snowflake_schema.schema.name
  name                = "TABLE_NAME"
  comment             = "COMMENT"
  change_tracking     = false

  column {
    name     = "body"
    type     = "VARIANT"
    nullable = false
  }
}

###########################################
# stage・integration・file format
###########################################
module "stage" {
  source = "./module/stage"
  ...
}

###########################################
# tasl・procedure
###########################################
module "task" {
  source = "./module/task"
  ...
}

database module

 データベースmoduleではdatabaseの作成及び権限の設定を行っています。 権限の設定は実際の利用用途によって変わってくると思いますが、 主に以下3つの権限を準備して権限付与しておけば最低限よいのではないかと思われます。

  • read権限のみを持つロール(各データベースごとに作成)
  • read・write権限を持つロール(各データベースごとに作成)
  • admin関連のロール
###########################################
# database
###########################################
resource snowflake_database database {
  name = var.name
  comment = var.description
  data_retention_time_in_days = 3
}

###########################################
# grant
###########################################
resource snowflake_database_grant grant {
  provider = snowflake.security_admin
  database_name = snowflake_database.database.name
  enable_multiple_grants = true

  privilege = "USAGE"
  roles     = [...]

  with_grant_option = false
}

...

###########################################
# output
###########################################
output "database_name" {
  value = snowflake_database.database.name
}

stage module

 ステージmoduleではstage・integration・file formatの作成及び権限の設定を行っています。 ファイルフォーマットなどは元データの形式によって変わってくるため、 variable化など行って動的に変更できるようにしても良いかもしれないです。

resource snowflake_storage_integration integration {
  provider = snowflake.account_admin
  name    = "${var.database_name}_INTEGRATION_S3"
  comment = "A storage integration for ${var.description}"
  type    = "EXTERNAL_STAGE"

  enabled = true
  storage_provider         = "S3"
  storage_aws_role_arn     = var.storage_aws_role_arn
  storage_allowed_locations = [var.storage_allowed_location]
}

resource snowflake_integration_grant grant {
  provider = snowflake.account_admin
  integration_name = snowflake_storage_integration.integration.name
  roles         = [...]
  privilege     = "USAGE"
  with_grant_option = false
}

resource snowflake_file_format json_format {
  name        = "JSON"
  database    = var.database_name
  schema      = "PUBLIC"
  format_type = "JSON"
  compression = "AUTO"
  binary_format = "UTF-8"
}

resource "snowflake_stage" "stage" {
  name        = "${var.database_name}_${var.schema_name}"
  url         = var.storage_allowed_location
  database    = var.database_name
  schema      = var.schema_name
  storage_integration = snowflake_storage_integration.integration.name
  file_format = "FORMAT_NAME = ${snowflake_file_format.json_format.database}.${snowflake_file_format.json_format.schema}.${snowflake_file_format.json_format.name}"
}

output "stage_name" {
  value = snowflake_stage.stage.name
}

output "file_format" {
  value = "${snowflake_file_format.json_format.database}.${snowflake_file_format.json_format.schema}.${snowflake_file_format.json_format.name}"
}

task module

 タスクmoduleではprocedure・taskの作成を行います。 データのロードはjavascriptのプログラムによって行うためprocedureとして定義しており、 taskの定期実行でprocedureを定期的に呼び出すことで定期更新を実現しています。

resource "snowflake_procedure" "procedure" {
  name     = "LOAD_${var.database_name}_${var.schema_name}_${var.table_name}"
  database = var.database_name
  schema   = var.schema_name
  language = "JAVASCRIPT"
  comment             = "load into ${var.database_name}.${var.schema_name}.${var.table_name}"
  return_type         = "VARCHAR"
  execute_as          = "CALLER"
  return_behavior     = "IMMUTABLE"
  statement           = <<EOT
    ...(javasvtiptでデータロードするプログラム)
EOT
}

resource snowflake_task task {
  provider = snowflake.task_admin
  comment = var.description

  database = var.database_name
  schema   = var.schema_name

  name          = "${var.database_name}_${var.schema_name}_${var.table_name}_TASK"
  schedule      = "USING CRON 45 9 * * * Asia/Tokyo"
  sql_statement = "CALL ${snowflake_procedure.procedure.database}.${snowflake_procedure.procedure.schema}.${snowflake_procedure.procedure.name}();"

  user_task_timeout_ms                     = 10000
  user_task_managed_initial_warehouse_size = "XSMALL"
  enabled                                  = true
}

output "task_name" {
  value = snowflake_task.task.name
}

terraformを利用する際の注意点

 以下terraformを利用する際にハマった注意点を載せておこうと思います。

実行roleが変わるためmodule内部にproviderが必要

 Snowflakeの特徴として作成リソースによって実行ロールを変えるケースが多い事があり、 そのためaliasを含むproviderを複数作る必要があるのですが、 これらがルートディレクトリで設定してもmodule側で利用できず各moduleにて設定が必要となってきます。 この事象はネット上でいくつか報告があり「ルートディレクトリだけでも問題ない」等の記述もありましたが、 terraformのバージョンなどの影響下僕の環境だと各moduleで設定が必要だったため、 ルートディレクトリでの設定でエラーが出る方は試してみてください。
 ただmodule側で設定した際の注意点としてmoduleの削除が少し困難になる点が有り、 例えばルートディレクトリのmoduleを読んでいる箇所をコメントアウトしてしまうと、 module配下のproviderが見つからずリソース削除時にエラーがでてしまいます。 そのためmodule内部のリソースを全てコメントアウトして削除してから、 再度ルートディレクトリのmoduleをコメントアウトすると行った手順が必要になります。

terraform {
  required_providers {
    snowflake = {
      source  = "Snowflake-Labs/snowflake"
      version = "0.44.0"
    }
  }
}

provider "snowflake" {
  role = "アドミン権限のロール名"
}

provider "snowflake" {
  alias = "account_admin"
  role  = "アカウントアドミン権限のロール名"
}

権限付与の際にallが利用できない

 SnowflakeではSQL利用時に以下のような書き方で全スキーマに権限付与等を行うことができますが、 terraformで記載する際にはそういったallやall schemasといった記載方法を用いることができません。

GRANT all ON all schemas IN DATABASE *** TO ROLE ***;
GRANT all ON all tables IN DATABASE *** TO ROLE ***;
GRANT all ON all procedures IN DATABASE *** TO ***;
GRANT all ON all stages IN DATABASE *** TO ROLE ***;
GRANT all ON all file formats IN DATABASE *** TO ROLE ***;

そのためそれぞれ以下のような記載方法で記述する必要があります

GRANT all:すべての権限

 以下のような全権限をlistで持たせておき、 for_each = var.all_table_privileges といった記載方法でgrant文を量産する

variable "all_table_privileges" {
  type    = list(string)
  default = [
    "INSERT",
    "DELETE",
    "SELECT",
    "UPDATE"
    ]
}

ON all schemas:全てのリソース(スキーマ・テーブルなど)

 こちらは今後作成するものに関してはSnowflakeのfuture機能を用い(grant系resourceにて on_future = true を設定)、 デフォルトで作成されるデータベースや既存のものにはそれぞれgrant系resourceを作る必要があります。

integrationはAWS側の設定が必要

 ステージmoduleの箇所にて var.storage_aws_role_arn などを指定していることからも分かる通り、 S3からデータを取得する事ができるAWS IAM roleを事前に作成しておく必要があります。 データ取得時の条件で詳細にアクセス権限が設定できるので、 用途に合わせて設定を行うようにしてください。

まとめ

 今回はSnowflakeをterraform化する際に調査した内容を記事としてまとめさせていただきました。 元々SQLで全リソースを管理できる特性から管理しやすくはなっていますが、 terraform化を進めることでより安全にリソース管理ができたように思えます。
 ただ今後手動で作成するSQLでの操作要望がでてくることが想定され、 その中で全てをterraform管理にするのか一部手動作成を許す運用にするかなどは検討が必要かと思いました。 そういった実際の運用におけるベストプラクティスは、 知見が溜まり次第こういった記事の形で発信していければと思います。

データ周りで話題のdbt(data build tool)をBigQueryを使ってみました
櫻井 裕司
2022/12/05 櫻井 裕司
tech
ETL・ELTのLoad部分を担うオープンソースサービスであるdbtを使ってみて、既存のサービスとの比較を行いました。既存のサービスにない多くの特徴を持っていますので、もし気になった方はぜひ見ていただければと思います。
【事例紹介】IVRy様の分析基盤データパイプラインの設計・開発をお手伝いさせていただきました
櫻井 裕司
2022/11/23 櫻井 裕司
tech case
電話自動応答サービスを展開されているIVRy様に対し、弊社でデータパイプライン構築のお手伝いさせていただきました。その中で重視した考え方や設計思想、また構築後の使用感などを記事にまとめさせていただきましたので、データパイプラインをご検討中の方は是非ご参考にしていただけますと幸いです。
BQにおけるSQL検算を効率化する無料chrome拡張機能をリリースいたしました
櫻井 裕司
2022/09/01 櫻井 裕司
tech
BigQueryのjoin句を含むstandardSQLを入力することで、join前後でのレコード数の変化を返すSQLを自動でクリップボードにコピーする無料chrome拡張機能をリリースいたしました。
社内ドキュメントにNotionを導入して感じた事
櫻井 裕司
2022/04/02 櫻井 裕司
tech
社内ドキュメントをNotionに寄せることで見えてきたメリット・デメリットをまとめていきたいと思います。また使う中で感じたいくつかの要望もまとめていこうと思います。
「BIツール」活用 超入門 Google Data Portalではじめるデータ集計・分析・可視化 第3章 BIツールに関する知識をつける
白井 透
2022/03/31 白井 透
techinternlearning
【「BIツール」活用 超入門 Google Data Portalではじめるデータ集計・分析・可視化 第3章】現在長期インターンをさせてもらっているSinkCapitalさんの方で、データ系の業務に携わることになりそうなのですが、それの準備期間として紹介していただいた本をまとめていきたいと思います。
「BIツール」活用 超入門 Google Data Portalではじめるデータ集計・分析・可視化 第2章 さまざまな分析をしてみよう
白井 透
2022/03/30 白井 透
techinternlearning
【「BIツール」活用 超入門 Google Data Portalではじめるデータ集計・分析・可視化 第2章】現在長期インターンをさせてもらっているSinkCapitalさんの方で、データ系の業務に携わることになりそうなのですが、それの準備期間として紹介していただいた本をまとめていきたいと思います。
「BIツール」活用 超入門 Google Data Portalではじめるデータ集計・分析・可視化 第1章 分析ダッシュボードを作ってみよう
白井 透
2022/03/29 白井 透
techinternlearning
【「BIツール」活用 超入門 Google Data Portalではじめるデータ集計・分析・可視化 第1章】現在長期インターンをさせてもらっているSinkCapitalさんの方で、データ系の業務に携わることになりそうなのですが、それの準備期間として紹介していただいた本をまとめていきたいと思います。
Ruby on Rails チュートリアル第14章をやってみて & まとめ
白井 透
2022/02/20 白井 透
techinternlearning
【Ruby on rails 第14章】インターン先の方から、「これやっとけば、だいぶいい感じだよ!」と言われたので、Ruby on railsのチュートリアルをやってみたいと思います。
Ruby on Rails チュートリアル第13章をやってみて
白井 透
2022/02/20 白井 透
techinternlearning
【Ruby on rails 第13章】インターン先の方から、「これやっとけば、だいぶいい感じだよ!」と言われたので、Ruby on railsのチュートリアルをやってみたいと思います。
Ruby on Rails チュートリアル第12章をやってみて
白井 透
2022/02/19 白井 透
techinternlearning
【Ruby on rails 第12章】インターン先の方から、「これやっとけば、だいぶいい感じだよ!」と言われたので、Ruby on railsのチュートリアルをやってみたいと思います。
Ruby on Rails チュートリアル第11章をやってみて
白井 透
2022/02/19 白井 透
techinternlearning
【Ruby on rails 第11章】インターン先の方から、「これやっとけば、だいぶいい感じだよ!」と言われたので、Ruby on railsのチュートリアルをやってみたいと思います。
Ruby on Rails チュートリアル第10章をやってみて
白井 透
2022/02/18 白井 透
techinternlearning
【Ruby on rails 第10章】インターン先の方から、「これやっとけば、だいぶいい感じだよ!」と言われたので、Ruby on railsのチュートリアルをやってみたいと思います。
Ruby on Rails チュートリアル第9章をやってみて
白井 透
2022/02/16 白井 透
techinternlearning
【Ruby on rails 第9章】インターン先の方から、「これやっとけば、だいぶいい感じだよ!」と言われたので、Ruby on railsのチュートリアルをやってみたいと思います。
Ruby on Rails チュートリアル第8章をやってみて
白井 透
2022/02/14 白井 透
techinternlearning
【Ruby on rails 第8章】インターン先の方から、「これやっとけば、だいぶいい感じだよ!」と言われたので、Ruby on railsのチュートリアルをやってみたいと思います。
Ruby on Rails チュートリアル第7章をやってみて
白井 透
2022/02/14 白井 透
techinternlearning
【Ruby on rails 第7章】インターン先の方から、「これやっとけば、だいぶいい感じだよ!」と言われたので、Ruby on railsのチュートリアルをやってみたいと思います。
Ruby on Rails チュートリアル第6章をやってみて
白井 透
2022/02/13 白井 透
techinternlearning
【Ruby on rails 第6章】インターン先の方から、「これやっとけば、だいぶいい感じだよ!」と言われたので、Ruby on railsのチュートリアルをやってみたいと思います。
Ruby on Rails チュートリアル第5章をやってみて
白井 透
2022/02/12 白井 透
techinternlearning
【Ruby on rails 第5章】インターン先の方から、「これやっとけば、だいぶいい感じだよ!」と言われたので、Ruby on railsのチュートリアルをやってみたいと思います。
Ruby on Rails チュートリアル第4章をやってみて
白井 透
2022/02/11 白井 透
techinternlearning
【Ruby on rails 第4章】インターン先の方から、「これやっとけば、だいぶいい感じだよ!」と言われたので、Ruby on railsのチュートリアルをやってみたいと思います。
Ruby on Rails チュートリアル第3章をやってみて
白井 透
2022/02/08 白井 透
techinternlearning
【Ruby on rails 第3章】インターン先の方から、「これやっとけば、だいぶいい感じだよ!」と言われたので、Ruby on railsのチュートリアルをやってみたいと思います。
Ruby on Rails チュートリアル第2章をやってみて
白井 透
2022/02/07 白井 透
techinternlearning
【Ruby on rails 第2章】インターン先の方から、「これやっとけば、だいぶいい感じだよ!」と言われたので、Ruby on railsのチュートリアルをやってみたいと思います。
Ruby on Rails チュートリアル第1章をやってみて & 自己紹介
白井 透
2022/02/07 白井 透
techinternlearningpersonal
【Ruby on rails 第1章】インターン先の方から、「これやっとけば、だいぶいい感じだよ!」と言われたので、Ruby on railsのチュートリアルをやってみたいと思います。
Nuxt上でのd3を利用した散布図の作成方法
櫻井 裕司
2021/10/29 櫻井 裕司
techdataAnalytics
クリック可能な散布図をNuxtjs上で作成する場合にd3.jsが汎用性が高く便利でした。利用するにあたって難しかった点などを備考録としてまとめています。
アクセスログを可視化しGAのデータを直感的に理解できる型態にする試み(ネットワーク型)
櫻井 裕司
2021/09/05 櫻井 裕司
techdataAnalytics
ビジネスに活きる分析を進める上で弊社では「理解できる」ことを重要と考えており、特に直感的理解は可視化を進める上で特に重要だと考える内容の一つです。弊社では様々なお客様のデータ分析を進める上で常により示唆の大きい可視化を追求しており、今回はその中で最近試みているネットワーク側の可視化についてまとめたいと思います。
代表櫻井による特別講演会が白陵高等学校で開かれました
櫻井 裕司
2021/07/31 櫻井 裕司
eventpersonal
2021年の夏に兵庫県の私立白陵高等学校において、代表櫻井による特別講演会を開催いたしました。今振り返って高校の頃の自分に伝えたいことについてお話しました。
Nuxtで動的ページを随時追加する場合にNot Foundとなる
櫻井 裕司
2021/05/31 櫻井 裕司
tech
Nuxtで動的ページを登録する方法はありますが、登録後に随時コンテンツが追加される際はNot Foundとなってしまうので、そう言った際の対処方法について
GKEをやめてCloud Runを始めてみました
櫻井 裕司
2021/04/19 櫻井 裕司
tech
firebaseで構築したシステムの裏で動かすバッチの負荷が大きく、cloud functionsで終わらなかったためCloud Runを利用してみました。動作確認までの知見等を雑多にまとめてみました。
AWSをやめてfirebaseを使い始めて感じたメリットやデメリットとそれの対応策(LT登壇内容)
櫻井 裕司
2021/03/26 櫻井 裕司
techeventpersonal
みそかつウェブ・GDG Nagoya主催の「around firebase」とCloud Native Nagoya主演の「Cloud Native Nagoya」にてfirebaseのLTをさせていただきました。そこで会話させていただいたfirebaseを使い始めて感じたメリット・デメリットについてまとめています。
PWA+SPAのwebアプリ作成にnuxtjs+firebaseがめちゃ便利だった
櫻井 裕司
2021/01/16 櫻井 裕司
tech
PWA+SPAのwebアプリを作る際にnuxt.js+firebaseを合わせて利用すると便利だったので知見を書き留めています
s3のhostingでPWAを導入する方法
櫻井 裕司
2020/12/19 櫻井 裕司
tech
アプリ作成時にpwaが比較されることが多かったですが、実際にpwaを実装した経験がなかったため今回自社サイトをPWA化してみました。
dockerでseleniumを動かしてみる(chrome_headless)
櫻井 裕司
2020/12/06 櫻井 裕司
tech
seleniumの相談をいただくことが増えたため、seleniumの勉強もかねてdockerでの実行テストを行いました
THE DECKのイベントにお邪魔させていただきました
本林 秀和
2020/12/05 本林 秀和
eventpersonal
大学コンソーシアム大阪のイベント@The DECK にお邪魔してきました
flutter(dart)を触ってみた感想
櫻井 裕司
2020/11/18 櫻井 裕司
tech
android向けアプリへの対応も考慮してflutter(dart)を触ってみたので、感想をまとめておこうと思います。理解が深まっていく中で定期的にまとめていければと思います。
代表本林による特別講演会が滝高校で開かれました
本林 秀和
2020/11/07 本林 秀和
eventpersonal
2020年11月7日(土)愛知県の私立滝高校において、代表本林による特別講演会を開催いたしました。IT業界やデータサイエンスについてお話しました。
AWS・GCPを選ぶ際の観点
櫻井 裕司
2020/10/28 櫻井 裕司
tech
AWSかGCPを選ぶ際の観点について書き留めておこうと思います
CloudFormationとterraformの比較
櫻井 裕司
2020/10/04 櫻井 裕司
tech
AWS CloudFormationとterraformの両方を使ってみて感じた違いをまとめてみました。
iosのcallkit周りでできること
櫻井 裕司
2020/08/24 櫻井 裕司
tech
新規事業を検討する上でios(swift)の電話周りでできることを調査したため、調査結果をブログとして残しています。
総務省特定サービス産業実態調査のデータ分析
櫻井 裕司
2020/07/18 櫻井 裕司
techdataAnalytics
総務省がAPIで市場データを公開しており、分析技術向上と市場感を養うことを目的に定期的に分析を行なっていこうと思います。今回は「特定サービス産業実態調査」について見ていこうと思います。
「お絵かきつみ木バトル」をリリースしました
櫻井 裕司
2020/07/12 櫻井 裕司
techapp
タスク管理を二次元的に行うアプリ「お絵かきつみ木バトル」をリリースしました。SinkCapitalはデータコンサルですが、知見蓄積のため様々な媒体での実験的開発を行っています
総務省工業統計調査のデータ分析
櫻井 裕司
2020/07/11 櫻井 裕司
techdataAnalytics
総務省がAPIで市場データを公開しており、分析技術向上と市場感を養うことを目的に定期的に分析を行なっていこうと思います。今回は「工業統計調査」について見ていこうと思います。
総務省サービス産業動向調査のデータ分析
櫻井 裕司
2020/07/08 櫻井 裕司
techdataAnalytics
総務省がAPIで市場データを公開しており、分析技術向上と市場感を養うことを目的に定期的に分析を行なっていこうと思います。初回は「サービス産業動向調査」について見ていこうと思います。
タスク管理アプリ「タスククロス」をリリースしました
櫻井 裕司
2020/04/08 櫻井 裕司
techapp
タスク管理を二次元的に行うアプリ「タスククロス」をリリースしました。SinkCapitalはデータコンサルですが、知見蓄積のため様々な媒体での実験的開発を行っています
【terraform】gcpでcicd環境を構築する方法
櫻井 裕司
2020/01/04 櫻井 裕司
tech
企業サイトはAWSを利用しているのですが、要件によってはGCPの方が適している場合もあるため、GCPでのcicd構築も行いました。AWSと比較しつつ説明しているため是非ご参考にしてみてください。
【合格体験記】GCP_Cloud_Archtectに受かりました
櫻井 裕司
2019/12/23 櫻井 裕司
personalqualification
Google Professional Cloud Architectに合格したので、勉強法別のコスパをまとめてみました。
AWSでサブドメインなし(wwwなし)からサブドメインあり(wwwあり)へのリダイレクト設定
櫻井 裕司
2019/12/23 櫻井 裕司
tech
もともと企業サイトがサブドメインありで公開していたが、サブドメインなしでもエラーなく接続できるように設計。terraformで作成しているので是非ご参考ください。
マークダウンで記事を書けるようにしてみた
櫻井 裕司
2019/12/16 櫻井 裕司
tech
ホームページのブログをマークダウンを使用してかけるようにしました。gatsbyなどもありますが、今回はお手製cicd+pythonを使用してライトに作成しました。
Copyright © SinkCapital 2022