SEEDS Creator's Blog

読者です 読者をやめる 読者になる 読者になる

社内WindowsサーバーをAWSに移行する話1

AWS クラウド インフラ EC2

経緯

シーズでは、見積書・請求書の発行などに社内にWindowsサーバーを立て弥生販売を使っていました。

複数拠点から複数人が同時に使うためネットワーク版5ライセンスです。

社内にサーバーを置くメリットとして、

*ギガビットLANでの高速アクセス

*社外との通信が発生しないためセキュリティーが高い

*売るほどサーバーラックがあるのでコストはあまり気にならない

といった利点がありましたが サーバー筐体費用、Windowsサーバー、SQLライセンスなどの初期費用(トータル約40万※構築費用は自前のため無料)がかかるうえ 毎年のライセンス更新や筐体保守費用、また毎月の電気代・空調費用も馬鹿になりません。 さらに、場所も取るし、空調にも気を使うし、なにかとメンテも大変なのでクラウドに行きたいと考えておりました。

要件

*AWSで24時間365日稼働(ただし夜間は止めるかも)

*OSはWindowsサーバー2012

*弥生販売ネットワーク版5ライセンスを動かす

*シーズ社内とVPNでセキュアに常時接続

特に最後のVPNで社内とシームレスかつセキュアに接続が一番重要ですね。

これらの要件をAWSでこのように準備しました。

AWS構成

*ec2インスタンス(Windows2012) t2.small $36.60

*EBS45GB $5.40

*VPC VPN接続 $36

合計 約78ドル=約8,424円 (1ドル108円)

f:id:panmizser:20161121214003p:plain

EBSボリューム、転送量、EIP、IOなど少額の従量制がありますが、それらを含んだとして、約8,500円です。

移行してどうだったか

結論としては、最高でした。

まず費用としては

サーバー1台をデータセンターでハウジング(月50,000相当,OSライセンス諸々込)として、それが月8,500円ポッキリになりました。(83%DOWNです!)

また弥生を使わない夜間止めることで更にコストダウンも可能です。

次に、回線速度やアプリの使用感ですが、こちらも全く問題ありません。

インスタンスタイプは最初 large → medium と様子を見ていきましたが最終的にはsmallまで落としても操作感に問題ありませんでした。

(ただし弥生インストール時はlargeでやったほうが効率がいいです)

回線速度は、AWSの提供するVPNサービスを利用することで全くストレスを感じません。 (以前、WindowsインスタンスからPPTPで会社ルーターに繋げたりしたことがありましたが、その場合、一応つながりますが、結構遅かったです。)

次回は、これらAWSの設定、社内VPNルーターの設定を含め詳しく解説していきたいと思います。

AWS 中国(北京)リージョンの利用でハマった所をご紹介します

f:id:cs_sonar:20161118201515p:plain

原口です。

AWS China(Beijing) [中国(北京)リージョン] を触らせていただく機会がありまして触ってみた感じをお伝え致します。

中国リージョンは結構前から追加されていますが、通常のアカウントのリージョン一覧には出てきません。

中国リージョンを利用するには他のリージョンとは異なり、専用のアカウントを作成しなければ利用できません。

基本情報

[リージョン]
cn-north-1

[アベイラビリティゾーン]
cn-north-1a
cn-north-1b

無許可でのポート80 / 443 / 8080 のポートによるページ公開ができない

中国では、ウェブサイトを勝手に公開できないようで、AWS側にて上記のポートは接続できないようになっています。ICPライセンスというものを登録しなければ公開できません。基本的にはAWSアカウントにライセンスが紐づいているようでライセンスが紐づけば公開が可能となるようです。

注意点として、ELBやEC2などでは接続できないときはブラウザくるくるですが、s3の接続できないエラーは401レスポンス(UnauthorizedAccess)を返します。401(UnauthorizedAccess)はs3のgetObjectがない場合でも出すのでICPライセンスが原因である、、、という判別がつきにくいところでハマりやすいので注意です。

ちなみにELBやEC2は待ち受けポートを適当なポートに変えてやれば無理やり公開する事は可能でした。

ARNやドメインネームが変わっているので注意

ドメイン名は ec2.amazonaws.comec2.amazonaws.com.cnと、完全に別のドメインになっていますし、 ARNもarn:awsarn:aws-cn と変わっているので注意が必要です。

cloudformationやterraformのテンプレートなど既存のノウハウを生かそうと流用すると arnを直接指定している部分などではまります。

ないサービスが多い

以下の一覧でも確認できます

リージョン - グローバルインフラストラクチャ | AWS

今回は

  • route53
  • lambda
  • RDS(Aurora)

あたりがなかったので困りました。

既存リージョンからAMIはコピーできない

完全別サービスみたいな感じですので、既存のリージョンで作成していたAMIなどを共有する事ができません。
これはかなりつらかったので・・・以下のようにディスクイメージを作成してコピーする方法を用いました。

インスタンスコピーの手順

AmazonLinux (HVM)を使用した場合。

移行したいAMIのsnapshotからVolumeを作成し、適当なインスタンスにアタッチします。
アタッチしたボリュームをddコマンドでイメージファイル化します。
(/dev/xvdfとしてアタッチした場合)

dd if=/dev/xvdf of=image.img bs=1M

イメージファイルを中国側に作成したインスタンスに転送します

scp -i chn.pem ./image.img ec2-user@***.***.***.***:/home/ec2-user/

中国側インスタンスで空のVolumeを作成し、アタッチします。
この時、空のVolumeサイズはコピー元のVolumeサイズと同じにしてください。

このアタッチした空Volumeにddコマンドでイメージファイルを書き込みます
(/dev/xvdfとしてアタッチした場合)

dd if=./image.img of=/dev/xvdf bs=1M oflag=direct

※独自OSを使っている場合などはこの際にboot関連の項目を書き換えたりしないといけないかもしれないですがAmazonLinuxでは特に修正なくできました。

Volumeをデタッチしてsnapshotを作成します。
そしてsnapshotからAMIを作成。
この際のパラメータはHVM(Hardware-assited VM)に。
カーネルIDなどはデフォルトでOKです。

これで、既存リージョンのAMIを北京リージョンに持ってくる事ができた事になります。

このとき、作成したAMIを北京リージョンで立ち上げるとうまく立ち上がってこない事があります。
マネージメントコンソールからget_systemlogで見ると以下のようなのが出てる場合・・・

http://packages.ap-northeast-1.amazonaws.com/2016.09/main/20160901f6a8/x86_64/repodata/repomd.xml?instance_id=i-******************************&region=ap-northeast-1: [Errno 12]
Timeout on http://packages.ap-northeast-1.amazonaws.com/2016.09/main/20160901f6a8/x86_64/repodata/repomd.xml?instance_id=i-******************************&region=ap-northeast-1: (28, 'Connection timed out after 10000 milliseconds')
Trying other mirror.`

Amazon Linuxはcloud-initでyum update(セキュリティのみのもの)が走るのですがそれが途中で止まっているのが原因です。
止まってしまった場合は再起動すればOKです。
これはたぶん以下の変数が書き換わっていないからではないかと思います。

/etc/yum/vars/awsdomain
/etc/yum/vars/awsregion

同様にRDSのスナップショットも移動できないです。こっちはダンプ持ってく感じになりますね

よく接続切れる、またはめちゃくちゃ遅くなったりする

南北問題と言うらしいです・・・。

(参考) qiita.com

【デーモン化で解決!】WEBrickでRedmineを立ち上げるとpost時に真っ白になる

Redmine WEB プログラミング

f:id:seeds-std:20161108200910p:plain
どうも、はらぐちです。

今回は、 「WEBrickでRedmineを立ち上げると、なぜかpostした時だけ真っ白になってしまう」という件について、 解決法をご紹介します。 rails力が足りなくてハマった感じですが……

経緯

シーズではプロジェクト管理ソフトのひとつにRedmineを使用しているのですが、 最近、古いサーバー上のRedmineを、最新OSを搭載した新しいサーバーに移行することになりました。

1.データをそのままごっそり持ってきて、
2.mysqldumpをリストア、
3.rbenvで該当バージョンをそろえて、
4.gemも同じバージョンを入れていったのですが、

どうしても、Passengerだけがうまく使えない……

そこで、WEBrickで起動し、apacheのリバースプロキシ経由で参照するように設定をしてみました。

おおむねこれでうまく動いていたのですが、 なぜかPostした時だけ真っ白なページになる状態に…… (※真っ白なページにはなりますが、更新自体はされている。)

解決法

いろいろ調べてみた結果、 そのままフォアグランドで起動するとうまくいくのにバックグラウンド実行するとうまくいかない事がわかりました。 そこからはWEBrickのドキュメントなどを参照して、-dオプションでデーモン化で立ち上げる事が可能と判明。 以下のような起動方法で問題なく動作しました

/path/to/redmine/script/server -d -e production

デーモン化は知りませんでしたが、バックグラウンド実行だと何故こんな動きになるんでしょうね? ひとまずはデーモン化で解決しました!

AWSとVPN接続を張ったけど転送量はどうなの?

AWS インフラ

blog_img_4285
先日、CTO原口くんにお願いして、シーズ社内にあったWindowsサーバーをAWSに移行しました。 AWSにWindowsServerOSインスタンスを立てて、シーズからはVPN(IPsec接続)でシームレスかつセキュアに社内ネットワークを拡張したイメージです。 その話はまた別にするとして、その時、「AWSでファイルサーバーをやるのってどうなの?使えるの?」という話になったので検証をちょこっとやってみました。

ファイルサーバー自体は、EC2.linuxでsambaを立てるなり、WindowsServerでファイルサーバーをするなりして簡単に実装できますが、一番のネックは転送スピードということになりますよね。

そこを検証してみました。

環境

社内LAN環境はすべてギガビット回線 =>社内ファイルサーバーにはギガビット転送ができる(1000Mbps=125MB/s)

インターネットともギガビットの専用線を引いている。 インターネット接続はRTX1200を利用している。VPNルーターとしても利用している。 AWS VPC VPN接続にはRTX1200からIPSECで接続している。

社内、社外インターネットともギガビットのため、理論上はすべてギガで通信できる環境です。

社内ファイルサーバーの転送スピード

アップロード
inG

アップロード(パソコンから社内ファイルサーバー)スピードです。 だいたい平均的に32.5MB/s(260Mbps) となっているので、理論値の26%ぐらいしかでていませんが、通常利用ではまったく問題のない速さだと思います。

ダウンロード
outG

ダウンロード(社内ファイルサーバーからパソコン)はさらに早くなりました。 57.2MB/s(457.6Mbps)! これ以上求める必要はないでしょう。というレベルだと思います。

AWS上VPN接続

アップロード
in

アップロード(パソコンからAWS-VPNファイルサーバー)転送スピードは6.82MB/s(54Mbps)です。 スピードはかなり落ちましたが、実用性ではどうでしょうかね。 一昔前の100Mbps環境時代の速度というところでしょうか。 今のギガに慣れているとストレスかもしれませんが、使えなくはなさそうですね。

ダウンロード
out

ダウンロード(AWS-VPNファイルサーバーからパソコン)は逆に遅くなりました。 3.68MB/s(29.44Mbps)で止まっています。 出だしは早かったのですが、なにか制限が入っているのでしょうかね。 とはいえ、まあ実用的に全く使えないわけではなさそうです。

結論

AWS-VPNは100Mbpsで繋がっていた時代の速度ではあるが、使えないことはなさそう。 しかし、転送量でも課金されるので注意が必要。(アップロードは無料) 1000GB = $139.86 100GB = $13.86 10GB = $1.26

Terraformを使ってみました

AWS AWS Terraform インフラ

blog_img_4238
Terraformは、あらかじめインフラ構成を設定ファイルに記述して、 クラウド環境に適用・管理するツールです。 Vagrantなどを開発しているHashiCorpのツールになります。

AWSだけではなく様々なプロバイダに対応していますが、AWSで使用してみました。

インストール

Linuxサーバに入れてみました。 ダウンロードしてきて展開するだけで使えます。

cd /opt
mkdir terraform
cd terraform
wget https://releases.hashicorp.com/terraform/0.6.16/terraform_0.6.16_linux_amd64.zip
unzip terraform_0.6.16_linux_amd64.zip

パスを通すと便利でした。

vi ~/.bashrc

export PATH=/opt/terraform:$PATH

AWS側事前準備

  • AWSアカウント作成
  • terraformで触るリソースをいじれるポリシーを付与したIAMユーザを作成

terraformの動作イメージ

必ず使うコマンドは以下の三つ

terraform plan dry-runです。設定ファイルの記述ミスなどをチェックしてくれます

terraform apply 実行です。設定ファイル通りの構成を実装してくれます

terraform destroy 作成した構成を削除してくれます

terraform初期設定

まずはAWSアクセスキーなどの設定。 terraformは「terraform.tfvars」というファイルがカレントディレクトリにあると そちら中を読んで変数として取り扱ってくれます。 注意点として、このファイルでは配列は設定できないようです。

このようにアクセスキーなどを変数として設定しておく事ができます。

file : terraform.tfvars

#####################################
#Variable Settings
#####################################
#AWS Settings
access_key = "xxxxxxxxxxxxxxxxxxx"
secret_key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
region = "ap-northeast-1"

このファイルは.gitignoreとかでリポジトリでは管理しないようにします。

次のこの変数をtfファイル内で使用できるようにvariableで定義します。 上記のterraform.tfvarsの記述内容は環境変数に入るので、それを定義します。

file : variables.tf

#####################################
# Variable Settings
#####################################
#AWS Settings
variable "access_key" {}
variable "secret_key" {}
variable "region" {}

上記で設定した変数を使ってterraformのAWS設定を記述します

file : aws.tf

provider "aws" {
    access_key = "${var.access_key}"
    secret_key = "${var.secret_key}"
    region = "${var.region}"
}

以上で初期設定は終わり。 terraform planやterraform applyをするとカレントにある *.tf ファイルをすべて読み込んでくれます。 また、一度applyを実行すると、terraform.tfstateというファイルが作成されます。 terraform.tfstate は、Terraform が管理しているリソースの状態が保存されているのだと思います。 おそらく次回実行時にこちらのstateファイルとの差分でどのようなAPIを投げるか決定しているのだと思います。

VPCを作成してみる

実際にいろいろ設定をしてみたので紹介です。 以下は

・VPCの作成
・サブネット二つ作成(いずれもパグリックサブネット)
・DHCPオプションの作成
・インターネットゲートウェイ作成
・ルーティングテーブル作成

を行っています。

file aws_vpc.tf

#####################################
# VPC Settings
#####################################
resource "aws_vpc" "vpc_main" {
    cidr_block = "${var.root_segment}"
    enable_dns_support = true
    enable_dns_hostnames = true
    tags {
        Name = "${var.app_name}"
    }
}

#####################################
# DHCP option sets
#####################################
resource "aws_vpc_dhcp_options" "vpc_main-dhcp" {
    domain_name = "${var.dhcp_option_domain_name}"
    domain_name_servers = ["AmazonProvidedDNS"]
    tags {
        Name = "${var.app_name} DHCP"
    }
}
resource "aws_vpc_dhcp_options_association" "vpc_main-dhcp-association" {
    vpc_id = "${aws_vpc.vpc_main.id}"
    dhcp_options_id = "${aws_vpc_dhcp_options.vpc_main-dhcp.id}"
}

#####################################
# Internet Gateway Settings
#####################################
resource "aws_internet_gateway" "vpc_main-igw" {
    vpc_id = "${aws_vpc.vpc_main.id}"
    tags {
        Name = "${var.app_name} igw"
    }
}

#####################################
# Public Subnets Settings
#####################################
resource "aws_subnet" "vpc_main-public-subnet1" {
    vpc_id = "${aws_vpc.vpc_main.id}"
    cidr_block = "${var.public_segment1}"
    availability_zone = "${var.public_segment1_az}"
    tags {
        Name = "${var.app_name} public-subnet1"
    }
}
resource "aws_subnet" "vpc_main-public-subnet2" {
    vpc_id = "${aws_vpc.vpc_main.id}"
    cidr_block = "${var.public_segment2}"
    availability_zone = "${var.public_segment2_az}"
    tags {
        Name = "${var.app_name} public-subnet2"
    }
}

#####################################
# Routes Table Settings
#####################################
resource "aws_route_table" "vpc_main-public-rt" {
    vpc_id = "${aws_vpc.vpc_main.id}"
    route {
        cidr_block = "0.0.0.0/0"
        gateway_id = "${aws_internet_gateway.vpc_main-igw.id}"
    }
    tags {
        Name = "${var.app_name} public-rt"
    }
}

resource "aws_route_table_association" "vpc_main-rta1" {
    subnet_id = "${aws_subnet.vpc_main-public-subnet1.id}"
    route_table_id = "${aws_route_table.vpc_main-public-rt.id}"
}

resource "aws_route_table_association" "vpc_main-rta2" {
    subnet_id = "${aws_subnet.vpc_main-public-subnet2.id}"
    route_table_id = "${aws_route_table.vpc_main-public-rt.id}"
}

この例の通り、作成したリソースのIDなどは他のリソースで読み込む事が可能です。 一番上で作成したVPCのIDは以下のように取得できます。

${aws_vpc.vpc_main.id}

セキュリティグループを作成してみる

特筆するところはないですが、ソース元をセキュリティグループにする例も載せてみました。 ソース元を配列にする事で複数の設定ができます。 terraform.tfvarsに配列が指定できたらいいんですが・・・

resource "aws_security_group" "lb_sg" {
    name = "${var.app_name} Load Balancer"
    vpc_id = "${aws_vpc.vpc_main.id}"
    ingress {
        from_port = 80
        to_port = 80
        protocol = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
    }
    egress {
        from_port = 0
        to_port = 0
        protocol = "-1"
        cidr_blocks = ["0.0.0.0/0"]
    }
    description = "${var.app_name} Load Balancer"
}

resource "aws_security_group" "web_sg" {
    name = "${var.app_name} WEB Server"
    vpc_id = "${aws_vpc.vpc_main.id}"
    ingress {
        from_port = 22
        to_port = 22
        protocol = "tcp"
        cidr_blocks = ["${var.root_segment}"]
    }
    ingress {
        from_port = 80
        to_port = 80
        protocol = "tcp"
        cidr_blocks = ["${var.root_segment}"]
        security_groups = ["${aws_security_group.lb_sg.id}"]
    }
    egress {
        from_port = 0
        to_port = 0
        protocol = "-1"
        cidr_blocks = ["0.0.0.0/0"]
    }
    description = "${var.app_name} WEB Server"
}

RDSの作成

RDS用のサブネットグループを作成する部分が少しはまりました

resource "aws_db_instance" "default" {
  allocated_storage       = 5
  identifier              = "${var.rds_name}"
  engine                  = "${var.rds_engine}"
  engine_version          = "${var.rds_engine_version}"
  instance_class          = "${var.rds_instane_type}"
  name                    = "${var.rds_db_name}"
  username                = "${var.rds_user}"
  password                = "${var.rds_pass}"
  db_subnet_group_name    = "${aws_db_subnet_group.default.id}"
  parameter_group_name    = "${var.rds_parameter_group}"
  vpc_security_group_ids  = ["${aws_security_group.mysql_sg.id}"]
  backup_retention_period = "1"
  backup_window           = "17:08-17:38"
  storage_type            = "gp2"
  maintenance_window      = "Sat:13:38-Sat:14:08"
  multi_az                = false
  apply_immediately       = true
  publicly_accessible     = true
}

resource "aws_db_subnet_group" "default" {
  name = "default-${aws_vpc.vpc_main.id}"
  description = "Our main group of subnets"
  subnet_ids = ["${aws_subnet.vpc_main-public-subnet1.id}","${aws_subnet.vpc_main-public-subnet2.id}"]
}

s3の作成

ポリシーを設定する場合は外部に用意したポリシーのjsonを読み込ませて設定してみました。

resource "aws_s3_bucket" "b" {
    bucket = "${var.s3_bucket_name}"
    acl = "private"
    policy = "${file("s3_bucket_policy.json")}"
}

elbの作成

# Create a new load balancer
resource "aws_elb" "default" {
  name = "${var.elb_name}"
  security_groups = ["${aws_security_group.lb_sg.id}"]
  subnets = ["${aws_subnet.vpc_main-public-subnet1.id}","${aws_subnet.vpc_main-public-subnet2.id}"]

  listener {
    instance_port = 80
    instance_protocol = "http"
    lb_port = 80
    lb_protocol = "http"
  }

  health_check {
    healthy_threshold = 2
    unhealthy_threshold = 2
    timeout = 5
    target = "HTTP:80/index.html"
    interval = 30
  }

}

dynamoDBのテーブル作成

range_keyがソートキーになります

resource "aws_dynamodb_table" "users" {
    name = "${var.dynamodb_prefix_name}.users"
    read_capacity = 1
    write_capacity = 1
    hash_key = "id"
    range_key = "username"
    attribute {
      name = "id"
      type = "N"
    }
    attribute {
      name = "username"
      type = "S"
    }
}

Nが数値、Sが文字列、Bがバイナリです。

elasticacheの作成

redisを作成してみた

resource "aws_elasticache_cluster" "redis" {
    cluster_id = "${var.cache_cluster_name}"
    engine = "redis"
    node_type = "${var.cache_instane_type}"
    port = 6379
    num_cache_nodes = 1
    parameter_group_name = "${var.cache_parameter_group}"
    security_group_ids = ["${aws_security_group.redis_sg.id}"]
    subnet_group_name = "${aws_elasticache_subnet_group.subnet.id}"
}

resource "aws_elasticache_subnet_group" "subnet" {
    name = "${var.cache_cluster_name}"
    description = "${var.cache_cluster_name}"
    subnet_ids = ["${aws_subnet.vpc_main-public-subnet1.id}","${aws_subnet.vpc_main-public-subnet2.id}"]
}

IAMロールの作成

いろいろ躓きました・・・。 IAMロールの作成の場合、

  • ロールの作成
  • 管理ポリシーをアタッチ
  • インラインポリシーをアタッチ

という形なのですが、terraformではポリシーのリソース作成でIMAロールを指定します。 また、IAMロール作成時、「信頼されたエンティティ」のID プロバイダーとして amazonを追加しないと使えないところがはまりました。(普段意識していなかったので・・・)

IAMロールの作成。 信頼されたエンティティにec2.amazonaws.comを設定しています。

resource "aws_iam_role" "sample_role" {
    name = "${var.sample_iam_role_name}"
    assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF
}

作成したロールに管理ポリシーをアタッチ 管理ポリシーの場合はポリシーarnを直接記述します。

resource "aws_iam_policy_attachment" "dynamodb" {
  name = "AmazonDynamoDBFullAccess"
  roles = ["${aws_iam_role.sample_role.id}"]
  policy_arn = "arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess"
}

作成したロールにインラインポリシーをアタッチ インラインポリシーの場合はpolicyのjsonを直接記述します

resource "aws_iam_role_policy" "sqs_policy" {
  name = "AmazonSQSFullAccess"
  role = "${aws_iam_role.sample_role.id}"
  policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "sqs:*"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}
EOF
}

EC2インスタンスの作成

作成したIAMロールを関連付けたインスタンスを作成します。 ついでに固定IPもつけてみました。 インスタンスに関連づける場合は「aws_iam_instance_profile」でまず インスタンスプロフィールを作成する必要があるようです。

こちらのリソースで作成したnameの値をaws_instanceのiam_instance_profileで指定すれば うまくいきました。

resource "aws_iam_instance_profile" "sample_role" {
    name = "sample_role"
    roles = ["${aws_iam_role.sample_role.name}"]
}

resource "aws_instance" "sample" {
    ami = "${var.sample_ami}"
    instance_type = "t2.micro"
    vpc_security_group_ids = ["${aws_security_group.sample_sg.id}"]
    subnet_id = "${aws_subnet.vpc_main-public-subnet1.id}"
    iam_instance_profile = "sample_role"
    associate_public_ip_address = true
    key_name = "${var.key_pair_name}"
    tags {
        Name = "${var.sample_tag_name}"
    }
    root_block_device {
        delete_on_termination = "true"
    }
}

# 固定IPもつけてみる
resource "aws_eip" "lb" {
    instance = "${aws_instance.sample.id}"
    vpc      = true
}

AutoScalingの設定

こちらはあまりうまくいってないので使ってないですが、うまくいかなかったりうまくいったりします。

resource "aws_launch_configuration" "as_conf" {
    name_prefix = "${var.launch_config_name}"
    image_id = "${var.sample_ami}"
    instance_type = "t2.micro"
    iam_instance_profile = "api_role"
    security_groups = ["${aws_security_group.sample_sg.id}"]
    key_name = "${var.key_pair_name}"
    associate_public_ip_address = true

    lifecycle {
        create_before_destroy = true
    }

    root_block_device {
        volume_type = "gp2"
        volume_size = "24"
        delete_on_termination = true
    }
}

resource "aws_autoscaling_group" "sample" {
    name = "${var.auto_scaling_group_name}"
    vpc_zone_identifier = ["${aws_subnet.vpc_main-public-subnet1.id}","${aws_subnet.vpc_main-public-subnet2.id}"]
    launch_configuration = "${aws_launch_configuration.as_conf.name}"
    max_size = 0
    min_size = 0
    desired_capacity = 0
    default_cooldown = 300
    health_check_grace_period = 300
    health_check_type = "EC2"
    load_balancers = ["${aws_elb.default.name}"]
    force_delete = true
    tag {
        key = "Name"
        value = "${var.api_tag_name}"
        propagate_at_launch = true
    }
}

root_block_deviceやelb_block_deviceを使うと以下のようなエラーが出てしまう為、現在はあまり使用していません。

Error refreshing state: 1 error(s) occurred:

* aws_launch_configuration.as_conf: Invalid address to set: []string{"root_block_device", "0", "encrypted"}

こちら、お分かりにな方がいたらご教授頂きたいです・・・

怖いところ

「割と軽微な修正」だと思って修正すると インスタンスが削除されたりする可能性があります。

例えばインスタンスのIAMロールを変更はインスタンスの立ち上げ時にしか変更できないのですが terraformでIAMロールを変更してterraform applyすると、インスタンスは削除されて新規作成される、、 という動作となります。

これはどう考えてもterraformが正しい動作をしているのですが 本番環境などでterraform applyを実行するのは怖すぎるな・・・と思いました。

個人的なTerraformの使いどころ

おなじような機能にAWS公式サービスのCloudFormationがありますが、 構成を管理してしまうところが嫌だと感じていました。

つまり初回構築だけ実行したい、、、という事ができないわけです。 もちろんTerraformにも構成管理をする機能はありますが プロバイダ非依存である為、このあたりは柔軟に対応できます。

あと設定ファイルがjsonではないのでコメントなども書けるのもいいですね。 InteliJにはterraform用のプラグインもありますので 設定ファイル作成もしやすいです。

というわけで個人的には 「初期構築用ツール」、もしくは「開発環境構築ツール」として利用していこうと思います。 destroyでサクッと全部消えるのはとても便利

逆に構成を管理させたい場合は WEB GUIにて変数をフォームで渡して実行、、って事ができるので やはりCloudFormationの方がいいかなぁと感じています。 (AutoScaleはCloudFormationを使う事が多いです)

情報セキュリティマネジメント試験(SG) がはじまります

html IT その他

blog_img_4185
こんにちは。

IPA(情報処理推進機構)の情報処理技術者試験に新しい試験区分が追加されましたね。 その名も、、、

情報セキュリティマネジメント試験(SG) [ Information Security Management Examination ]

じゃじゃーん、、すごく難しそうな試験名(笑)

対象者像は以下のとおりです。

情報システムの利用部門にあって、情報セキュリティリーダとして、部門の業務遂行に必要な情報セキュリティ対策や組織が定めた情報セキュリティ諸規程(情報セキュリティポリシを含む組織内諸規程)の目的・内容を適切に理解し、情報及び情報システムを安全に活用するために、情報セキュリティが確保された状況を実現し、維持・改善する者

 

  • 春期・秋期実施
  • 試験時間・出題形式・出題数(解答数)

内容みてると

ITパスポート <= 情報セキュリティマネジメント試験 < 基本情報処理

みたいな位置づけですかね。最近はこども向けのプログラミング教室があったり、国も施策として考えているみたいですし、試験区分が増えて、IT業界が盛り上がって行くのはいいことですね。これでブラックなイメージが払しょくされればいいのですが(涙)個人的にはLPIC系の国家資格ができればいいのになぁと思う今日この頃です。 今年も何か受験したいと思います。(これは受けないけど(笑))

■参考 https://www.jitec.ipa.go.jp/1_11seido/sg.html https://www.jitec.ipa.go.jp/sg/

FuelPHP はじめました。複雑な 独自validation 設定には Closure を使おう

php プログラミング

Fuel PHP


ども。Webエンジニアの ishino です。

最近 FuelPHP を触る機会が増えてきたのていたので、学んだことを少しづつに記事にしていこうと思います。
珍しく、真面目にプログラムのこと書きましたので、よろしくお願いします。

FuelPHPとは?

FuelPHPはPHPで書かれたオープンソースのHMVCパターンを使うフレームワークです。
フレームワークは基本的な機能が揃っているので、高速にアプリケーションを開発することができます。
PHPのフレームワークにはたくさんの種類がありますが、中でもFuelPHPは比較的新しく、軽量で中規模のアプリケーションの開発に向いていると言われています。

validationの基本

FuelPHPは、POSTされた値の内容に対して、かんたんにvalidationをかけることができます。 必須項目の入力チェックは

$val = Validation::forge();
$val->add('name', '名前')
    ->add_rule('required');

でOKです。

ただ、複雑なvalidationチェックを行うには、自分で設定しなければなりません。 はじめは、この書き方が分からず、調べましたのでここに書いておきます。

複雑な 独自Validation 設定には Closure を使う

$option['name'] = 'hoge';
$val = Validation::forge();
$val->add('name', '名前')
    ->add_rule(['validation_name' => function($name) use ($option) {
        if ($name != $option['name']) {
            Validation::active()->set_message('validation_name', '「:label」が正しくありません');
            return false;
        } else {
            return true;
        }
}]);

このようにClosureを使うことで、独自validationを記述できるようになります。

また、functionの引数にはPOSTの値が、
その他でvalidtionで使うパラメータはuseで渡すことも可能です。

また、独自Validationを複数設定する時は、Closureに名前を設定しないとエラーメッセージが上書きされてしまうので、
上のコードのように名前を設定しておくといいですよ。


◎下の記事が参考になりました。 FuelPHPのValidationにクロージャを使う FuelPHPを更に使ってみて使えるなと思った拡張ValidationRuleの書き方とCore拡張の小技