DRYな備忘録

Don't Repeat Yourself.

aws cli を使ったVPCの新規作成からEC2へのsshまで

まずWebコンソールでゴールの確認

  1. VPCの作成
  2. Subnetの作成
  3. InternetGatewayの作成
  4. VPCに上記3のInternetGatewayをアタッチ
  5. SubnetのRouteTableに上記3のInternetGatewayに紐付いたルールを追加
  6. 上記1のVPC内で、上記2のSubnet配下に、EC2インスタンスをつくる
  7. (適宜、必要があればSecurityGroupのInboundをいじったりする)
  8. sshできる。

ここまでやった。できた。

% ssh -i ~/Desktop/otiai10.tokyo.pem ec2-user@54.249.68.183

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
[ec2-user@ip-10-0-0-11 ~]$ exit
logout
Connection to 54.249.68.182 closed.

これをゴールとして、以下、これをaws cliだけでやっていく。

まずはお掃除する。

% aws ec2 describe-vpcs \
  --filters Name=tag:Name,Values=otiai10-test-web \
  | jq .Vpcs[].VpcId

% aws ec2 delete-vpc --vpc-id vpc-374f0d50

An error occurred (DependencyViolation) when calling the DeleteVpc operation: The vpc 'vpc-374f0d50' has dependencies and cannot be deleted.

% aws ec2 delete-vpc help

NAME
       delete-vpc -

DESCRIPTION
       Deletes  the  specified VPC. You must detach or delete all gateways and
       resources that are associated with the VPC before you  can  delete  it.
       For  example,  you  must  terminate  all  instances running in the VPC,
       delete all security groups associated with the VPC (except the  default
       one),  delete  all  route  tables  associated  with the VPC (except the
       default one), and so on.

まあそうですよね。消すべき要素としては、

  1. EC2インスタンス
  2. Subnet
  3. InternetGateway
  4. 最後に、VPC

という感じだろうか。

# EC2インスタンスIDの取得
% aws ec2 describe-instances \
  --filters Name=tag:Name,Values='otiai10 Test' \
  | jq .Reservations[].Instances[].InstanceId

# セキュリティグループの取得
% aws ec2 describe-instances \
  --filters Name=tag:Name,Values='otiai10 Test' \
  | jq .Reservations[].Instances[].SecurityGroups

# EC2インスタンスの削除
% aws ec2 terminate-instances \
  --instance-ids i-0acd5d33bb4196314

# セキュリティグループの削除
% aws ec2 delete-security-group \
  --group-id sg-7fb2ec07
# Subnet IDの取得
% aws ec2 describe-subnets \
  --filters Name=tag:Name,Values=otiai10-test-web-example \
  | jq .Subnets[].SubnetId

# Subnetの削除
% aws ec2 delete-subnet \
  --subnet-id subnet-39020970
# InternetGatewayのIDの取得
% aws ec2 describe-internet-gateways \
  --filters Name=tag:Name,Values=otiai10-test-web-ig \
  | jq .InternetGateways[].InternetGatewayId

# InternetGatewayの削除
% aws ec2 delete-internet-gateway \
  --internet-gateway-id igw-6de6b009

An error occurred (DependencyViolation) when calling the DeleteInternetGateway operation:
The internetGateway 'igw-6de6b009' has dependencies and cannot be deleted.

おっと。なんだ。detachか?

# VPC IDの取得
% aws ec2 describe-vpcs \
  --filters Name=tag:Name,Values=otiai10-test-web \
  | jq .Vpcs[].VpcId

# InternetGatewayをVPCからdetach
% aws ec2 detach-internet-gateway \
  --internet-gateway-id igw-6de6b009 \
  --vpc-id vpc-374f0d50

# VPCの削除
% aws ec2 delete-vpc --vpc-id vpc-374f0d50

# InternetGatewayの削除
% aws ec2 delete-internet-gateway \
  --internet-gateway-id igw-6de6b009

awscliを使ったVPCの新規作成からEC2へのssh可能状態まで

VPCを作成。

% aws ec2 create-vpc --cidr-block 10.0.0.0/16 | jq .Vpc.VpcId
"vpc-b7e4acd0"
% aws ec2 create-tags \
   --resources vpc-b7e4acd0 \
   --tags Key=Name,Value=otiai10-test

% aws ec2 describe-vpcs \
  --filter Name=tag:Name,Values=otiai10-test 

# 取れてることを確認

Subnetの作成。

% aws ec2 create-subnet \
  --availability-zone ap-northeast-1a \
  --cidr-block 10.0.0.0/18 \
  --vpc-id vpc-b7e4acd0

# 一応名前つけとく
% aws ec2 create-tags \
  --resources subnet-eb6076a2 \
  --tags Key=Name,Value=otiai10-sn

InternetGatewayの作成。

% aws ec2 create-internet-gateway

# 一応名前つけとく
% aws ec2 create-tags \
  --resources igw-a9beedcd \
  --tags Key=Name,Value=otiai10-ig

InternetGatewayをVPCにアタッチ。

% aws ec2 attach-internet-gateway \
  --vpc-id vpc-b7e4acd0 \
  --internet-gateway-id igw-a9beedcd

MainのRouteTableの確認。

% aws ec2 describe-route-tables \
  | jq '.RouteTables[] | select(.VpcId =="vpc-b7e4acd0")'

ここにRouteの追加。

% aws ec2 create-route \
  --destination-cidr-block 0.0.0.0/0 \
  --route-table-id rtb-57a20331 \
  --gateway-id igw-a9beedcd

これで一応要件を満たしたVPCvpc-b7e4acd0 )ができたと思う。

動作確認

SecurityGroupの作成。

% aws ec2 create-security-group \
  --group-name otiai10-ssh \
  --description ssh-from-office \
  --vpc-id vpc-b7e4acd0

# オフィスからのSSHを開ける
% aws ec2 authorize-security-group-ingress \
  --group-id sg-ab5550d3 \
  --protocol tcp \
  --port 22 \
  --cidr 106.180.6.34/32

EC2インスタンスの作成

% aws ec2 run-instances \
  --instance-type t2.nano \
  --image-id ami-e99f4896 \
  --key-name otiai10.tokyo \
  --security-group-ids sg-ab5550d3 \
  --subnet-id subnet-eb6076a2 \
  --associate-public-ip-address

EC2インスタンスへのSSH

% ssh \
  -i ~/.ssh/aws/otiai10.tokyo.pem \
  ec2-user@52.197.24.227


       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
[ec2-user@ip-10-0-8-208 ~]$
[ec2-user@ip-10-0-8-208 ~]$ uname -a
Linux ip-10-0-8-208.ap-northeast-1.compute.internal 4.14.47-64.38.amzn2.x86_64 #1 SMP Mon Jun 18 22:33:07 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
[ec2-user@ip-10-0-8-208 ~]$ exit
logout
Connection to 52.197.24.227 closed.
%
%

できた。帰りはしんどいのでWebコンソールでお掃除した。

DRYな備忘録として

Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版

Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版

Amazon Web Servicesではじめる新米プログラマのためのクラウド超入門 (CodeZine BOOKS)

Amazon Web Servicesではじめる新米プログラマのためのクラウド超入門 (CodeZine BOOKS)

CWLでHello, World。

CWLって何

的なものについては、このあたりをご参考ください。Web系プログラマ諸兄の99%は縁が無いかと思います。

参考

ログ

% mkdir -p ~/tmp/cwl-playground/hello-world
% cd ~/tmp/cwl-playground/hello-world
% vi hello.cwl
% vi job.yml

hello.cwl の中身

#!/usr/bin/env cwl-runner

cwlVersion: v1.0
class: CommandLineTool
baseCommand: echo
inputs:
    message:
        type: string
        inputBinding:
            position: 1
outputs: []

job.yml の中身

message: Hello World!!

ほんで、

% cwltool ./hello.cwl ./job.yml

とすると

/usr/local/bin/cwltool 1.0.20180622214234
Resolved './hello.cwl' to 'file:///root/hello-world/hello.cwl'
[job hello.cwl] /tmp/tmpGt_fgK$ echo \
    'Hello, World!!'
Hello, World!!
[job hello.cwl] completed success
{}
Final process status is success

となる。

まとめ

これ

github.com

雑感

  • alpineでcwltoolインストールしてもなんかエラー吐いてるので調査

DRYな備忘録として

【Go言語】aws-sdk-goで Instance Profile の作成

CLIでやるのはこれ↓でやって概念理解したので、

otiai10.hatenablog.com

SDK使って同じことをコードからやる。

package main

import (
    "bytes"
    "encoding/json"
    "flag"
    "fmt"
    "time"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/iam"
)

const (
    arnPolicyAmazonS3FullAccess = "arn:aws:iam::aws:policy/AmazonS3FullAccess"
)

var (
    region string
    name   string
)

func init() {
    flag.StringVar(&region, "region", "ap-northeast-1", "Region")
    flag.StringVar(&name, "role-name", "testtest", "Role and profile name")
    flag.Parse()
}
func main() {

    // 0) APIクライアントの初期化
    sess := session.New(&aws.Config{
        Region: aws.String(region),
    })
    client := iam.New(sess)

    // 1) Roleをつくる
    assumepolicy := map[string]interface{}{
        "Version": "2012-10-17",
        "Statement": []map[string]interface{}{
            {
                "Sid":       "",
                "Effect":    "Allow",
                "Action":    "sts:AssumeRole",
                "Principal": map[string]string{"Service": "ec2.amazonaws.com"},
            },
        },
    }
    buf := bytes.NewBuffer(nil)
    if err := json.NewEncoder(buf).Encode(assumepolicy); err != nil {
        panic(err)
    }

    createRoleOutput, err := client.CreateRole(&iam.CreateRoleInput{
        Path:                     aws.String("/"),
        RoleName:                 aws.String(name),
        AssumeRolePolicyDocument: aws.String(buf.String()),
        Description:              aws.String(time.Now().Format(time.RFC3339)),
    })
    if err != nil {
        panic(err)
    }
    role := createRoleOutput.Role

    // 2) Policyをつくる
    //    ... というのは割愛します。今回は既存のもの使おう。
    //        具体的には、 arn:aws:iam::aws:policy/AmazonS3FullAccess です。

    // 3) Role に Policy を attach する
    _, err = client.AttachRolePolicy(&iam.AttachRolePolicyInput{
        PolicyArn: aws.String(arnPolicyAmazonS3FullAccess),
        RoleName:  role.RoleName,
    })
    if err != nil {
        panic(err)
    }

    // 4) Instance Profile をつくる
    instanceprofileCreateOutput, err := client.CreateInstanceProfile(&iam.CreateInstanceProfileInput{
        InstanceProfileName: role.RoleName, // めんどくさいのでRole名と同じにします
    })
    if err != nil {
        panic(err)
    }
    instanceprofile := instanceprofileCreateOutput.InstanceProfile

    // 5) Instance Profile に Role を追加する
    _, err = client.AddRoleToInstanceProfile(&iam.AddRoleToInstanceProfileInput{
        InstanceProfileName: instanceprofile.InstanceProfileName,
        RoleName:            role.RoleName,
    })
    if err != nil {
        panic(err)
    }

    // 成果物
    fmt.Printf("%+v\n", instanceprofile)
}

実行

% go run main.go
{
  Arn: "arn:aws:iam::111222333444555666:instance-profile/testtest",
  CreateDate: 2018-06-05 08:18:09.494 +0000 UTC,
  InstanceProfileId: "AIPAJDNEGOMABCDEFGHIJK",
  InstanceProfileName: "testtest",
  Path: "/"
}

雑感

DRYな備忘録として

Goならわかるシステムプログラミング

Goならわかるシステムプログラミング

Amazon Web Services パターン別構築・運用ガイド 改訂第2版 (Informatics&IDEA)

Amazon Web Services パターン別構築・運用ガイド 改訂第2版 (Informatics&IDEA)

aws cli で IAM Instance Profile をつくってEC2に適用する

Role つくる

% aws iam get-role --role-name foobar
% aws iam create-role --role-name foobar --assume-role-policy-document file://assume-role-policy.json
% aws iam get-role --role-name foobar

assume-role-policy.json というのは、

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

Policy つくる

arn:aws:iam::aws:policy/AmazonS3FullAccess など既存のものを使ってもよい。

% aws iam create-policy --policy-name testpolicy --policy-document file://testpolicy.json
% aws iam list-policies --query Policies[?PolicyName==\'testpolicy\']
% export POLICY_ARN=`aws iam list-policies --query Policies[?PolicyName==\'testpolicy\'].Arn --output text`
% echo $POLICY_ARN

testpolicy.json というのは、

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:List*"
            ],
            "Resource": [
                "arn:aws:s3:::*"
            ]
        }
    ]
}

Role に Policy を attach する

% aws iam attach-role-policy --role-name foobar --policy-arn $POLICY_ARN
% aws iam list-attached-role-policies --role-name foobar

Instance Profile をつくる

% aws iam create-instance-profile --instance-profile-name hogefuga
% aws iam get-instance-profile --instance-profile-name hogefuga

Instance Profile に Role を attach する

% aws iam add-role-to-instance-profile --instance-profile-name hogefuga --role-name foobar
% aws iam get-instance-profile --instance-profile-name hogefuga

以上でいけてるはず。

確認: 作成した Instance Profile を利用してみる

Negative Control: 作成したInstance Profileを使わずにEC2をローンチする

% aws ec2 run-instances \
--region ap-northeast-1 \
--instance-type t2.nano \
--associate-public-ip-address \
--key-name otiai10-test.tokyo \
--image-id ami-92df37ed \
--security-group-ids sg-8fec68f7
[ec2-user@ip-172-31-26-230 ~]$ aws s3 ls s3://otiai10-test-bucket
Unable to locate credentials. You can configure credentials by running "aws configure".

Positive: 作成したInstance Profileを付与してEC2をローンチする

% aws ec2 run-instances \
--region ap-northeast-1 \
--instance-type t2.nano \
--associate-public-ip-address \
--key-name otiai10-test.tokyo \
--image-id ami-92df37ed \
--security-group-ids sg-8fec68f7 \
--iam-instance-profile Name=hogefuga
[ec2-user@ip-172-31-21-74 ~]$ aws s3 ls s3://otiai10-test-bucket
                           PRE aaa/
                           PRE bbb/
                           PRE xxx/
[ec2-user@ip-172-31-21-74 ~]$ touch perm-test-example.txt
[ec2-user@ip-172-31-21-74 ~]$ aws s3 cp perm-test-example.txt s3://otiai10-test-bucket/example.txt
upload failed: ./perm-test-example.txt to s3://otiai10-test-bucket/example.txt An error occurred (AccessDenied) when calling the PutObject operation: Access Denied

当該 Instance Profile を付与したインスタンスだけが、S3へ指定した権限を持つことが確認できた。

後片付け

% aws ec2 terminate-instances --instance-ids i-00dd9b9d9310be741 i-0f78bdb6bf62cc5c5
% aws iam remove-role-from-instance-profile --instance-profile-name hogefuga --role-name foobar
% aws iam delete-instance-profile --instance-profile-name hogefuga
% aws iam detach-role-policy --role-name foobar --policy-arn $POLICY_ARN
% aws iam delete-role --role-name foobar

雑感

  • IAM Instance Profile まわりをCLIでやるのはたいへんだるい

DRYな備忘録として

合格対策 AWS認定ソリューションアーキテクト - アソシエイト

合格対策 AWS認定ソリューションアーキテクト - アソシエイト

Amazon Web Services パターン別構築・運用ガイド 改訂第2版 (Informatics&IDEA)

Amazon Web Services パターン別構築・運用ガイド 改訂第2版 (Informatics&IDEA)

AWSによるサーバーレスアーキテクチャ

AWSによるサーバーレスアーキテクチャ

Rの日付・時間のパースと、時間差分の計算

# Datetime文字列のパース
> t1 <- strptime("May 11 08:42:20", format = "%b %d %H:%M:%S"
1. )
> t2 <- strptime("May 11 08:47:23", format = "%b %d %H:%M:%S")

# 時間の差分
> t2 - t1
Time difference of 5.05 mins

# 秒でくれ
> as.numeric(t2 - t1, units = "secs")
[1] 303
> 

追記 2018/05/16

Rによるやさしい統計学

Rによるやさしい統計学

DRY