🐰

AWS Systems ManagerドキュメントでChef Recipeを実行する

2023/09/10に公開

AWS OpsWork for Chef Automateが2024年5月5日にサービス終了となります。
AWS OpsWork for Chef Automateサービス終了
AWSでChefを利用したいけどChefサーバを立てるほどの規模ではなくライトにサーバレスでRecipeを実行したい方、AWS Systems Manager(SSM)でChef Recipeを実行できます。

本記事ではSSMドキュメントを使用したChef Recipeの実行について、以下のドキュメントを参考に任意のRecipe実行を実践してみます。
チュートリアル: Chef recipe を実行する関連付けの作成

概要

まずは公式ドキュメントの概要を確認してできることを理解します。

AWS-ApplyChefRecipes SSM ドキュメントを使用して、Chef recipe を実行する State Manager 関連付けを作成できます。State Manager は AWS Systems Manager の一機能です。AWS-ApplyChefRecipes SSM ドキュメントを使用して Linux ベースのSystems Manager マネージドノードをターゲットにすることができます。このドキュメントには、Chef recipe を実行するための以下の利点があります。

  • Chef の複数のリリース (Chef 11 から Chef 17) をサポートします。
  • ターゲットノードに Chef クライアントソフトウェアを自動的にインストールします。
  • オプションで、ターゲットノードの Systems Manager コンプライアンスチェックを実行し、コンプライアンスチェックの結果を Amazon Simple Storage Service (Amazon S3) バケットに保存します。
  • ドキュメントの 1 回の実行で複数のクックブックと recipe を実行します。
  • オプションで、recipe を why-run モードで実行して、どの recipe がターゲットノードに変更を加えるかを、変更せずに確認します。
  • オプションで、カスタム JSON 属性を chef-client 実行に適用します。
  • オプションで、指定した場所に保存されているソースファイルからカスタム JSON 属性を適用します。

"AWS-ApplyChefRecipes" SSMドキュメントは以下のフローで定義されています。

  • ステップ1(setKnownHostsLinux)
    GitリポジトリへSSH接続するための認証情報を設定します。Recipe格納先にGit以外を選択した場合はスキップされます。
  • ステップ2(downloadCookbooks)
    Cookbooksをダウンロードします。
  • ステップ3(setCustomJson)
    オプションで指定されたカスタムjsonを設定します。
  • ステップ4(runShellScript)
    run_listやcompliance_parameterを検証します。
    Cookbooksダウンロード先のtarまたはzipファイルを展開して実行用のディレクトリへコピーします。
    EC2インスタンスにChef Clientがインストールされていない場合はダウンロードしてインストールします。
    chef-clientコマンドでRecipeを実行します。

前提

SSMドキュメント"AWS-RunInspecChecks"の実行前に実施しておく前提作業を記載します。

  • Recipe適用対象EC2インスタンスのセットアップ
  • SSM Agentのインストール
  • EC2インスタンスとSSMの通信設定(セキュリティグループで443ポートへのアウトバウンド許可、またはVPC Endpointの作成)
  • Recipe格納先およびレポート出力先のS3バケット作成
  • ログ出力先のCloudWatch Logsロググループ作成
  • インスタンスロールへSSM、S3、CloudWatch Logsのポリシー付与

本記事では以下の構成を想定します。

EC2インスタンスのOSはSSM Agentインストール済みのAmazon Linux 2023(AMI:al2023-ami-2023.1.20230809.0-kernel-6.1-x86_64)を使用します。

Recipe格納先の準備

公式ドキュメントではCookbookやRecipeの格納先について次のように記載されています。本記事ではS3バケットへRecipeを格納します。

Git、GitHub、HTTP、または Amazon S3 バケットを、AWS-ApplyChefRecipes ドキュメントで指定する Chef クックブックや recipe のダウンロードソースとして使用できます。

S3をソースとして使用する場合のファイル形式は以下に記載されています。
Amazon S3 をクックブックソースとして使用する

Chef クックブックは、単一の .zip や tar.gz ファイルまたはディレクトリ構造として Amazon S3 に保存およびダウンロードすることもできます。

なお、EC2インスタンスにtarやzipコマンドがインストールされていない場合はエラーとなりますので事前に確認しておきましょう。また、zipを選択した場合は以下のコードにより"Cookbooks could not be extracted with tar. Trying with unzip..."が必ず結果に出力されます。

AWS-ApplyChefRecipes: 763-775行

          "    if (tar xf \"$archive\" -C \"$destination\" >/dev/null); then",
          "        return",
          "    fi",
          "",
          "    report_error \"Cookbooks could not be extracted with tar. Trying with unzip...\"",
          "",
          "    if [[ ! -x \"$(command -v unzip)\" ]]; then",
          "        throw_error \"'unzip' is not installed. Failed to extract cookbooks.\"",
          "    fi",
          "",
          "    if (unzip -o \"$archive\" -d \"$destination\" >/dev/null); then",
          "        return",
          "    fi",

Chef Cookbookの準備

適用対象のChef Cookbookを準備します。Chef Supermarketでは様々な製品に対応したChefコミュニティが提供するCookbookが利用できます。
https://supermarket.chef.io/

nginxを使ってみましょう。
nginx - Chef Supermarket
右下の「Download Cookbook」を押してダウンロードします。

Chefリポジトリは以下のような構造として、cookbooksフォルダ配下にダウンロードしたnginx資材を配置し、nginxフォルダ配下にrecipesフォルダを新規作成して、default.rbファイルを作成しました。

chef-repo/
 └ cookbooks/
  └ nginx/
   ├ libraries/
   ├ recipes/
   │ └ default.rb
   ├ resources/
   ├ templates/
   ├ ・・・

default.rbファイルの内容はnginx cookbookのドキュメントに記載されていたコマンドを単純実行します。

default.rb
nginx_install 'nginx' do
    source 'distro'
end

nginx_service 'nginx' do
    action :enable
    delayed_action :start
end

nginx_config 'nginx' do
    action :create
    notifies :reload, 'nginx_service[nginx]', :delayed
end

nginx_site 'test_site' do
    mode '0644'

    variables(
        'server' => {
        'listen' => [ '*:80' ],
        'server_name' => [ 'test_site' ],
        'access_log' => '/var/log/nginx/test_site.access.log',
        'locations' => {
            '/' => {
            'root' => '/var/www/nginx-default',
            'index' => 'index.html index.htm',
            },
        },
        }
    )

    action :create
    notifies :reload, 'nginx_service[nginx]', :delayed
end

cookbookが完成したらchef-repoフォルダをzipアーカイブしてRecipe格納先のS3バケットへアップロードします。

SSM Run Commandの実行

SSM Run CommandでRecipeを実行します。
Run Commandの実行画面で必要な選択肢を入力していきます。(記載のないパラメータはデフォルトです。)
「AWS Systems Manager」→「Run Command」→「コマンドの実行」で「AWS-ApplyChefRecipes」を選択して「コマンドのパラメータ」を入力し「実行」を押下します。
実行

コマンドドキュメント

  • ドキュメント名: AWS-ApplyChefRecipes
  • ドキュメントのバージョン: 1(デフォルト)

コマンドのパラメータ

  • Source Type(Required)
    Chef Cookbookが格納されたソースリポジトリを指定します。Git, GitHub, HTTP, S3から選択できます。ここでは「S3」を選択します。
  • Source Info(Required)
    Source Typeに応じたソースリポジトリの情報を指定します。S3バケットへ配置したCookbook zipファイルのパスを指定します。
{
   "path":"https://s3.amazonaws.com/{s3-bucket-name}/{archive-file-name}"
}

s3-bucket-namearchive-file-nameは適切なものへ置き換えてください。

  • Run List(Optional)
    適用するChef Recipeを指定します。以下のように複数指定できます。
recipe[cookbook_name1::recipe_name],recipe[cookbook_name2::recipe_name]

ここではnginxのdefault recipeを指定します。

recipe[nginx::default]
  • Json Attributes Sources(Optional)
    Recipeに渡すAttributesのソースパスを以下のような形式で指定します。複数のソースがある場合で同じAttributesがある場合は最初のソースのAttributesが後のソースのAttributesを上書きします。以下は公式ドキュメントの例です。
 {"sourceType":"s3", "sourceInfo":"someS3URL1"} {"sourceType":"s3", "sourceInfo":"someS3URL2"}
  • Json Attributes Content(Optional)
    Attributesをjson形式で直接指定します。JsonAttributesSourcesと同じAttributesは上書きされます。以下は公式ドキュメントの例です。
{"filepath":"/tmp/example.txt", "content":"Hello, World!"}
  • Chef Client Version(Optional)
    適用対象インスタンスにインストールするChefのバージョン。Chef 11~17を選択できます。「None」にするとインストールしません。
    ※Chef 17の場合、Compliance Report出力とあわせて使用すると以下のエラーが出力され失敗します。Chef 17が必要とするaws-sdk-coreのバージョンとCompliance Report(aws-sdk-ssm)が必要とするaws-sdk-coreのバージョンが異なるために競合が発生するようです。
FATAL: Gem::ConflictError: Unable to activate aws-sdk-ssm-1.156.0, because aws-sdk-core-3.125.1 conflicts with aws-sdk-core (~> 3, >= 3.177.0)

aws-sdk-cloudformationのケースで同様の事象があるようです。
https://github.com/chef/chef/issues/13808

  • Chef Client Arguments(Optional)
    Chef Clientを実行する際の追加オプション。以下にChef 17のhelpを記載します。
chef-clientのhelp
Usage: /usr/bin/chef-client (options)
        --[no-]always-dump-stacktrace
                                     Always dump the stacktrace regardless of the log_level setting.
        --chef-license ACCEPTANCE    Accept the license for this product and any contained products ('accept', 'accept-no-persist', or 'accept-silent')
    -S, --server CHEFSERVERURL       The Chef Infra Server URL.
        --chef-zero-host HOST        Host to start Chef Infra Zero on.
        --chef-zero-port PORT        Port (or port range) to start Chef Infra Zero on. Port ranges like 1000,1010 or 8889-9999 will try all given ports until one works.
    -f, --[no-]fork                  Fork Chef Infra Client process.
    -k, --client_key KEY_FILE        Set the client key file location.
        --[no-]color                 Use colored output, defaults to enabled.
    -c, --config CONFIG              The configuration file to use.
        --config-option OPTION=VALUE Override a single configuration option.
    -d, --daemonize [WAIT]           Daemonize the process. Accepts an optional integer which is the number of seconds to wait before the first daemonized run.
        --delete-entire-chef-repo    DANGEROUS: does what it says, only useful with --recipe-url.
        --disable-config             Refuse to load a config file and use defaults. This is for development and not a stable API.
    -R, --enable-reporting           (chef-client only) reporting data collection for runs.
    -E, --environment ENVIRONMENT    Set the Chef Infra Client environment on the node.
        --ez                         A memorial for Ezra Zygmuntowicz.
        --[no-]fips                  Enable FIPS mode.
        --force-formatter            Use formatter output instead of logger output.
        --force-logger               Use logger output instead of formatter output.
    -F, --format FORMATTER           The output format to use.
    -g, --group GROUP                Group to set privilege to.
    -i, --interval SECONDS           Run Chef Infra Client periodically, in seconds.
    -j JSON_ATTRIBS,                 Load attributes from a JSON file or URL.
        --json-attributes
        --[no-]listen                Whether a local mode (-z) server binds to a port.
    -z, --local-mode                 Point at local repository.
        --lockfile LOCKFILE          Set the lockfile location. Prevents multiple client processes from converging at the same time.
    -l, --log_level LEVEL            Set the log level (auto, trace, debug, info, warn, error, fatal).
    -L, --logfile LOGLOCATION        Set the log file location, defaults to STDOUT - recommended for daemonizing.
        --minimal-ohai               Only run the bare minimum Ohai plugins Chef Infra Client needs to function.
    -n NAMED_RUN_LIST,               Use a policyfile's named run list instead of the default run list.
        --named-run-list
    -N, --node-name NODE_NAME        The node name for this client.
        --once                       Cancel any interval or splay options, run Chef Infra Client once and exit.
    -o RunlistItem,RunlistItem...,   Replace current run list with specified items for a single run.
        --override-runlist
    -P, --pid PIDFILE                Set the PID file location, for the chef-client daemon process. Defaults to /tmp/chef-client.pid.
        --[no-]profile-ruby          Dump complete Ruby call graph stack of entire Chef Infra Client run (expert only).
        --recipe-url=RECIPE_URL      Pull down a remote archive of recipes and unpack it to the cookbook cache. Only used in local mode.
        --run-lock-timeout SECONDS   Set maximum duration to wait for another client run to finish, default is indefinitely.
    -r RunlistItem,RunlistItem...,   Permanently replace current run list with specified items.
        --runlist
        --[no-]skip-cookbook-sync    (chef-client only) Use cached cookbooks without overwriting local differences from the Chef Infra Server.
        --[no-]slow-report [COUNT]   List the slowest resources at the end of the run (default: 10).
        --legacy-mode                Run in legacy mode.
    -s, --splay SECONDS              The splay time for running at intervals, in seconds.
    -t, --target TARGET              Target Chef Infra Client against a remote system or device
    -u, --user USER                  User to set privilege to.
    -K, --validation_key KEY_FILE    Set the validation key file location, used for registering new clients.
    -v, --version                    Show Chef Infra Client version.
    -W, --why-run                    Enable whyrun mode.
    -h, --help                       Show this help message.
  • Why Run(Optional)
    実機に反映せずにRecipeの構文チェックやテスト実行をする場合は「Why Run」を「True」にします。Why Runの実行で問題が発生しなければ「False」にして実機へ反映しましょう。
  • Compliance Severity(Optional): None
    Chef Recipeと実機のドリフトをSSMコンプライアンスレポートへ表示する際の重大度。コンプライアンスレポートをスキップする場合は「None」とします。
  • Compliance Type(Optional)
    コンプライアンスレポートを出力するタイプを指定します。「Custom:Chef」とします。
  • Compliance Report Bucket(Optional)
    コンプライアンスレポートを出力するS3バケットを指定します。S3バケットは予め作成しておきます。

ターゲット

  • ターゲット
    適用対象インスタンスを「タグ指定」、「手動選択」、「リソースグループ」の中から選べます。

出力オプション

コマンドの実行結果をS3バケットやCloudWatch Logsへ出力できます。コンソールからでも確認できますが文字数制限があるため、できるだけ出力するように設定しておきましょう。

  • コマンド出力の Amazon S3 バケットへの書き込み: 「S3 バケットへの書き込みを有効化する」にチェック
  • S3 バケット名:
    • リストからバケット名を選択します: s3-output-bucket-name
  • コマンド出力を Amazon CloudWatch Logs に書き込む: 「CloudWatch 出力」にチェック
  • ロググループ名 - オプション: cloudwatch-logs-group-name

実行結果の確認

実行結果は以下のような画面になります。インスタンスIDを選択すると各ステップの結果が表示されます。
実行結果その1

各ステップの結果は以下のような画面です。何回か試行錯誤したため初回実行結果ではありませんが、参考までにOutputとErrorの内容をそのまま記載します。
実行結果ステップ1

Output
INFO: This step will be skipped since cookbook source is not Git.
Error
Error(0)

実行結果ステップ2

Output
Content downloaded to /var/lib/amazon/ssm/i-0997f8cff6eef4a8b/document/orchestration/6c8e4443-8442-4e4e-bbd2-649636b38fbc/downloads/customer_cookbooks
Error
Error(0)

実行結果ステップ3

Output
INFO: Custom json is set up.
Error
Error(0)

実行結果ステップ4

Output
WARNING: Compliance reports S3 bucket is set, but compliance severity is set to 'None'. No compliance reports will be generated.
WARNING: Compliance type is not empty but compliance severity is set to 'None'. No compliance reports will be generated.
Lets Encrypt certificate fixed
INFO: Executing chef client...
Chef Infra Client, version 17.9.26
Patents: https://www.chef.io/patents
Infra Phase starting
[2023-08-28T13:22:53+00:00] ERROR: shard_seed: Failed to get dmi property serial_number: is dmidecode installed?
[2023-08-28T13:22:53+00:00] WARN: Run List override has been provided.
[2023-08-28T13:22:53+00:00] WARN: Original Run List: [role[squid-role]]
[2023-08-28T13:22:53+00:00] WARN: Overridden Run List: [recipe[nginx::default]]
Resolving cookbooks for run list: ["nginx::default"]
Synchronizing cookbooks:
  - nginx (12.2.3)
Installing cookbook gem dependencies:
Compiling cookbooks...
Loading Chef InSpec profile files:
Loading Chef InSpec input files:
Loading Chef InSpec waiver files:
Converging 4 resources
Recipe: nginx::default
  * nginx_install[nginx] action install
    * directory[/var/lib/amazon/ssm/i-0997f8cff6eef4a8b/document/orchestration/6c8e4443-8442-4e4e-bbd2-649636b38fbc/downloads/ohai/plugins] action create
      - create new directory /var/lib/amazon/ssm/i-0997f8cff6eef4a8b/document/orchestration/6c8e4443-8442-4e4e-bbd2-649636b38fbc/downloads/ohai/plugins
      - restore selinux security context
    * template[/var/lib/amazon/ssm/i-0997f8cff6eef4a8b/document/orchestration/6c8e4443-8442-4e4e-bbd2-649636b38fbc/downloads/ohai/plugins/nginx.rb] action create
      - create new file /var/lib/amazon/ssm/i-0997f8cff6eef4a8b/document/orchestration/6c8e4443-8442-4e4e-bbd2-649636b38fbc/downloads/ohai/plugins/nginx.rb
      - update content in file /var/lib/amazon/ssm/i-0997f8cff6eef4a8b/document/orchestration/6c8e4443-8442-4e4e-bbd2-649636b38fbc/downloads/ohai/plugins/nginx.rb from none to 1576f5
      --- /var/lib/amazon/ssm/i-0997f8cff6eef4a8b/document/orchestration/6c8e4443-8442-4e4e-bbd2-649636b38fbc/downloads/ohai/plugins/nginx.rb	2023-08-28 13:22:54.499070877 +0000
      +++ /var/lib/amazon/ssm/i-0997f8cff6eef4a8b/document/orchestration/6c8e4443-8442-4e4e-bbd2-649636b38fbc/downloads/ohai/plugins/.chef-nginx20230828-3809-xl1ij4.rb	2023-08-28 13:22:54.499070877 +0000
      @@ -1 +1,83 @@
      +#
      +# Author:: Jamie Winsor (<jamie@vialstudios.com>)
      +#
      +# Copyright 2012, Riot Games
      +#
      +# Licensed under the Apache License, Version 2.0 (the "License");
      +# you may not use this file except in compliance with the License.
      +# You may obtain a copy of the License at
      +#
      +#     http://www.apache.org/licenses/LICENSE-2.0
      +#
      +# Unless required by applicable law or agreed to in writing, software
      +# distributed under the License is distributed on an "AS IS" BASIS,
      +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      +# See the License for the specific language governing permissions and
      +# limitations under the License.
      +#
      +
      +Ohai.plugin(:Nginx) do
      +  provides "nginx"
      +  provides "nginx/version"
      +  provides "nginx/configure_arguments"
      +  provides "nginx/prefix"
      +  provides "nginx/conf_path"
      +
      +  def parse_flags(flags)
      +    prefix = nil
      +    conf_path = nil
      +
      +    flags.each do |flag|
      +      case flag
      +      when /^--prefix=(.+)$/
      +        prefix = Regexp.last_match(1)
      +      when /^--conf-path=(.+)$/
      +        conf_path = Regexp.last_match(1)
      +      end
      +    end
      +
      +    [prefix, conf_path]
      +  end
      +
      +  collect_data do
      +    nginx Mash.new unless nginx
      +    # if we fail we should still have these values to avoid nil class errors
      +    # if people try to use them
      +    nginx[:version]             = nil unless nginx[:version]
      +    nginx[:configure_arguments] = [] unless nginx[:configure_arguments]
      +    nginx[:prefix]              = nil unless nginx[:prefix]
      +    nginx[:conf_path]           = nil unless nginx[:conf_path]
      +
      +    begin
      +      so = shell_out("/usr/sbin/nginx -V")
      +      # Sample output:
      +      # nginx version: nginx/1.10.1
      +      # built by clang 7.3.0 (clang-703.0.31)
      +      # built with OpenSSL 1.0.2h  3 May 2016
      +      # TLS SNI support enabled
      +      # configure arguments: --prefix=/usr/local/Cellar/nginx/1.10.1 --with-pcre --sbin-path=/usr/local/Cellar/nginx/1.10.1/bin/nginx --with-cc-opt='-I/usr/local/Cellar/pcre/8.38/include -I/usr/local/Cellar/openssl/1.0.2h_1/include' --with-ld-opt='-L/usr/local/Cellar/pcre/8.38/lib -L/usr/local/Cellar/openssl/1.0.2h_1/lib' --conf-path=/usr/local/etc/nginx/nginx.conf --pid-path=/usr/local/var/run/nginx.pid --lock-path=/usr/local/var/run/nginx.lock --http-client-body-temp-path=/usr/local/var/run/nginx/client_body_temp --http-proxy-temp-path=/usr/local/var/run/nginx/proxy_temp --http-fastcgi-temp-path=/usr/local/var/run/nginx/fastcgi_temp --http-uwsgi-temp-path=/usr/local/var/run/nginx/uwsgi_temp --http-scgi-temp-path=/usr/local/var/run/nginx/scgi_temp --http-log-path=/usr/local/var/log/nginx/access.log --error-log-path=/usr/local/var/log/nginx/error.log
      +
      +      if so.exitstatus == 0
      +        so.stderr.split("\n").each do |line|
      +          case line
      +          when /^configure arguments:(.+)/
      +            # This could be better: I'm splitting on configure arguments which removes them and also
      +            # adds a blank string at index 0 of the array. This is why we drop index 0 and map to
      +            # add the '--' prefix back to the configure argument.
      +            nginx[:configure_arguments] = Regexp.last_match(1).split(/\s--(?!param)/).drop(1).map { |ca| "--#{ca}" }
      +
      +            prefix, conf_path = parse_flags(nginx[:configure_arguments])
      +
      +            nginx[:prefix] = prefix
      +            nginx[:conf_path] = conf_path
      +          when /^nginx version: nginx\/(\d+\.\d+\.\d+)/
      +            nginx[:version] = Regexp.last_match(1)
      +          end
      +        end
      +      end
      +    rescue
      +      Ohai::Log.debug('Nginx plugin: Could not shell_out "/usr/sbin/nginx -V"')
      +    end
      +  end
      +end
      - restore selinux security context
    * ohai[nginx] action nothing (skipped due to action :nothing)
    * dnf_package[nginx] action install
      - install version 1:1.24.0-1.amzn2023.0.1.x86_64 of package nginx
    * ohai[nginx] action reload[2023-08-28T13:23:00+00:00] ERROR: shard_seed: Failed to get dmi property serial_number: is dmidecode installed?

      - re-run ohai and merge results into node attributes
  
  * nginx_service[nginx] action enable (up to date)
  * service[nginx] action nothing (skipped due to action :nothing)
  * nginx_config[nginx] action create
    * directory[/etc/nginx/conf.d] action create
      - change mode from '0755' to '0750'
      - restore selinux security context
    * directory[/etc/nginx/conf.http.d] action create
      - create new directory /etc/nginx/conf.http.d
      - change mode from '' to '0750'
      - change owner from '' to 'root'
      - change group from '' to 'root'
      - restore selinux security context
    * directory[/var/log/nginx] action create
      - change mode from '0711' to '0750'
      - restore selinux security context
    * file[/etc/nginx/conf.d/default.conf] action delete (up to date)
    * file[/etc/nginx/conf.d/example_ssl.conf] action delete (up to date)
    * nginx_site[default-site] action create
      * template[/etc/nginx/conf.http.d/default-site.conf] action create
        - create new file /etc/nginx/conf.http.d/default-site.conf
        - update content in file /etc/nginx/conf.http.d/default-site.conf from none to b28dbb
        --- /etc/nginx/conf.http.d/default-site.conf	2023-08-28 13:23:00.629083434 +0000
        +++ /etc/nginx/conf.http.d/.chef-default-site20230828-3809-emozey.conf	2023-08-28 13:23:00.629083434 +0000
        @@ -1 +1,17 @@
        +# Generated by Chef for ip-10-0-1-13.ap-northeast-1.compute.internal
        +# Do NOT modify this file by hand.
        +#
        +
        +server {
        +  listen       80;
        +  server_name  ip-10-0-1-13;
        +
        +  access_log   /var/log/nginx/localhost.access.log;
        +  error_log    /var/log/nginx/localhost.error.log;
        +
        +  location / {
        +    root       /usr/share/nginx/html;
        +    index      index.html index.htm;
        +  }
        +}
        - change mode from '' to '0640'
        - change owner from '' to 'root'
        - change group from '' to 'root'
        - restore selinux security context
    
    * template[/etc/nginx/nginx.conf] action create
      - update content in file /etc/nginx/nginx.conf from 8dcb91 to 465331
      --- /etc/nginx/nginx.conf	2023-05-31 21:08:48.000000000 +0000
      +++ /etc/nginx/.chef-nginx20230828-3809-hqrk8s.conf	2023-08-28 13:23:00.669083516 +0000
      @@ -1,84 +1,35 @@
      -# For more information on configuration, see:
      -#   * Official English Documentation: http://nginx.org/en/docs/
      -#   * Official Russian Documentation: http://nginx.org/ru/docs/
      +# Generated by Chef for ip-10-0-1-13.ap-northeast-1.compute.internal
      +# Do NOT modify this file by hand.
      +#
       
      -user nginx;
      -worker_processes auto;
      -error_log /var/log/nginx/error.log notice;
      -pid /run/nginx.pid;
      +user                  nginx;
      +worker_processes      auto;
      +error_log             /var/log/nginx/error.log;
      +pid                   /run/nginx.pid;
       
      -# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
      -include /usr/share/nginx/modules/*.conf;
      +include               /usr/share/nginx/modules/*.conf;
       
       events {
      -    worker_connections 1024;
      +  worker_connections  1024;
       }
       
       http {
      -    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
      -                      '$status $body_bytes_sent "$http_referer" '
      -                      '"$http_user_agent" "$http_x_forwarded_for"';
      +  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
      +                    '$status $body_bytes_sent "$http_referer" '
      +                    '"$http_user_agent" "$http_x_forwarded_for"';
       
      -    access_log  /var/log/nginx/access.log  main;
      +  access_log          /var/log/nginx/access.log main;
       
      -    sendfile            on;
      -    tcp_nopush          on;
      -    keepalive_timeout   65;
      -    types_hash_max_size 4096;
      +  sendfile            on;
      +  tcp_nopush          on;
      +  tcp_nodelay         on;
      +  keepalive_timeout   65;
      +  types_hash_max_size 2048;
       
      -    include             /etc/nginx/mime.types;
      -    default_type        application/octet-stream;
      +  include             /etc/nginx/mime.types;
      +  default_type        application/octet-stream;
       
      -    # Load modular configuration files from the /etc/nginx/conf.d directory.
      -    # See http://nginx.org/en/docs/ngx_core_module.html#include
      -    # for more information.
      -    include /etc/nginx/conf.d/*.conf;
      -
      -    server {
      -        listen       80;
      -        listen       [::]:80;
      -        server_name  _;
      -        root         /usr/share/nginx/html;
      -
      -        # Load configuration files for the default server block.
      -        include /etc/nginx/default.d/*.conf;
      -
      -        error_page 404 /404.html;
      -        location = /404.html {
      -        }
      -
      -        error_page 500 502 503 504 /50x.html;
      -        location = /50x.html {
      -        }
      -    }
      -
      -# Settings for a TLS enabled server.
      -#
      -#    server {
      -#        listen       443 ssl http2;
      -#        listen       [::]:443 ssl http2;
      -#        server_name  _;
      -#        root         /usr/share/nginx/html;
      -#
      -#        ssl_certificate "/etc/pki/nginx/server.crt";
      -#        ssl_certificate_key "/etc/pki/nginx/private/server.key";
      -#        ssl_session_cache shared:SSL:1m;
      -#        ssl_session_timeout  10m;
      -#        ssl_ciphers PROFILE=SYSTEM;
      -#        ssl_prefer_server_ciphers on;
      -#
      -#        # Load configuration files for the default server block.
      -#        include /etc/nginx/default.d/*.conf;
      -#
      -#        error_page 404 /404.html;
      -#        location = /404.html {
      -#        }
      -#
      -#        error_page 500 502 503 504 /50x.html;
      -#        location = /50x.html {
      -#        }
      -#    }
      -
      +  include             /etc/nginx/conf.d/*.conf;
      +  include             /etc/nginx/conf.http.d/list*.conf;
       }
      -
      - change mode from '0644' to '0640'
      - restore selinux security context
  
  * template[/etc/nginx/conf.http.d/list.conf] action nothing (skipped due to action :nothing)
  * nginx_site[test_site] action create
    * template[/etc/nginx/conf.http.d/test_site.conf] action create
      - create new file /etc/nginx/conf.http.d/test_site.conf
      - update content in file /etc/nginx/conf.http.d/test_site.conf from none to d30f01
      --- /etc/nginx/conf.http.d/test_site.conf	2023-08-28 13:23:00.749083681 +0000
      +++ /etc/nginx/conf.http.d/.chef-test_site20230828-3809-vyifuy.conf	2023-08-28 13:23:00.749083681 +0000
      @@ -1 +1,21 @@
      +# Generated by Chef for ip-10-0-1-13.ap-northeast-1.compute.internal
      +# Do NOT modify this file by hand.
      +#
      +
      +# Server
      +# test_site
      +server {
      +  listen *:80;
      +
      +  server_name test_site;
      +  root /usr/share/nginx/html;
      +
      +  location / {
      +    root /var/www/nginx-default;
      +    index index.html index.htm;
      +  }
      +
      +  access_log /var/log/nginx/test_site.access.log;
      +  error_log /var/log/nginx/site-test_site-error.log;
      +}
      - change mode from '' to '0644'
      - change owner from '' to 'root'
      - change group from '' to 'root'
      - restore selinux security context
  
  * nginx_service[nginx] action start (up to date)
  * service[nginx] action enable
    - enable service service[nginx]
  * template[/etc/nginx/conf.http.d/list.conf] action create
    - create new file /etc/nginx/conf.http.d/list.conf
    - update content in file /etc/nginx/conf.http.d/list.conf from none to 9399eb
    --- /etc/nginx/conf.http.d/list.conf	2023-08-28 13:23:01.229084665 +0000
    +++ /etc/nginx/conf.http.d/.chef-list20230828-3809-3msmzx.conf	2023-08-28 13:23:01.229084665 +0000
    @@ -1 +1,9 @@
    +#
    +# Generated by Chef for ip-10-0-1-13.ap-northeast-1.compute.internal
    +# Do NOT modify this file by hand, changes will be overwritten.
    +#
    +
    +# Include files
    +include /etc/nginx/conf.http.d/default-site.conf;
    +include /etc/nginx/conf.http.d/test_site.conf;
    - change mode from '' to '0640'
    - change owner from '' to 'root'
    - change group from '' to 'root'
    - restore selinux security context
  * nginx_service[nginx] action reload (up to date)
  * service[nginx] action start
    - start service service[nginx]
  * service[nginx] action reload
    - reload service service[nginx]
[2023-08-28T13:23:01+00:00] WARN: Skipping final node save because override_runlist was given

Running handlers:
Running handlers complete
Infra Phase complete, 18/26 resources updated in 09 seconds
[2023-08-28T13:23:01+00:00] WARN: This release of Chef Infra Client became end of life (EOL) on May 1st 2023. Please update to a supported release to receive new features, bug fixes, and security updates.
INFO: User-specified recipes ran successfully.
Error
tar: This does not look like a tar archive
tar: Skipping to next header
tar: Exiting with failure status due to previous errors
ERROR: Cookbooks could not be extracted with tar. Trying with unzip...
/opt/chef/embedded/lib/ruby/gems/3.0.0/gems/ohai-17.9.1/lib/ohai/plugins/rpm.rb:25: warning: already initialized constant MACROS_MARKER
/opt/chef/embedded/lib/ruby/gems/3.0.0/gems/ohai-17.9.1/lib/ohai/plugins/rpm.rb:25: warning: previous definition of MACROS_MARKER was here
/opt/chef/embedded/lib/ruby/gems/3.0.0/gems/ohai-17.9.1/lib/ohai/plugins/rpm.rb:27: warning: already initialized constant DO_NOT_SPLIT
/opt/chef/embedded/lib/ruby/gems/3.0.0/gems/ohai-17.9.1/lib/ohai/plugins/rpm.rb:27: warning: previous definition of DO_NOT_SPLIT was here

RoleやNodeを指定して実行したい

SSMドキュメント"AWS-ApplyChefRecipes"では残念ながらRoleやNodeのjsonを指定した実行ができません。
SSMドキュメントではAWS所有のドキュメントをベースにカスタマイズしたドキュメントを作成することができます。
次回はRoleやNodeを指定できるカスタムドキュメントの作成について解説します。

Discussion