SEEDS Creator's Blog

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) がはじまります

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 を使おう

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拡張の小技

Internet Explorerのサポートポリシー変更!? 必要な対策をまとめてみました。


はじめまして、フロントエンドエンジニアのtoyodaです。
これからどうぞよろしくお願いいたします。


さて、最近「Internet Explorer(IE)のサポートポリシーの変更」という大きな出来事がありました。
変更内容としては、2016年1月13日から各オペレーションシステム(OS)の最新版のIEのみがサポート対象となり、古いIEのサポートは終了するというもの。

しかし「サポート終了」と言っても、結局のところ「誰が」「何をしたらいいのか」が分からない方もいらっしゃると思うので、簡潔に対策が必要となるユーザーと対策方法をまとめてみました。

対策が必要なユーザー

Windows Vistaを利用されている方

「Windows Vista」における最新版のIEは、「IE9」です。
IE7、IE8を利用されている方は、「IE9」をインストールしましょう。 ※IE7、IE8は、2016年1月13日にサポートが終了しました。

Windows 7を利用されている方

「Windows 7」における最新版のIEは、「IE11」です。
IE8~IE10を利用されている方は「IE11」をインストールしましょう。 ※IE8~IE10は、2016年1月13日にサポートが終了しました。

Windows 8を利用されている方

「Windows 8」は、2016年1月13日にサポートが終了しました。
利用されている方は「Windows 8.1」へのアップデートを行いましょう。 ※Windows8.1へアップグレードすることによりIE11がプレインストールされます。

Windows Serverを利用されている方

各Windows Serverにおいても、古いIEのサポートは終了し、最新版のIEのみがサポートの対象となります。 最新版のIEにつきましては、マイクロソフトのInternet Explorer サポートポリシー変更の重要なお知らせをご参照ください。

問題点と対策方法

古いバージョンのIEには、今後脆弱性が見つかっても更新プログラムなどは適用されないため、セキュリティの面で大きな脅威にさらされることになります。 そのため、安全にインターネットを利用するためにも、IEのバージョンアップを行う必要があるのです。
IEは、新しいバージョンを自動的にインストールされるように設定することも、その設定をOFFにすることもできます。 一度OFFにしたまま忘れているということも考えられるので、今一度バージョンの確認を行いましょう。
マイクロソフトのInternet Explorer サポートポリシー変更の重要なお知らせに、IEのバージョンの確認方法や最新版IEのダウンロードページへのリンクがまとめられた表があるので、そこからダウンロードしてインストールすることができます。

各OS、IEのサポート期間

各OS、IEのサポート期間についてまとめました。 あくまでもサポートの対象になるのは「その時点での最新版のIE」なので、今後もバージョンアップはしっかり行いましょう。

Windows Vista

「Windows Vista」の延長サポート終了日は、2017年4月12日までです。 そのため「IE9」も、2017年4月12日までサポートが継続されます。

Windows 7

「Windows 7」の延長サポートは、2020年1月15日までです。 そのため、最新版のIE(執筆時点では「IE11」)も、2017年4月12日までサポートが継続されます。

Windows 8

「Windows 8」のサポートは、2016年1月13日に終了しました。 そのため、早急にWindows 8.1へのアップグレードを行いましょう。

Windows 8.1

「Windows 8.1」の延長サポートは、2023年1月11日までです。 そのため、最新版のIE(執筆時点では「IE11」)も、2023年1月11日までサポートが継続されます。

Windows 10

「Windows 10」の延長サポートは、2025年10月15日までです。 そのため、最新版のIE(執筆時点では「IE11」)、新ブラウザ「Microsoft Edge」も、2025年10月15日までサポートが継続されます。

その他

その他のサポート期間等、詳細につきましては、マイクロソフト サポート ライフサイクルからご確認いただけます。

【COALESCE関数で解決!】MySQLで値が NULL のデータを集計(count)したい

MySQL


どうも、はらぐちです。

本来は NULL を撲滅すべきなのですが、
MySQLで値が NULL のデータを、どうしても集計(count)してみたくなったもので……

というわけで、やってみました!

やりたかった事

以下のようなテーブルとデータがあるとして

テーブル data
+-------+
| value |
+-------+
| aaa   |
| aaa   |
| aaa   |
| aaa   |
| bbb   |
| bbb   |
| NULL  |
| NULL  |
| NULL  |
+-------+

それぞれの値の数を集計するために、以下のSQLを実行したら

SELECT value,count(value) FROM data GROUP BY value;

結果

+-----------+--------------+
| value     | count(value) |
+-----------+--------------+
| NULL      |            0 |
| aaa       |            4 |
| bbb       |            2 |
+-----------+--------------+

NULLのカウントは 0 になって集計できない……
これをなんとか集計したい!

解決策

COALESCE関数を使う
引数を順番に評価し、NULL と評価されない最初の式の現在の値を返し、 すべての引数がNULLの場合はNULLを返すという関数です。

例えば以下の場合

COAESCE(value,value2,'abc')

valueカラムが null の場合は value2 を返す。 value2も null の場合は 'abc' という値を返す

という動きになります。

これを踏まえて、はじめのSQLを以下のように編集

SELECT value,count(COALESCE(value,'')) FROM data GROUP BY value;

結果

+-----------+---------------------------+
| value     | count(COALESCE(value,'')) |
+-----------+---------------------------+
| NULL      |                         3 |
| aaa       |                         4 |
| bbb       |                         2 |
+-----------+---------------------------+

値が NULL のレコード数がカウントできました!
ばんざい。

【WordPress】実務で使える!おすすめプラグインをまとめてみました


WordPressでの開発を主に担当している、
フロントエンドエンジニアのトウヤマです。

後輩エンジニアのために、そろそろ「WordPress関連の情報をまとめてあげないとな」って考えていたら、
なぜか、それならいっそブログにまとめてしまおう!ということになってしまいました……

というわけで、今回は、
ここ最近で使ってみて、今後も実務で使い続けたい!便利な「WordPress おすすめプラグイン」を7つまとめてみましたのでご紹介します。

Advanced Custom Fields

Advanced Custom Fields
Advanced Custom Fields

弊社では有料版のProを使用。
とりあえず入れないと開発ができないくらいです。


Options PageFlexible Contentは多用しています。



Custom Post Type Permalinks


更新箇所が2つ以上ある場合に使用。


例えば、NEWSとブログという時にNEWSのURLは「ID」でいいけど、ブログはURLを自由に設定したい!というときに便利。
カスタム投稿タイプのページャーまで設定してくれるのもありがたい。


※Custom Post Type Permalinks 1.0.0以上で下記の設定には注意。 Custom Post Type Permalinks 1.0.0以上で発生する、カスタム投稿へのパーマリンクが404になってしまう現象について。

Category Order and Taxonomy Terms Order


Category Order and Taxonomy Terms Order
カテゴリが多い場合によく活躍します。


カテゴリ一覧の順番を「登録順ではなくその都度入れ替えたい!」という依頼がよくあります。そういうときには、このプラグインで対応することが多いです。

AJAX Thumbnail Rebuild


AJAX Thumbnail Rebuild
サムネイルを複数作成する場合。


開発途中でサムネイルを作成しなおすような場合に使います。

AddQuicktag


AddQuicktag
◎更新する方がHTMLを書けない場合。


独自で作ったスタイルを登録し、更新者はボタンを押してタグを押すだけで、 入力が可能になります。

MW WP Form


MW WP Form
コンタクトフォームを作成する場合。


確認画面付きのフォームが作成されるプラグイン。
バリデーションの種類も豊富です。

MW WP Formの注意点については、過去にブログで書いてます。こちらも合わせてどうぞ。 [article link=3530]

Any Mobile Theme Switcher


Any Mobile Theme Switcher
スマホ対応である場合。


ユーザーエージェントの判定でテンプレートの切り替えが可能になります。

まとめ

プラグインを入れたら、予期せぬバグが発生したり、ページが重たくなった!なんてことも発生します。

最低限必要なプラグインのみインストールして、シンプルで分かりやすいWordPressの設計を心がけたいですね。






Vagrantのboxサイズを拡張する

提供されているboxが8GBしかなかったので拡張したのですが、結構大変だったのでメモします。

ディスクの拡張

boxから普通にインスタンスを作成。 インスタンスを作成したらシャットダウンして作業を行います。

VirtualBoxではディスクサイズが可変のタイプは .vdiなのですが、 Vagrantのboxとできるディスクタイプはvmdkとなります。 まずは、現在のvmdkディスクをクローンしてvdi形式のディスクを作成します。

その後、カレントディレクトリを作成した仮想サーバのディスクがある所まで移動して

VBoxManage clonehd "box-disk1.vmdk" "clone-box-disk1.vdi" --format vdi

クローンしたディスクの容量を拡張します。ここでは20GBにしたいと仮定して20480を設定しています。 (20(GB) * 1024(MB) = 20480)

VBoxManage modifyhd clone-box-disk1.vdi --resize 20480

次に、ディスク拡張されたvdiをvmdkにクローンします。

VBoxManage clonehd "clone-box-disk1.vdi" "box-disk2.vmdk" --format vmdk

拡張したディスクを差し替えます。 この作業は、VirtualBoxから行ってもいいかもしれません。 --port 0 --device 0 の部分はbox-disk1.vmdkが入っていたものを指定します。 ちなみに、server_default_1448874918650_80404 は仮想サーバー名です。

VBoxManage storageattach server_default_1448874918650_80404 --storagectl "SATA" --port 0 --device 0 --type hdd --medium box-disk2.vmdk

この設定を行った後、起動してみて無事に起動すればOKです。 確認できたら、またまたシャットダウンします。

パーティション操作

現在ディスクは20GBに拡張しましたが、パーティションは8GBまでしか使用されていない状態です。 パーティションを操作して、8GBを20GBに拡張します。

新たに作成された box-disk2.vmdk を適当な仮想サーバにアタッチします。 アタッチ後、lsblkコマンドでディスクの様態をチェック。

# lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda    202:65   0   8G  0 disk /
└ sda1 202:145  0   1G  0 part 
└─sda2 202:145  0   8G  0 part 
sdb    202:144  0  20G  0 disk 
└ sdb1 202:145  0   1G  0 [SWAP]
└─sdb2 202:145  0   8G  0 part 

今回くっつけたものはsdbとして認識されていました。 partedでパーティション操作を行っていきます。

ない場合は、 yum install parted か apt-get install partedでインストールします。

# parted /dev/sdb
GNU Parted 2.1
/dev/sdb を使用
GNU Parted へようこそ! コマンド一覧を見るには 'help' と入力してください。

表記をセクターに変更します。

(parted) unit s

現在の情報を表示します。

(parted) print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 41943040s
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start     End        Size       Type     File system     Flags
 1      2048s     1953791s   1951744s   primary  linux-swap(v1)
 2      1953792s  15988735s  15986688s  primary   ext4            boot

この情報はあとで使用するため、メモしておきましょう。 今回は、特にNumber2の行が重要になります。

次に、パーティションを削除します。

(parted) rm 2    

パーティションを作成します。

(parted) mkpart
Partition name? []? 
File system type? [ext2]? ext4
Start? 1953792s
End? 100%

パーティションサイズ以外は、元のパーティションと同じになるように修正します。

(parted) set 2 boot on
(parted) set 2 LBA off

ここまでできたら、EndとSize以外は元と同じになっているか確認します。

(parted) print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 41943040s
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start     End        Size       Type     File system     Flags
 1      2048s     1953791s   1951744s   primary  linux-swap(v1)
 2      1953792s  41943039s  39989248s  primary  ext4            boot

終了!

(parted) quit

20GBに拡張されていることを確認します。

# lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda    202:65   0   8G  0 disk /
└ sda1 202:145  0   1G  0 part 
└─sda2 202:145  0   8G  0 part 
sdb    202:144  0  20G  0 disk 
└ sdb1 202:145  0   1G  0 [SWAP]
└─sdb2 202:145  0  19G  0 part

念のため、ディスクチェックをかけましょう。

e2fsck -f /dev/sdb2

ここまでできたら、適当な仮想サーバをシャットダウンしてディスクを外します。

パーティション拡張したディスクで起動

インスタンスを起動します。

resize2fs /dev/sda2

ここで、サイズが20GBに拡張されたら完了です。

box作成

あとはVagrantfileがあるディレクトリでboxを作成して終了です。

vagrant package