funasaki memo

このブログ上の投稿は個人のものであり、所属する企業を代表する投稿ではありません。所属:AWSのSolutions Architect

AWS Systems ManagerでサンプルのAutomation Documentを作成・実行してみる(3)~承認のステップを追加~

前回のメモでは、AWS Systems ManagerのAutomation Documentにて複数ステップを実行しました。今回はそのDocumentをベースに、承認のステップを追加します。分かりやすさのため、前回のAutomation Documentでの「ファイル削除」のステップは割愛します。

今回使用するサンプルのAutomation Documentは以下です。

{
  "description": "Automation Document Example JSON Template",
  "schemaVersion": "0.3",
  "assumeRole": "{{ AutomationAssumeRole }}",
  "parameters": {
    "AutomationAssumeRole": {
      "type": "String",
      "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.",
      "default": ""
    }
  },
  "mainSteps": [
    {
    "name":"createText1",
      "action":"aws:runCommand",
      "maxAttempts":3,
      "timeoutSeconds":1200,
      "onFailure":"Abort",
      "inputs":{
        "DocumentName":"AWS-RunShellScript",
        "InstanceIds":[
          "i-04e0ac63bc6e4105f"
        ],
        "Parameters":{
          "workingDirectory":"/home/ec2-user",
          "commands":[
            "echo hello1 > testfile1"
          ]
        }
      }
    },
    {
         "name":"approve",
         "action":"aws:approve",
         "timeoutSeconds":1000,
         "onFailure":"Abort",
         "inputs":{
            "NotificationArn":"arn:aws:sns:ap-northeast-1:123456789012:test",
            "Message":"Please approve this automation.",
            "MinRequiredApprovals":1,
            "Approvers":[
               "arn:aws:iam::123456789012:user/user1"
            ]
         }
    },
    {
    "name":"ls",
      "action":"aws:runCommand",
      "maxAttempts":3,
      "timeoutSeconds":1200,
      "onFailure":"Abort",
      "inputs":{
        "DocumentName":"AWS-RunShellScript",
        "InstanceIds":[
          "i-04e0ac63bc6e4105f"
        ],
        "Parameters":{
          "workingDirectory":"/home/ec2-user",
          "commands":[
            "ls"
          ]
        }
      }
    }
  ]
}

Amazon SNS (Simple Notification Service)のトピックはすでに作成済みで、そのトピックに対して、今回は自分のメールアドレスでsubscribeしています。

上記Automation Documentを実行した直後の結果は以下。

f:id:kenjifunasaki:20180413190010p:plain

approveのステップで待機中となっているのが分かります。この状態で、自分のメールボックスを確認すると、以下のような内容のメールが届いていました。

Please approve this automation.

-- Approval Details --

Approval Step Name: approve
Region: ap-northeast-1
Automation Execution Id: 59cf7cbe-3f00-11e8-8d8a-6d3cffee791e
Approval Expires At: 2018-04-13 10:09 AM UTC

-- Approve or reject through AWS CLI --

Approve:   aws ssm send-automation-signal --automation-execution-id 59cf7cbe-3f00-11e8-8d8a-6d3cffee791e --signal-type Approve --payload Comment=Replace_This_With_Approve_Comment 

Reject:   aws ssm send-automation-signal --automation-execution-id 59cf7cbe-3f00-11e8-8d8a-6d3cffee791e --signal-type Reject --payload Comment=Replace_This_With_Reject_Comment

Approval Expiresには、今回タイムアウト時間を1000秒に指定しているため、その時間経過との時刻が指定されているようです。この時刻になる前に、指定された以下コマンドを、先ほどのドキュメントで指定したIAMユーザで実行してみます。

aws ssm send-automation-signal --automation-execution-id 59cf7cbe-3f00-11e8-8d8a-6d3cffee791e --signal-type Approve --payload Comment=I_approved_this_automation

実行後、Automationの実行結果を確認すると
f:id:kenjifunasaki:20180413190440p:plain

無事approveのステップが成功になり、その後のステップも成功していることが確認できました。

AWS Systems ManagerでサンプルのAutomation Documentを作成・実行してみる(2)~複数ステップ実行 & ステップ実行エラー時の動作確認~

前回のメモでは、AWS Systems ManagerでAutomation Documentのサンプルを作成しましたが、実行ステップ数が1個のみだったので、今回は複数ステップで実行してみます。

新規Automation Documentを作成します。名前はMySampleAutomationDocument2、ドキュメントタイプはオートメーションドキュメントにします。

f:id:kenjifunasaki:20180413144636p:plain

コンテンツは今回は2ステップで実行したいので、以下を入れてみます。

{
  "description": "Automation Document Example JSON Template",
  "schemaVersion": "0.3",
  "assumeRole": "{{ AutomationAssumeRole }}",
  "parameters": {
    "AutomationAssumeRole": {
      "type": "String",
      "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.",
      "default": ""
    }
  },
  "mainSteps": [
    {
    "name":"createText1",
      "action":"aws:runCommand",
      "maxAttempts":3,
      "timeoutSeconds":1200,
      "onFailure":"Abort",
      "inputs":{
        "DocumentName":"AWS-RunShellScript",
        "InstanceIds":[
          "i-04e0ac63bc6e4105f"
        ],
        "Parameters":{
          "workingDirectory":"/home/ec2-user",
          "commands":[
            "echo hello1 > testfile1"
          ]
        }
      }
    },
    {
    "name":"ls",
      "action":"aws:runCommand",
      "maxAttempts":3,
      "timeoutSeconds":1200,
      "onFailure":"Abort",
      "inputs":{
        "DocumentName":"AWS-RunShellScript",
        "InstanceIds":[
          "i-04e0ac63bc6e4105f"
        ],
        "Parameters":{
          "workingDirectory":"/home/ec2-user",
          "commands":[
            "ls"
          ]
        }
      }
    }
  ]
}

/home/ec2-userディレクトリ内にtestfile1を作成して、こちらのディレクトリ内でlsコマンドを実行します。

作成したMySampleAutomationDocument2を実行してみます。
f:id:kenjifunasaki:20180413144924p:plain

結果の画面は以下です。
f:id:kenjifunasaki:20180413145038p:plain

無事2つのステップが成功しているのが分かります。あとは、lsコマンドを実行するステップの詳細を見てみます。

f:id:kenjifunasaki:20180413145206p:plain

上記画面にて、lsコマンドを/home/ec2-userディレクトリで自動実行し、作成したtextfile1ファイルがリスト表示されているのが分かります。

続いて、わざと1ステップでエラーを発生させてみます。実際には存在しないファイルの削除を行うステップを追加します。まずは、既存のMySampleAutomationDocument2で新しいバージョンを作成します。画面右上の新しいバージョンの作成を選びます。

f:id:kenjifunasaki:20180413175932p:plain

コンテンツを修正します。

f:id:kenjifunasaki:20180413180018p:plain

コンテンツの中身は以下です。ステップ2番目に存在しないファイルを削除するステップを入れてみます。

{
  "description": "Automation Document Example JSON Template",
  "schemaVersion": "0.3",
  "assumeRole": "{{ AutomationAssumeRole }}",
  "parameters": {
    "AutomationAssumeRole": {
      "type": "String",
      "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.",
      "default": ""
    }
  },
  "mainSteps": [
    {
    "name":"createText1",
      "action":"aws:runCommand",
      "maxAttempts":3,
      "timeoutSeconds":1200,
      "onFailure":"Abort",
      "inputs":{
        "DocumentName":"AWS-RunShellScript",
        "InstanceIds":[
          "i-04e0ac63bc6e4105f"
        ],
        "Parameters":{
          "workingDirectory":"/home/ec2-user",
          "commands":[
            "echo hello1 > testfile1"
          ]
        }
      }
    },
    {
    "name":"rm",
      "action":"aws:runCommand",
      "maxAttempts":3,
      "timeoutSeconds":1200,
      "onFailure":"Abort",
      "inputs":{
        "DocumentName":"AWS-RunShellScript",
        "InstanceIds":[
          "i-04e0ac63bc6e4105f"
        ],
        "Parameters":{
          "workingDirectory":"/home/ec2-user",
          "commands":[
            "rm 1111.txt"
          ]
        }
      }
    },
    {
    "name":"ls",
      "action":"aws:runCommand",
      "maxAttempts":3,
      "timeoutSeconds":1200,
      "onFailure":"Abort",
      "inputs":{
        "DocumentName":"AWS-RunShellScript",
        "InstanceIds":[
          "i-04e0ac63bc6e4105f"
        ],
        "Parameters":{
          "workingDirectory":"/home/ec2-user",
          "commands":[
            "ls"
          ]
        }
      }
    }
  ]
}

新しいバージョンの作成を選んだあと、MySampleAutomationDocument2の新しいバージョンを実行します。

f:id:kenjifunasaki:20180413180230p:plain

すると当然ですが、存在しないファイルを削除しようとするステップ2が失敗します。

f:id:kenjifunasaki:20180413180507p:plain

ステップ実行の失敗時の挙動については、OnFailureで指定可能です。デフォルトではAbort (中止)の動作になりますが、Continueを指定することで、継続も可能です。
Systems Manager 自動化ドキュメントのリファレンス - AWS Systems Manager

今回は、rmのステップにて、失敗時に継続するように変更してみます。変更箇所は以下。

   {
    "name":"rm",
      "action":"aws:runCommand",
      "maxAttempts":3,
      "timeoutSeconds":1200,
      "onFailure":"Continue",
      "inputs":{
        "DocumentName":"AWS-RunShellScript",
        "InstanceIds":[
          "i-04e0ac63bc6e4105f"
        ],
        "Parameters":{
          "workingDirectory":"/home/ec2-user",
          "commands":[
            "rm 1111.txt"
          ]
        }
      }
    },

修正して再度実行した結果は以下。

f:id:kenjifunasaki:20180413182122p:plain

ステップ2が失敗しても、続けてステップ3が実行されたことが分かります。

AWS Systems ManagerでサンプルのAutomation Documentを作成・実行してみる(1)

AWS Systems Managerで自作で簡単なAutomation Documentを作成してみたので、そのメモです。

Systems Managerエージェントは既にAmazon LinuxベースのEC2インスタンスにインストール・動作済みで、Managed Instanceとして動作済みの前提とします。

まずは、AWS Management ConsoleにてAWS Systems Managerの画面を開いて、Documentを選択します。

f:id:kenjifunasaki:20180413114022p:plain

上記画面にてドキュメントを作成を選択。

f:id:kenjifunasaki:20180413114200p:plain

名前にMySampleAutomationDocument1を入れて、ドキュメントタイプにオートメーションドキュメントを選択、コンテンツには以下を入れます。

{
  "description": "Automation Document Example JSON Template",
  "schemaVersion": "0.3",
  "assumeRole": "{{ AutomationAssumeRole }}",
  "parameters": {
    "AutomationAssumeRole": {
      "type": "String",
      "description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf.",
      "default": ""
    }
  },
  "mainSteps": [
    {
    "name":"createText1",
      "action":"aws:runCommand",
      "maxAttempts":3,
      "timeoutSeconds":1200,
      "onFailure":"Abort",
      "inputs":{
        "DocumentName":"AWS-RunShellScript",
        "InstanceIds":[
          "i-04e0ac63bc6e4105f"
        ],
        "Parameters":{
           "workingDirectory":"/home/ec2-user",
          "commands":[
            "echo hello1 > testfile1"
          ]
        }
      }
    }
  ]
}

オートメーションの実行を選択して、画面右上の「自己所有」を選択して、フィルタする。

f:id:kenjifunasaki:20180413135000p:plain

先ほど作成したMySampleAutomationDocument1を選択、ドキュメントのバージョンは今回は1(デフォルト)を選択して、オートメーションを実行する。

f:id:kenjifunasaki:20180413135024p:plain

以下画面にて成功したことを確認する。

f:id:kenjifunasaki:20180413135041p:plain

個別にステップ(ステップID)を確認してみる。

f:id:kenjifunasaki:20180413140210p:plain

今回はechoコマンドをテキストファイルに出力しただけなので、特に出力は出ていないが、問題なく成功したことが分かる。念のためEC2インスタンスsshでログインして見ると

[ec2-user@ip-10-0-1-164 ~]$ ls
testfile1

続いて、複数ステップでの実行も試してみる。

AWS CodeBuildで internet connectivity error になる件について

AWS CodeBuildで毎回Provisioningでfailedになり、エラーメッセージを見ると"Build does not have internet connectivity. Please check subnet network configuration."と表示されていました。

VPCのサブネットはpublic subnetを選択していて、Route tableもInternet gatewayにroutingされていて、Security Groupもすべてのtrafficを許可していたのに、なぜ繋がらないのだろう?と思っていたら、原因が分かりました。

CodeBuildでprovisionされるインスタンスには、Public IPが割り当てられないようです。そのためPrivate Subnetに立てて、NAT GatewayかNATインスタンス経由でインターネットにoutbound通信させないといけないようです。(気づくのに時間かかってしまった。。)

docs.aws.amazon.com

Amazon VPCAWS CodeBuild を使用するには、NAT ゲートウェイまたは NAT インスタンスが必要です。これにより、AWS CodeBuild がパブリックエンドポイントに到達できるようになります (ビルド実行時に CLI コマンドを実行するなど)。AWS CodeBuild は、作成したネットワークインターフェイスに Elastic IP アドレスを割り当てることをサポートしていないため、NAT ゲートウェイまたは NAT インスタンスの代わりにインターネットゲートウェイを使用することはできません。パブリック IP アドレスの自動割り当ては、Amazon EC2 インスタンスによる起動以外で作成されたネットワークインタフェースに対しては Amazon EC2 ではサポートされていません。

Amazon CognitoのGetOpenIdTokenForDeveloperIdentityとGetCredentialsForIdentityを使ってみる。

Amazon CognitoのGetOpenIdTokenForDeveloperIdentityとGetCredentialsForIdentityを使ってみたときのサンプルコードのメモ。
Amazon Cognito側でのIdentity Poolの作成は済んでいる前提。

getOpenIdTokenForDeveloperIdentity

AWSCredentials credentials = new BasicAWSCredentials("XXXX", "XXXXX");
AmazonCognitoIdentityClient client = new AmazonCognitoIdentityClient(credentials);
client.setEndpoint("cognito-identity.ap-northeast-1.amazonaws.com");
		
GetOpenIdTokenForDeveloperIdentityRequest getOpenIdTokenForDeveloperIdentityRequest = new GetOpenIdTokenForDeveloperIdentityRequest();
getOpenIdTokenForDeveloperIdentityRequest.setIdentityPoolId("ap-northeast-1:XXXX");
Map<String,String> logins = new HashMap<String,String>();
logins.put("login.mycompany.myapp","user1");
getOpenIdTokenForDeveloperIdentityRequest.setLogins(logins);
GetOpenIdTokenForDeveloperIdentityResult getOpenIdTokenForDeveloperIdentityResult = client.getOpenIdTokenForDeveloperIdentity(getOpenIdTokenForDeveloperIdentityRequest);

getCredentialsForIdentity

GetCredentialsForIdentityRequest getCredentialsForIdentityRequest = new GetCredentialsForIdentityRequest();
Map<String,String> map = new HashMap<String,String>();
map.put("cognito-identity.amazonaws.com", getOpenIdTokenForDeveloperIdentityResult.getToken());
getCredentialsForIdentityRequest.setLogins(map);
getCredentialsForIdentityRequest.setIdentityId(getOpenIdTokenForDeveloperIdentityResult.getIdentityId());
		
GetCredentialsForIdentityResult result = client.getCredentialsForIdentity(getCredentialsForIdentityRequest);
Credentials userCredentials = result.getCredentials();
System.out.println("AccessKey: " + userCredentials.getAccessKeyId());
System.out.println("SecretKey: " + userCredentials.getSecretKey());

mod_rewriteを使ってAmazon S3のコンテンツを表示させる

自分で立てたWebサーバから静的コンテンツ(index.html等)を配信していた形を、元々のWebサーバのURLは変えずに、Amazon S3から配信させてみます。(事前にAmazon S3の該当バケットにindex.html等のコンテンツをアップしておきます。)

今回は、Amazon LinuxApache HTTP Serverで試しました。

まずは、Apacheをインストール、起動します。

sudo yum install -y httpd
sudo service httpd start

適当なindex.htmlファイルを/var/www/html以下に作成します。

動作するサーバにアクセスすると

curl http://ec2-xx-xx-xxx-xxx.ap-northeast-1.compute.amazonaws.com
(自分で立てたサーバ上のコンテンツが表示)

次に、/etc/httpd/conf/httpd.confの中身を見て、mod_rewriteがロードされていることを確認します。

LoadModule rewrite_module modules/mod_rewrite.so

続けて、/etc/httpd/conf/httpd.confの中に以下を追記します。

<VirtualHost *:80>
    DocumentRoot /var/www/html
    ServerName ec2-xx-xx-xxx-xxx.ap-northeast-1.compute.amazonaws.com
    RewriteEngine On
    RewriteRule ^/(.*)$ http://xxxxx.s3-website-ap-northeast-1.amazonaws.com/$1 [P,L]
</VirtualHost>

※上記例では、S3のWebサイトホスティングのURLに直接変更させています。

その後、Apacheを再起動して

sudo service httpd restart

同様にアクセスする。

curl http://ec2-xx-xx-xxx-xxx.ap-northeast-1.compute.amazonaws.com
(xxxxx.s3-website-ap-northeast-1.amazonaws.com/index.htmlの内容が表示される)

httpd.confのRewriteRuleで末尾の[P,L]にしておくと、URLはec2-xx-xx-xxx-xxx...のままで、S3の画像を表示させます。末尾を[R,L]にすると、S3のURLにリダイレクトされました。

リダイレクト先のドメイン名は元々のS3のものを使っていますが、これをRoute 53等のDNSでカスタムドメインを登録して、カスタムドメインでS3へアクセスさせることも勿論できます。

この方法を使えば、アプリ側を特に修正を入れずに、URLにマッチした場合にS3の画像を表示させることができそうですね!(勿論rewriteさせる形ではなく、アプリ側を修正させる方が望ましいですけども。)

Amazon LinuxにRedisをインストール

yumを使ってRedisをAmazon Linuxにインストールしてみる。

$ sudo yum --enablerepo=epel install redis

redis起動

$ sudo /etc/init.d/redis start

redisの情報を確認

$ redis-cli -h localhost info
redis_version:2.4.10
redis_git_sha1:00000000
redis_git_dirty:0
arch_bits:64
multiplexing_api:epoll
gcc_version:4.4.6
process_id:17580
uptime_in_seconds:318
uptime_in_days:0
lru_clock:304917
used_cpu_sys:0.28
used_cpu_user:0.08
used_cpu_sys_children:0.00
used_cpu_user_children:0.00
connected_clients:1
connected_slaves:0
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
used_memory:726192
used_memory_human:709.17K
used_memory_rss:1847296
used_memory_peak:726328
used_memory_peak_human:709.30K
mem_fragmentation_ratio:2.54
mem_allocator:jemalloc-2.2.5
loading:0
aof_enabled:0
changes_since_last_save:0
bgsave_in_progress:0
last_save_time:1387169174
bgrewriteaof_in_progress:0
total_connections_received:2
total_commands_processed:2
expired_keys:0
evicted_keys:0
keyspace_hits:0
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:0
vm_enabled:0
role:slave
master_host:replica1.wfisum.0001.apne1.cache.amazonaws.com
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
master_link_down_since_seconds:1387169493