The idea of Chef is to automate the whole process; it is rare that any single individual knows everything in such a large infrastructure. Also, Chef has a large community that participates to solve large problems.
The basic principle of Chef is that the user knows each bit of the environment; for example which are the packages that need to be installed, requirements of your applications, and so on. The best person for any application development is the team who developed the system. While creating a system, they can write down the requirements and easily convert them into Ruby code.
Moreover, any large organization uses a number of different packages to handle web applications, for instance, you have a Python application, running on Nginx, using uWSGI, caching with memcahe and redis, and using Elasticsearch for quick search.
All the mentioned packages have a list of dependencies. Once you have the recipes, you can run them once or several times on the same system and the results will be identical. The chef-client keeps track of the changes in resources. If any resource item is updated, then it runs the resource again and marks it as successful.
Chef is designed on a Thin Server, Thick Client approach. The client does not need continuous communication to the server. Once the client receives the set of instructions (cookbooks), it will execute and report to the server. The server is responsible for the distribution of cookbooks, templates, environments, and so on, via the workstation. Also, the server will keep a copy of all configurations.
Moreover, while creating the recipes, an order should be maintained. As we have already discussed, recipes are based on several resources. Each resource contains a set of actions and are executed one by one. The resources execute sequentially and the order needs to be maintained. For example, if you try to install PostgreSQL before
libpq-dev, you will get the error of missing dependency and the recipe script will exit with an error.