著者は、Write for DOnationsプログラムの一部として寄付を受け取るためにMozilla Foundationを選択しました。
前書き
Ansibleは、YAMLテンプレートを使用して、ホストで実行されるタスクのリストを定義するエージェントレス構成管理ツールです。 Ansibleでは、rolesは変数、タスク、ファイル、テンプレート、およびモジュールのコレクションであり、これらを一緒に使用して、単一の複雑な機能を実行します。
Moleculeは、Ansibleロールの自動テストを実行するためのツールであり、一貫して適切に記述され、維持されているロールの開発をサポートするように特別に設計されています。 Moleculeのユニットテストにより、開発者は複数の環境に対して異なるパラメーターでロールを同時にテストできます。 開発者は、頻繁に変更されるコードに対してテストを継続的に実行することが重要です。このワークフローにより、コードライブラリを更新してもロールが引き続き機能します。 Travis CIなどの継続的インテグレーションツールを使用してMoleculeを実行すると、テストを継続的に実行できるため、コードへの貢献によって重大な変更が発生することはありません。
このチュートリアルでは、UbuntuサーバーとCentOSサーバーにApache Webサーバーとファイアウォールをインストールして構成する、事前に作成されたベースロールを使用します。 次に、そのロールのMoleculeシナリオを初期化してテストを作成し、ロールがターゲット環境で意図したとおりに実行されることを確認します。 Moleculeを構成したら、Travis CIを使用して、新しく作成したロールを継続的にテストします。 コードに変更が加えられるたびに、Travis CIはmolecule test
を実行して、役割が引き続き正しく実行されることを確認します。
前提条件
このチュートリアルを始める前に、次のものが必要です。
-
sudo非rootユーザーとファイアウォールを含むUbuntu 18.04 Initial Server Setupガイドに従ってセットアップされた1つのUbuntu18.04サーバー。
-
AnsibleとMoleculeが構成されています。これは、How To Test Ansible Roles with Molecule on Ubuntu 18.04のステップ1に従って実行できます。
-
How To Contribute to Open Source: Getting Started with Gitに従ってインストールされたGit。
-
継続的インテグレーションとその使用事例に精通している。 詳細については、An Introduction to Continuous Integration, Delivery, and Deploymentを確認してください。
-
GitHubのアカウント。
-
Travis CIのアカウント。
[[step-1 -—- forking-the-base-role-repository]] ==ステップ1—基本ロールリポジトリをフォークする
Apacheをインストールし、DebianベースおよびRedHatベースのディストリビューションにファイアウォールを構成するansible-apacheと呼ばれる事前に作成されたロールを使用します。 このロールを分岐してベースとして使用し、その上でMoleculeテストをビルドします。 フォークを使用すると、リポジトリのコピーを作成して、元のプロジェクトを変更せずにリポジトリに変更を加えることができます。
ansible-apacheロールのフォークを作成することから始めます。 ansible-apacheリポジトリに移動し、Forkボタンをクリックします。
リポジトリをフォークすると、GitHubからフォークのページに移動します。 これは基本リポジトリのコピーですが、自分のアカウントにあります。
緑色のClone or Downloadボタンをクリックすると、Clone with HTTPSのボックスが表示されます。
リポジトリに表示されているURLをコピーします。 次のステップでこれを使用します。 URLは次のようになります。
https://github.com/username/ansible-apache.git
username
をGitHubユーザー名に置き換えます。
フォークをセットアップしたら、サーバー上でフォークを複製し、次のセクションでロールの準備を開始します。
[[step-2 -—- preparing-your-role]] ==ステップ2—役割の準備
前提条件のHow To Test Ansible Roles with Molecule on Ubuntu 18.04のステップ1に従うと、MoleculeとAnsibleが仮想環境にインストールされます。 この仮想環境を使用して、新しい役割を開発します。
まず、以下を実行して、前提条件に従って作成した仮想環境をアクティブにします。
source my_env/bin/activate
次のコマンドを実行して、手順1でコピーしたURLを使用してリポジトリをクローニングします。
git clone https://github.com/username/ansible-apache.git
出力は次のようになります。
OutputCloning into 'ansible-apache'...
remote: Enumerating objects: 16, done.
remote: Total 16 (delta 0), reused 0 (delta 0), pack-reused 16
Unpacking objects: 100% (16/16), done.
新しく作成したディレクトリに移動します。
cd ansible-apache
ダウンロードした基本役割は、次のタスクを実行します。
-
Includes variables:役割は、ホストの分布に従って、必要なすべてのvariablesを含めることから始まります。 Ansibleは変数を使用して、異なるシステム間の格差を処理します。 Ubuntu18.04とCentOS7をホストとして使用しているため、ロールはOSファミリがそれぞれDebianとRed Hatであり、
vars/Debian.yml
とvars/RedHat.yml
の変数を含むことを認識します。 -
Includes distribution-relevant tasks:これらのタスクには
tasks/install-Debian.yml
とtasks/install-RedHat.yml
が含まれます。 指定されたディストリビューションに応じて、関連するパッケージがインストールされます。 Ubuntuの場合、これらのパッケージはapache2
とufw
です。 CentOSの場合、これらのパッケージはhttpd
とfirewalld
です。 -
Ensures latest index.html is present:このタスクは、ApacheがWebサーバーのホームページとして使用するテンプレート
templates/index.html.j2
をコピーします。 -
Starts relevant services and enables them on boot:最初のタスクの一部としてインストールされた必要なサービスを開始して有効にします。 CentOSの場合、これらのサービスは
httpd
とfirewalld
であり、Ubuntuの場合、これらはapache2
とufw
です。 -
Configures firewall to allow traffic:これには
tasks/configure-Debian-firewall.yml
またはtasks/configure-RedHat-firewall.yml
のいずれかが含まれます。 Ansibleは、FirewalldまたはUFWのいずれかをファイアウォールとして構成し、http
サービスをホワイトリストに登録します。
この役割がどのように機能するか理解できたので、Moleculeを設定してテストします。 これらのタスクのテストケースを作成して、それらが行う変更をカバーします。
[[step-3 -—- writing-your-tests]] ==ステップ3—テストを書く
基本ロールが意図したとおりにタスクを実行することを確認するには、Moleculeシナリオを開始し、ターゲット環境を指定して、3つのカスタムテストファイルを作成します。
次のコマンドを使用して、このロールの分子シナリオを初期化することから始めます。
molecule init scenario -r ansible-apache
次の出力が表示されます。
Output--> Initializing new scenario default...
Initialized scenario in /home/sammy/ansible-apache/molecule/default successfully.
Molecule構成ファイルにプラットフォームとして含めることにより、CentOSとUbuntuをターゲット環境として追加します。 これを行うには、テキストエディタを使用してmolecule.yml
ファイルを編集します。
nano molecule/default/molecule.yml
次の強調表示されたコンテンツをMolecule構成に追加します。
~/ansible-apache/molecule/default/molecule.yml
---
dependency:
name: galaxy
driver:
name: docker
lint:
name: yamllint
platforms:
- name: centos7
image: milcom/centos7-systemd
privileged: true
- name: ubuntu18
image: solita/ubuntu-systemd
command: /sbin/init
privileged: true
volumes:
- /lib/modules:/lib/modules:ro
provisioner:
name: ansible
lint:
name: ansible-lint
scenario:
name: default
verifier:
name: testinfra
lint:
name: flake8
ここでは、systemdサービスを使用しているため、特権モードで起動される2つのターゲットプラットフォームを指定しています。
-
centos7
は最初のプラットフォームであり、milcom/centos7-systemd
イメージを使用します。 -
ubuntu18
は2番目のプラットフォームであり、solita/ubuntu-systemd
イメージを使用します。 特権モードを使用して必要なカーネルモジュールをマウントすることに加えて、起動時に/sbin/init
を実行して、iptablesが稼働していることを確認します。
ファイルを保存して終了します。
特権コンテナーの実行の詳細については、official Molecule documentationにアクセスしてください。
デフォルトのMoleculeテストファイルを使用する代わりに、ターゲットプラットフォームごとに1つのカスタムテストファイルを作成し、すべてのプラットフォームに共通のテストを作成するために1つのファイルを作成します。 次のコマンドを使用して、シナリオのデフォルトのテストファイルtest_default.py
を削除することから始めます。
rm molecule/default/tests/test_default.py
これで、ターゲットプラットフォームごとに3つのカスタムテストファイルtest_common.py
、test_Debian.py
、およびtest_RedHat.py
の作成に進むことができます。
最初のテストファイルtest_common.py
には、各ホストが実行する共通のテストが含まれます。 共通のテストファイルtest_common.py
を作成および編集します。
nano molecule/default/tests/test_common.py
ファイルに次のコードを追加します。
~/ansible-apache/molecule/default/tests/test_common.py
import os
import pytest
import testinfra.utils.ansible_runner
testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all')
@pytest.mark.parametrize('file, content', [
("/var/www/html/index.html", "Managed by Ansible")
])
def test_files(host, file, content):
file = host.file(file)
assert file.exists
assert file.contains(content)
test_common.py
ファイルに、必要なライブラリをインポートしました。 また、test_files()
というテストを作成しました。これは、役割が実行するディストリビューション間の唯一の共通タスクである、テンプレートをWebサーバーのホームページとしてコピーすることを保持します。
次のテストファイルtest_Debian.py
は、Debianディストリビューションに固有のテストを保持しています。 このテストファイルは、特にUbuntuプラットフォームを対象としています。
次のコマンドを実行して、Ubuntuテストファイルを作成および編集します。
nano molecule/default/tests/test_Debian.py
これで、必要なライブラリをインポートし、ubuntu18
プラットフォームをターゲットホストとして定義できます。 このファイルの先頭に次のコードを追加します。
~/ansible-apache/molecule/default/tests/test_Debian.py
import os
import pytest
import testinfra.utils.ansible_runner
testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('ubuntu18')
次に、同じファイルにtest_pkg()
テストを追加します。
test_pkg()
テストを定義する次のコードをファイルに追加します。
~/ansible-apache/molecule/default/tests/test_Debian.py
...
@pytest.mark.parametrize('pkg', [
'apache2',
'ufw'
])
def test_pkg(host, pkg):
package = host.package(pkg)
assert package.is_installed
このテストでは、apache2
およびufw
パッケージがホストにインストールされているかどうかを確認します。
[.note]#Note: Moleculeテストファイルに複数のテストを追加する場合は、各テストの間に2つの空白行があることを確認してください。そうしないと、Moleculeから構文エラーが発生します。
#
次のテストtest_svc()
を定義するには、ファイルのtest_pkg()
テストの下に次のコードを追加します。
~/ansible-apache/molecule/default/tests/test_Debian.py
...
@pytest.mark.parametrize('svc', [
'apache2',
'ufw'
])
def test_svc(host, svc):
service = host.service(svc)
assert service.is_running
assert service.is_enabled
test_svc()
は、apache2
およびufw
サービスが実行され、有効になっているかどうかを確認します。
最後に、最後のテストtest_ufw_rules()
をtest_Debian.py
ファイルに追加します。
ファイルのtest_svc()
テストで次のコードを追加して、test_ufw_rules()
を定義します。
~/ansible-apache/molecule/default/tests/test_Debian.py
...
@pytest.mark.parametrize('rule', [
'-A ufw-user-input -p tcp -m tcp --dport 80 -j ACCEPT'
])
def test_ufw_rules(host, rule):
cmd = host.run('iptables -t filter -S')
assert rule in cmd.stdout
test_ufw_rules()
は、ファイアウォール構成がApacheサービスによって使用されるポートでのトラフィックを許可することを確認します。
これらの各テストを追加すると、test_Debian.py
ファイルは次のようになります。
~/ansible-apache/molecule/default/tests/test_Debian.py
import os
import pytest
import testinfra.utils.ansible_runner
testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('ubuntu18')
@pytest.mark.parametrize('pkg', [
'apache2',
'ufw'
])
def test_pkg(host, pkg):
package = host.package(pkg)
assert package.is_installed
@pytest.mark.parametrize('svc', [
'apache2',
'ufw'
])
def test_svc(host, svc):
service = host.service(svc)
assert service.is_running
assert service.is_enabled
@pytest.mark.parametrize('rule', [
'-A ufw-user-input -p tcp -m tcp --dport 80 -j ACCEPT'
])
def test_ufw_rules(host, rule):
cmd = host.run('iptables -t filter -S')
assert rule in cmd.stdout
test_Debian.py
ファイルには、test_pkg()
、test_svc()
、およびtest_ufw_rules()
の3つのテストが含まれるようになりました。
test_Debian.py
を保存して終了します。
次に、test_RedHat.py
テストファイルを作成します。このファイルには、CentOSプラットフォームを対象とするRedHatディストリビューションに固有のテストが含まれています。
次のコマンドを実行して、CentOSテストファイルtest_RedHat.py
を作成および編集します。
nano molecule/default/tests/test_RedHat.py
Ubuntuテストファイルと同様に、test_RedHat.py
ファイルに含める3つのテストを作成します。 テストコードを追加する前に、ファイルの先頭に次のコードを追加することで、必要なライブラリをインポートし、centos7
プラットフォームをターゲットホストとして定義できます。
~/ansible-apache/molecule/default/tests/test_RedHat.py
import os
import pytest
import testinfra.utils.ansible_runner
testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('centos7')
次に、test_pkg()
テストを追加します。このテストでは、httpd
およびfirewalld
パッケージがホストにインストールされているかどうかを確認します。
ライブラリインポートのコードに従って、test_pkg()
テストをファイルに追加します。 (繰り返しますが、それぞれの新しいテストの前に2つの空白行を含めることを忘れないでください。)
~/ansible-apache/molecule/default/tests/test_RedHat.py
...
@pytest.mark.parametrize('pkg', [
'httpd',
'firewalld'
])
def test_pkg(host, pkg):
package = host.package(pkg)
assert package.is_installed
これで、test_svc()
テストを追加して、httpd
およびfirewalld
サービスが実行されて有効になっていることを確認できます。
test_pkg()
テストに続いて、test_svc()
コードをファイルに追加します。
~/ansible-apache/molecule/default/tests/test_RedHat.py
...
@pytest.mark.parametrize('svc', [
'httpd',
'firewalld'
])
def test_svc(host, svc):
service = host.service(svc)
assert service.is_running
assert service.is_enabled
test_RedHat.py
ファイルの最終テストはtest_firewalld()
になり、Firewalldにhttp
サービスがホワイトリストに登録されているかどうかがチェックされます。
test_svc()
コードの後に、ファイルにtest_firewalld()
テストを追加します。
~/ansible-apache/molecule/default/tests/test_RedHat.py
...
@pytest.mark.parametrize('file, content', [
("/etc/firewalld/zones/public.xml", "")
])
def test_firewalld(host, file, content):
file = host.file(file)
assert file.exists
assert file.contains(content)
ライブラリをインポートして3つのテストを追加すると、test_RedHat.py
ファイルは次のようになります。
~/ansible-apache/molecule/default/tests/test_RedHat.py
import os
import pytest
import testinfra.utils.ansible_runner
testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('centos7')
@pytest.mark.parametrize('pkg', [
'httpd',
'firewalld'
])
def test_pkg(host, pkg):
package = host.package(pkg)
assert package.is_installed
@pytest.mark.parametrize('svc', [
'httpd',
'firewalld'
])
def test_svc(host, svc):
service = host.service(svc)
assert service.is_running
assert service.is_enabled
@pytest.mark.parametrize('file, content', [
("/etc/firewalld/zones/public.xml", "")
])
def test_firewalld(host, file, content):
file = host.file(file)
assert file.exists
assert file.contains(content)
これで、test_common.py
、test_Debian.py
、およびtest_RedHat.py
の3つのファイルすべてでテストの記述が完了したので、役割をテストする準備が整いました。 次のステップでは、Moleculeを使用して、新しく構成されたロールに対してこれらのテストを実行します。
[[step-4 -—- testing-against-your-role]] ==ステップ4—あなたの役割に対するテスト
ここで、Moleculeを使用して、基本ロールansible-apache
に対して新しく作成したテストを実行します。 テストを実行するには、次のコマンドを使用します。
molecule test
Moleculeがすべてのテストの実行を完了すると、次の出力が表示されます。
Output...
--> Scenario: 'default'
--> Action: 'verify'
--> Executing Testinfra tests found in /home/sammy/ansible-apache/molecule/default/tests/...
============================= test session starts ==============================
platform linux -- Python 3.6.7, pytest-4.1.1, py-1.7.0, pluggy-0.8.1
rootdir: /home/sammy/ansible-apache/molecule/default, inifile:
plugins: testinfra-1.16.0
collected 12 items
tests/test_common.py .. [ 16%]
tests/test_RedHat.py ..... [ 58%]
tests/test_Debian.py ..... [100%]
========================== 12 passed in 80.70 seconds ==========================
Verifier completed successfully.
出力にVerifier completed successfully
が表示されます。これは、ベリファイアがすべてのテストを実行し、それらを正常に返したことを意味します。
役割の開発が正常に完了したので、Gitに変更をコミットし、継続的なテストのためにTravis CIをセットアップできます。
[[step-5 --- using-git-to-share-your-updated-role]] ==ステップ5—Gitを使用して更新された役割を共有する
このチュートリアルでは、これまで、ansible-apache
という役割のクローンを作成し、UbuntuおよびCentOSホストに対して機能することを確認するためのテストを追加しました。 更新されたロールをパブリックと共有するには、これらの変更をコミットしてフォークにプッシュする必要があります。
次のコマンドを実行してファイルを追加し、行った変更をコミットします。
git add .
このコマンドは、現在のディレクトリで変更したすべてのファイルをステージング領域に追加します。
また、正常にコミットするには、名前と電子メールアドレスをgit config
に設定する必要があります。 これを行うには、次のコマンドを使用します。
git config user.email "[email protected]"
git config user.name "John Doe"
変更したファイルをリポジトリにコミットします。
git commit -m "Configured Molecule"
次の出力が表示されます。
Output[master b2d5a5c] Configured Molecule
8 files changed, 155 insertions(+), 1 deletion(-)
create mode 100644 molecule/default/Dockerfile.j2
create mode 100644 molecule/default/INSTALL.rst
create mode 100644 molecule/default/molecule.yml
create mode 100644 molecule/default/playbook.yml
create mode 100644 molecule/default/tests/test_Debian.py
create mode 100644 molecule/default/tests/test_RedHat.py
create mode 100644 molecule/default/tests/test_common.py
これは、変更を正常にコミットしたことを意味します。 次のコマンドを使用して、これらの変更をフォークにプッシュします。
git push -u origin master
GitHub資格情報のプロンプトが表示されます。 これらの資格情報を入力すると、コードがリポジトリにプッシュされ、次の出力が表示されます。
OutputCounting objects: 13, done.
Compressing objects: 100% (12/12), done.
Writing objects: 100% (13/13), 2.32 KiB | 2.32 MiB/s, done.
Total 13 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), completed with 2 local objects.
To https://github.com/username/ansible-apache.git
009d5d6..e4e6959 master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
フォークのリポジトリ(github.com/username/ansible-apache
)に移動すると、ファイルに加えた変更を反映したConfigured Molecule
という新しいコミットが表示されます。
これで、Travis CIを新しいリポジトリに統合して、ロールに加えられた変更が自動的にMoleculeテストをトリガーできるようにすることができます。 これにより、ロールが常にUbuntuおよびCentOSホストで機能するようになります。
[[step-6 -—- integrating-travis-ci]] ==ステップ6— TravisCIの統合
このステップでは、Travis CIをワークフローに統合します。 有効にすると、フォークにプッシュした変更はTravis CIビルドをトリガーします。 これの目的は、寄稿者が変更を加えるたびにTravis CIが常にmolecule test
を実行するようにすることです。 重大な変更が行われた場合、Travisはビルドステータスを宣言します。
Travis CIに進んで、リポジトリを有効にします。 GitHubのActivateボタンをクリックできるプロファイルページに移動します。
Travis CIでリポジトリをアクティブ化するための詳細なガイダンスhereを見つけることができます。
Travis CIを機能させるには、そのための指示を含む構成ファイルを作成する必要があります。 Travis構成ファイルを作成するには、サーバーに戻って次のコマンドを実行します。
nano .travis.yml
このチュートリアルで作成した環境を複製するには、Travis構成ファイルでパラメーターを指定します。 次のコンテンツをファイルに追加します。
~/ansible-apache/.travis.yml
---
language: python
python:
- "2.7"
- "3.6"
services:
- docker
install:
- pip install molecule docker
script:
- molecule --version
- ansible --version
- molecule test
このファイルで指定したパラメーターは次のとおりです。
-
language
:言語としてPythonを指定すると、CI環境はpython
キーで指定したPythonバージョンごとに個別のvirtualenv
インスタンスを使用します。 -
python
:ここでは、TravisがPython2.7とPython3.6の両方を使用してテストを実行することを指定しています。 -
services
:Moleculeでテストを実行するにはDockerが必要です。 TravisがCI環境にDockerが存在することを確認する必要があることを指定しています。 -
install
:ここでは、Travis CIがvirtualenv
で実行する予備インストール手順を指定しています。-
pip install molecule docker
は、DockerリモートAPIのPythonライブラリとともにAnsibleとMoleculeが存在することを確認します。
-
-
script
:これは、TravisCIが実行する必要のあるステップを指定するためのものです。 ファイルでは、3つのステップを指定しています。-
molecule --version
は、Moleculeが正常にインストールされている場合、Moleculeバージョンを出力します。 -
ansible --version
は、Ansibleが正常にインストールされている場合、Ansibleのバージョンを出力します。 -
molecule test
は、最終的にMoleculeテストを実行します。
-
molecule --version
およびansible --version
を指定する理由は、バージョン管理によるansible
またはmolecule
の設定ミスの結果としてビルドが失敗した場合に、エラーをキャッチするためです。
コンテンツをTravisCI構成ファイルに追加したら、.travis.yml
を保存して終了します。
これで、リポジトリに変更をプッシュするたびに、Travis CIは上記の設定ファイルに基づいて自動的にビルドを実行します。 script
ブロック内のコマンドのいずれかが失敗した場合、TravisCIはビルドステータスをそのように報告します。
ビルドステータスを簡単に確認できるように、ロールのREADME
にビルドステータスを示すバッジを追加できます。 テキストエディタを使用してREADME.md
ファイルを開きます。
nano README.md
ビルドステータスを表示するには、README.md
に次の行を追加します。
~/ansible-apache/README.md
[![Build Status](https://travis-ci.org/username/ansible-apache.svg?branch=master)](https://travis-ci.org/username/ansible-apache)
username
をGitHubユーザー名に置き換えます。 以前に行ったように、変更をコミットしてリポジトリにプッシュします。
まず、次のコマンドを実行して、.travis.yml
とREADME.md
をステージング領域に追加します。
git add .travis.yml README.md
次を実行して、リポジトリに変更をコミットします。
git commit -m "Configured Travis"
最後に、次のコマンドを使用して、これらの変更をフォークにプッシュします。
git push -u origin master
GitHubリポジトリに移動すると、最初にbuild: unknownが報告されていることがわかります。
数分以内にTravisはビルドを開始し、Travis CI Webサイトで監視できます。 ビルドが成功すると、GitHubはREADMEファイルに配置したバッジを使用して、リポジトリのステータスも報告します。
Travis CI Webサイトにアクセスして、ビルドの完全な詳細にアクセスできます。
新しい役割にTravis CIを正常に設定したので、Ansibleの役割に対する変更を継続的にテストおよび統合できます。
結論
このチュートリアルでは、GitHubからApache Webサーバーをインストールおよび構成するロールを分岐し、テストを作成してこれらのテストをUbuntuおよびCentOSを実行するDockerコンテナーで構成することにより、Moleculeの統合を追加しました。 新しく作成したロールをGitHubにプッシュすることで、他のユーザーがロールにアクセスできるようになりました。 貢献者によって役割が変更されると、Travis CIは自動的にMoleculeを実行して役割をテストします。
ロールの作成とMoleculeでのテストに慣れたら、これをAnsible Galaxyと統合して、ビルドが成功するとロールが自動的にプッシュされるようにすることができます。