- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2020-08-03T08:53:49+00:00","","")
#mynavi(Azureメモ)
#setlinebreak(on);
* 概要 [#q629b743]
#html(<div class="pl10">)
VMにアクセスする Azure Functions の開発手順を記載する。
#html(</div>)
* 目次 [#uf1ea711]
#contents
- 関連
-- [[Azureメモ]]
-- [[Azure CLI の操作]]
-- [[GoからInfluxDBにアクセスする]]
-- [[Azure Functions を Go で書く]]
- 参考
-- [[Premium プランの関数アプリを作成する:https://docs.microsoft.com/ja-jp/azure/azure-functions/scripts/functions-cli-create-premium-plan]]
-- [[Azure Functions の Premium プラン:https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-premium-plan]]
-- [[サンプルスクリプト:https://docs.microsoft.com/ja-jp/azure/azure-functions/scripts/functions-cli-create-premium-plan#sample-script]]
-- [[Azure Functions のデプロイ テクノロジ:https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-deployment-technologies]]
-- [[Azure Functions の zip デプロイ:https://docs.microsoft.com/ja-jp/azure/azure-functions/deployment-zip-push]]
-- [[チュートリアル: Functions を Azure 仮想ネットワークに統合する:https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-create-vnet]]
-- [[アプリを Azure 仮想ネットワークと統合する:https://docs.microsoft.com/ja-jp/azure/app-service/web-sites-integrate-with-vnet]]
-- [[Azure Functions のネットワーク オプション:https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-networking-options]]
* 作成する関数の仕様 [#i6e368a7]
#html(<div class="pl10">)
以降の手順で作成する関数の仕様 及び リソースイメージは以下の通り。
- Blobストレージへのファイルアップロードをトリガーに起動する関数とする。
- 関数はVMで稼働する InfluxDB にサンプルデータを登録する。(ファイル内容に関係なく...)
#html(<div style="display: inline-block; border: 1px solid #333">)
&ref(sample-azure-image.png,nolink);
#html(</div>)
#html(</div>)
* 作成するファイル [#h684fc8d]
#html(<div class="pl10">)
以降の手順で作成する全ファイルは以下の通り
#html(){{
<div style="padding: 0px 10px 10px 10px; border: 1px solid #333;">
<pre style="display: inline-block; margin: 0; padding-right: 10px; font-size: 1rem; background: transparent; border: 0px; vertical-align: top;">
.
├── 0_env.sh
├── 1_create_resources.sh
├── 2_setup_influxdb.sh
├── 3_deploy_funcapp.sh
├── 9_remove_resources.sh
├── functions
│   ├── BlobTrigger
│   │   └── function.json
│   ├── go_server_sample.exe
│   ├── go_server_sample.go
│   ├── host.json
│   └── local.settings.json
├── pem
│   ├── id_rsa
│   └── id_rsa.pub
</pre>
<pre style="display: inline-block; margin: 0; font-size: 1rem; background: transparent; border: 0px; vertical-align: top;">
... リソース名の定義など
... リソース作成用のシェル
... VMのInfluxDBのセットアップ用シェル
... 関数アプリのデプロイ用シェル
... リソース一括削除用のシェル
... 内部関数名(トリガー名)
... 関数のトリガー定義
... カスタムハンドラー(実行可能ファイル)
... カスタムハンドラー(ソース)
... 関数アプリの定義ファイル
... ローカル実行用の設定ファイル
... 作成するVMのSSH鍵の退避先(VM作成時に自動生成)
</pre>
</div>
}}
#html(</div>)
* リソース作成/デプロイ用のシェル作成 [#z256443a]
#html(<div class="pl10">)
リソース作成用のシェルを以下の通り作成する。
当記事では全てCLIをシェル化したが、恐らく ARM(Azure Resource Manager)を使うのが正解。
※https://azure.microsoft.com/ja-jp/features/resource-manager/
// START tabs1
#html(){{
<div id="tabs1">
<ul>
<li><a href="#tabs1-0">0_env.sh</a></li>
<li><a href="#tabs1-1">1_create_resources.sh</a></li>
<li><a href="#tabs1-2">2_setup_influxdb.sh</a></li>
<li><a href="#tabs1-3">3_deploy_funcapp.sh</a></li>
<li><a href="#tabs1-9">9_remove_resources.sh</a></li>
</ul>
}}
// START tabs1-0
#html(<div id="tabs1-0">)
このシェルでは作成する各リソースの名前の定義を行っている。
※ -p 付きで実行すればコンソールへの表示も行うようにしている。
0_env.sh
#mycode2(){{
#!/bin/bash
# 全てのリソース名に付与する接頭文字 (Storageアカウント名などは世界でユニークな必要があるので他ユーザと被らないような名前を付ける)
PREFIX=XXXXXX
# サブスクリプションID (Application Insight を使用しない場合は空)
subscriptionId=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
# リージョン
region=japanwest
insightsRegion=japaneast # 2020/7時点では Appplication Insights で西日本(japanwest)は使用できない
# リソースグループ名
# ( az group delete --name $resourceGroup で一括削除可能 )
resourceGroup=${PREFIX}ResourceGroup
# ストレージアカウント名
storageAccountName=${PREFIX}straccount
storageSku=Standard_LRS
# Storageコンテナ名
storageContainerIn=${PREFIX}-strcontainer-i
storageContainerOut=${PREFIX}-strcontainer-o
# 仮想ネットワーク名
vnetName=${PREFIX}VNet
vnetPrefix=10.1.0.0/16
# ネットワークセキュリティグループ
nsgName=${vnetName}SecGrp
nsgPubRuleName=${nsgName}PubRule
nsgPubInboundPort="22"
#nsgPubInboundPort="443"
nsgPriRuleName=${nsgName}PriRule
nsgPriInboundPort="8086"
# VM用のサブネット
vmSubnetName=${PREFIX}VmSubnet
vmSubnetPrefix=10.1.1.0/24
# 関数アプリ用のサブネット
funcSubnetName=${PREFIX}FuncSubnet
funcSubnetPrefix=10.1.2.0/24
# 仮想マシン
vmName=${PREFIX}Vm
vmImage=UbuntuLTS # "az vm image list -o table" で利用可能なイメージの一覧を確認可能
vmIpAddress=10.1.1.5
vmUser=sample
# 関数アプリ名
funcAppName=${PREFIX}FuncApp
# 使用するFunctionsのバージョン
funcVersion=2
# 関数アプリのプラン名
funcPlanName=${PREFIX}premiumplan
funcPlanSku=EP1
# Application insights
insightsName=${PREFIX}Insights
insightsDays=30
if [ "$1" == "-p" ]; then
echo "region : $region"
echo "resourceGroup : $resourceGroup"
echo "storageAccountName : $storageAccountName"
echo "storageSku : $storageSku"
echo "storageContainerIn : $storageContainerIn"
echo "storageContainerOut : $storageContainerOut"
echo "vnetName : $vnetName"
echo "vnetPrefix : $vnetPrefix"
echo "nsgName : $nsgName"
echo "nsgPubRuleName : $nsgPubRuleName"
echo "nsgPubInboundPort : $nsgPubInboundPort"
echo "nsgPriRuleName : $nsgPriRuleName"
echo "nsgPriInboundPort : $nsgPriInboundPort"
echo "vmSubnetName : $vmSubnetName"
echo "vmSubnetPrefix : $vmSubnetPrefix"
echo "vmName : $vmName"
echo "vmImage : $vmImage"
echo "vmIpAddress : $vmIpAddress"
echo "vmUser : $vmUser"
echo "funcAppName : $funcAppName"
echo "funcVersion : $funcVersion"
echo "funcPlanName : $funcPlanName"
echo "funcPlanSku : $funcPlanSku"
echo "funcSubnetName : $funcSubnetName"
echo "funcSubnetPrefix : $funcSubnetPrefix"
echo "insightsName : $insightsName"
echo "insightsDays : $insightsDays"
echo "insightsRegion : $insightsRegion"
fi
}}
#html(</div>)
// END tabs1-0
// START tabs1-1
#html(<div id="tabs1-1">)
このシェルでは各リソースを作成する。
※関数アプリは中身が空のアプリとして作成される。(create のみ行っている)
1_create_resources.sh
#mycode2(){{
#!/bin/bash
source ./0_env.sh
# リソースグループの作成
echo az group create
az group create \
--name $resourceGroup \
--location $region
# ストレージアカウントの作成
echo az storage account create
az storage account create \
--name $storageAccountName \
--location $region \
--resource-group $resourceGroup \
--sku $storageSku
# Storageコンテナの作成
echo "az storage container create(in)"
az storage container create \
--name $storageContainerIn \
--resource-group $resourceGroup \
--account-name $storageAccountName
echo "az storage container create(out)"
az storage container create \
--name $storageContainerOut \
--resource-group $resourceGroup \
--account-name $storageAccountName
# NSG(ネットワークセキュリティグループの)作成
echo az network nsg create
az network nsg create \
--resource-group $resourceGroup \
--name $nsgName
# NSGルール(Public)
echo az network nsg rule create
az network nsg rule create \
--resource-group $resourceGroup \
--nsg-name $nsgName \
--name $nsgPubRuleName \
--access Allow \
--protocol Tcp \
--direction Inbound \
--priority 100 \
--source-address-prefix Internet \
--source-port-range "*" \
--destination-port-range $nsgPubInboundPort
# NSGルール(Private) # TODO: 同一ネットワーク内であれば不要
#echo az network nsg rule create
#az network nsg rule create \
# --resource-group $resourceGroup \
# --nsg-name $nsgName \
# --name $nsgPriRuleName \
# --access Allow \
# --protocol Tcp \
# --direction Inbound \
# --priority 110 \
# --source-address-prefix VirtualNetwork \
# --source-port-range "*" \
# --destination-port-range $nsgPriInboundPort
# 仮想ネットワーク 及び サブネット作成
echo az network vnet create
az network vnet create \
--name $vnetName \
--resource-group $resourceGroup \
--address-prefixes $vnetPrefix \
--subnet-name $vmSubnetName \
--subnet-prefixes $vmSubnetPrefix \
--network-security-group $nsgName
# 仮想マシンの作成
# TODO: 管理用の踏み台サーバは別で用意する
rm -rf ~/.ssh/id_rsa
rm -rf ~/.ssh/id_rsa.pub
echo az vm create
az vm create \
--resource-group $resourceGroup \
--name $vmName \
--image $vmImage \
--generate-ssh-keys \
--subnet $vmSubnetName \
--vnet-name $vnetName \
--private-ip-address $vmIpAddress \
--admin-username $vmUser \
--custom-data 2_setup_influxdb.sh \
--output json \
--verbose
# --public-ip-address "" # TODO: 踏み台以外はPublicアクセスなしにする
# 生成されたSSH鍵を移動( --ssh-dest-key-path が効かない為 )
# ※ https://docs.microsoft.com/en-us/cli/azure/vm?view=azure-cli-latest#az-vm-create
rm -rf pem
mkdir -p pem
if [ -e ~/.ssh/id_rsa ]; then
mv ~/.ssh/id_rsa ./pem/
mv ~/.ssh/id_rsa.pub ./pem/
fi
# InfluxDB用のポート開放
echo az vm open-port
az vm open-port \
--resource-group $resourceGroup \
--name $vmName \
--port 8086
# Application Insights 拡張が利用できない場合は追加インストール
x=`az monitor app-insights --help 2>&1`
if [ "$?" != "0" ]; then
az extension add -n application-insights
fi
# Application Insights コンポーネント作成
echo az monitor app-insights component create
if [ "$subscriptionId" != "" ]; then
az monitor app-insights component create \
--app $insightsName \
--location $insightsRegion \
--resource-group $resourceGroup \
--query-access Enabled \
--retention-time $insightsDays \
--subscription $subscriptionId
fi
# プレミアムプランの作成(プレミアムプランでないと関数アプリからのVNetアクセス機能は提供されない)
echo az functionapp plan create
az functionapp plan create \
--name $funcPlanName \
--resource-group $resourceGroup \
--location $region \
--sku $funcPlanSku
# 関数アプリの作成
echo az functionapp create
if [ "$subscriptionId" != "" ]; then
az functionapp create \
--name $funcAppName \
--storage-account $storageAccountName \
--plan $funcPlanName \
--resource-group $resourceGroup \
--functions-version $funcVersion \
--app-insights $insightsName
else
az functionapp create \
--name $funcAppName \
--storage-account $storageAccountName \
--plan $funcPlanName \
--resource-group $resourceGroup \
--functions-version $funcVersion
fi
# 関数アプリの環境変数の設定
echo "az functionapp config appsettings"
az functionapp config appsettings set \
--name $funcAppName \
--resource-group $resourceGroup \
--settings "DB_HOST=$vmIpAddress" "DB_PORT=8086" "DB_NAME=sampledb" "DB_USER=sample" "DB_PW=sample"
# 関数アプリのVNet統合用のサブネット
echo az network vnet subnet create
az network vnet subnet create \
--name $funcSubnetName \
--resource-group $resourceGroup \
--vnet-name $vnetName \
--address-prefixes $funcSubnetPrefix
# 関数アプリのVNet統合(当コマンドはプレビュー版の為、将来で変更/削除される可能性あり)
echo az functionapp vnet-integration add
az functionapp vnet-integration add \
--name $funcAppName \
--resource-group $resourceGroup \
--vnet $vnetName \
--subnet $funcSubnetName
}}
#html(</div>)
// END tabs1-1
// START tabs1-2
#html(<div id="tabs1-2">)
このシェルはVM作成時に実行されるVMの初期化スクリプト。
az vm create 時の --custom-data として指定している為、手動で実行する必要はない。
処理内容は InfluxDBのセットアップ。(docker を使用)
2_setup_influxdb.sh
#mycode2(){{
#!/bin/bash
apt-get update
apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io
curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
mkdir /tmp/influx_docker && cd /tmp/influx_docker
cat <<_EOCONF_ >influxdb.conf
[meta]
dir = "/var/lib/influxdb/meta"
[data]
dir = "/var/lib/influxdb/data"
engine = "tsm1"
wal-dir = "/var/lib/influxdb/wal"
[http]
enabled = true
flux-enabled = true
_EOCONF_
cat <<_EOYML_>docker-compose.yml
version: "3"
services:
influxdb:
image: influxdb:1.8
hostname: influxdb_sample
container_name: influxdb_sample
volumes:
- ./influxdb:/var/lib/influxdb
- ./influxdb.conf:/etc/influxdb/influxdb.conf
ports:
- 8086:8086
_EOYML_
# start influxdb
docker-compose up -d
# wait until influxdb starts
while [ true ]; do
sleep 10
x=`sudo docker exec -i influxdb_sample influx --execute "show databases" 2>&1`
if [ "$?" == "0" ]; then
break
fi
done
# create sample database and sample user.
docker exec -i influxdb_sample influx --execute "create database sampledb"
docker exec -i influxdb_sample influx --execute "create user sample with password 'sample' WITH ALL PRIVILEGES"
}}
#html(</div>)
// END tabs1-2
// START tabs1-3
#html(<div id="tabs1-3">)
このシェルでは関数アプリのビルド/デプロイを行う。
関数アプリのOSはデフォルトのWindowsを使用している為、Windowsm用にビルドしている。
3_deploy_funcapp.sh
#mycode2(){{
#!/bin/bash
source 0_env.sh
rm -rf functions.zip
exefile=`cat functions/host.json | grep defaultExecutablePath | awk '{print $2}' | sed 's/"//g'`
cd functions
rm -rf $exefile
#GOOS=linux GOARCH=amd64 go build -o $exefile
#GOOS=windows GOARCH=386 go build -o $exefile
GOOS=windows GOARCH=amd64 go build -o $exefile
zip -r ../functions.zip *
cd ../
az functionapp deployment source config-zip -g $resourceGroup -n $funcAppName --src functions.zip
}}
#html(</div>)
// END tabs1-3
// START tabs1-9
#html(<div id="tabs1-9">)
このシェルはリソースの一括削除用のシェル。
やっている事はリソースグループを指定して削除しているだけ。
9_remove_resources.sh
#mycode2(){{
#!/bin/bash
source ./0_env.sh
az group delete --name $resourceGroup
}}
#html(</div>)
// END tabs1-9
#html(</div>)
// END tabs1
#html(<script>$(function() { $("#tabs1").tabs(); });</script>)
#html(</div>)
* リソースの作成 [#kef97978]
#html(<div class="pl10">)
ログイン
#myterm2(){{
az login
}}
リソース作成
#myterm2(){{
./1_create_resources.sh
}}
リソースグループ配下に作成されたリソースをAzure Portal からみると下図の通り。
#html(<div style="display: inline-block; border: 1px solid #333">)
&ref(azure_resources.png,nolink);
#html(</div>)
#html(</div>)
* VM 上に InfluxDB が正しく作成されているか確認 [#db5b14c8]
#html(<div class="pl10">)
作成したVMのPublic IPを確認
#myterm2(){{
az vm list-ip-addresses -o table
VirtualMachine PublicIPAddresses PrivateIPAddresses
---------------- ------------------- --------------------
XXXXXXXXX XX.XX.XXX.XX 10.1.1.5
}}
VMにSSH接続
#myterm2(){{
source ./0_env.sh
ssh -i ./pem/id_rsa $vmUser@確認したPublic IP
}}
InfluxDBにサンプルDBが作成されているか確認 (作成に少し時間がかかるので数分待ってから確認する)
#myterm2(){{
# dockerコンテナが起動しているか確認
sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
daffbdd72d06 influxdb:1.8 "/entrypoint.sh infl…" 10 minutes ago Up 10 minutes 0.0.0.0:8086->8086/tcp influxdb_sample
# サンプルDBが作成されているか確認
sudo docker exec -i influxdb_sample influx --execute "show databases"
name: databases
name
----
sampledb
_internal
}}
#html(</div>)
#html(</div>)
* 関数アプリの作成 [#x09d7bdd]
#html(<div class="pl10">)
// START tabs2
#html(){{
<div id="tabs2">
<ul>
<li><a href="#tabs2-1">host.json</a></li>
<li><a href="#tabs2-2">local.settings.json</a></li>
<li><a href="#tabs2-3">go_server_sample.go</a></li>
<li><a href="#tabs2-4">BlobTrigger?/function.json</a></li>
</ul>
}}
// START tabs2-1
#html(<div id="tabs2-1">)
functions/host.json
#mycode2(){{
{
"version": "2.0",
"httpWorker": {
"description": {
"defaultExecutablePath": "go_server_sample.exe"
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[1.*, 2.0.0)"
}
}
}}
#html(</div>)
// END tabs2-1
// START tabs2-2
#html(<div id="tabs2-2">)
functions/local.settings.json
#mycode2(){{
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"DB_HOST": "localhost",
"DB_PORT": "8086",
"DB_NAME": "sampledb",
"DB_USER": "sample",
"DB_PW": "sample"
}
}
}}
#html(</div>)
// END tabs2-2
// START tabs2-3
#html(<div id="tabs2-3">)
functions/go_server_sample.go
#mycode2(){{
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"math/rand"
"time"
"github.com/influxdata/influxdb-client-go"
)
type ReturnValue struct {
Data string
}
type InvokeResponse struct {
Outputs map[string]interface{}
Logs []string
ReturnValue interface{}
}
type InvokeRequest struct {
Data map[string]interface{}
Metadata map[string]interface{}
}
func blobTriggerHandler(w http.ResponseWriter, r *http.Request) {
var invokeReq InvokeRequest
d := json.NewDecoder(r.Body)
decodeErr := d.Decode(&invokeReq)
if decodeErr != nil {
http.Error(w, decodeErr.Error(), http.StatusBadRequest)
return
}
fmt.Println("The JSON data is:invokeReq metadata......")
fmt.Println(invokeReq.Metadata)
returnValue := invokeReq.Data["triggerBlob"]
returnValue := invokeReq.Data["blobData"]
invokeResponse := InvokeResponse{Logs: []string{"test log1", "test log2"}, ReturnValue: returnValue}
js, err := json.Marshal(invokeResponse)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// VM(InfluxDB)へのアクセス確認
dbHost := getEnv("DB_HOST", "localhost")
dbPort := getEnv("DB_PORT", "8086")
dbName := getEnv("DB_NAME", "unknown")
dbUser := getEnv("DB_USER", "unknown")
dbPw := getEnv("DB_PW", "unknown")
client := influxdb2.NewClient(fmt.Sprintf("http://%s:%s", dbHost, dbPort), fmt.Sprintf("%s:%s", dbUser, dbPw))
create_sample(client, dbName)
client.Close()
w.Header().Set("Content-Type", "application/json")
w.Write(js)
}
/**
* 環境変数の取得.
*/
func getEnv(envName string, defaultValue string) string {
value, exists := os.LookupEnv(envName)
if exists {
return value
} else {
return defaultValue
}
}
/**
* サンプルデータ登録(InfluxDB).
*/
func create_sample(client influxdb2.Client, dbName string) {
fmt.Printf("Write START\n")
writeAPI := client.WriteAPIBlocking("", fmt.Sprintf("%s/autogen", dbName))
// サンプルデータ登録
for i := 0; i < 5; i++ {
p := influxdb2.NewPointWithMeasurement("sample").
AddTag("tag1", "sample1").
AddTag("tag2", fmt.Sprintf("row%d", i+1)).
AddField("field1", i + 1).
AddField("field2", rand.Float64()).
SetTime(time.Now())
err := writeAPI.WritePoint(context.Background(), p)
if err != nil {
fmt.Printf("Write2 error: %s\n", err.Error())
} else {
fmt.Printf("Write2 success.\n")
}
}
fmt.Printf("Write END\n")
}
func main() {
httpInvokerPort, exists := os.LookupEnv("FUNCTIONS_HTTPWORKER_PORT")
if exists {
fmt.Println("FUNCTIONS_HTTPWORKER_PORT: " + httpInvokerPort)
}
mux := http.NewServeMux()
mux.HandleFunc("/BlobTrigger", blobTriggerHandler)
log.Println("Go server Listening...on httpInvokerPort:", httpInvokerPort)
log.Fatal(http.ListenAndServe(":"+httpInvokerPort, mux))
}}
#html(</div>)
// END tabs2-3
// START tabs2-4
#html(<div id="tabs2-4">)
functions/BlobTrigger/function.json
#mycode2(){{
{
"bindings" : [ {
"type" : "blobTrigger",
"direction" : "in",
"name" : "triggerBlob",
"name" : "blobData",
"path" : "作成したストレージコンテナ名1/{name}",
"dataType" : "binary",
"connection" : "AzureWebJobsStorage"
},
{
"type" : "blob",
"direction" : "out",
"name" : "$return",
"path" : "作成したストレージコンテナ名2/{name}",
"dataType" : "binary",
"connection" : "AzureWebJobsStorage"
} ]
}
}}
#html(</div>)
// END tabs2-4
#html(</div>)
// END tabs2
#html(<script>$(function() { $("#tabs2").tabs(); });</script>)
#html(</div>)
* 関数アプリのデプロイ [#v8360ab2]
#html(<div class="pl10">)
デプロイ
#myterm2(){{
./3_deploy_funcapp.sh
}}
#html(</div>)
* 動作確認 [#rcf31f7d]
#html(<div class="pl10">)
接続文字列の確認
#myterm2(){{
source 0_env.sh
az storage account show-connection-string --name $storageAccountName
{
"connectionString": "DefaultEndpointsProtocol=https;EndpointSuffix=core.windows.net;AccountName=xxxxxxxxxxx;AccountKey=xxxxxxxxxxxxxx"
}
}}
ストレージエクスプローラにStorageアカウントをアタッチ
#html(<div class="p20" style="border: 1px solid #333"><div class="pl20 ib">)
&ref(strexp1.png,nolink);
#html(</div><div class="pl20 ib">)
&ref(strexp2.png,nolink);
#html(</div><div class="pl20 ib">)
&ref(strexp3.png,nolink);
#html(</div></div>)
ファイルをアップロード
#html(<div style="padding: 20px; border: 1px solid #333">)
&ref(strexp4.png,nolink);
#html(</div>)
VMに接続して InfluxDB にデータが登録されているか確認
#myterm2(){{
ssh -i ./pem/id_rsa $vmUser@確認したPublic IP
sudo docker exec -i influxdb_sample influx -database sampledb -username sample --execute "select * from sample"
name: sample
time field1 field2 tag1 tag2
---- ------ ------ ---- ----
1596015616248498800 1 0.6046602879796196 sample1 row1
1596015616436070000 2 0.9405090880450124 sample1 row2
1596015616451632700 4 0.4377141871869802 sample1 row4
1596015616451632700 3 0.6645600532184904 sample1 row3
1596015616467330200 5 0.4246374970712657 sample1 row5
}}
#html(</div>)