{ "info": { "author": "Brian Peterson", "author_email": "brian.peterson@cloudshift.cc", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3" ], "description": "# tropoform\n\ntropoform is a tool that provides a [terraform](terraform.io) like interfaces for AWS\nCloud Formation stacks created by [troposphere](https://github.com/cloudtools/troposphere)\n\nYou can create a troposphere script (a python module) that has at least one method: get_template()\nand use tropoform to plan, apply, destroy the cloudformation stack.\n\n### Requirements\n* Python3 - sorry, not going to port this back to python 2.x\n* tropoform - can be installed with pip `pip3 install tropoform`\n\ntropoform installs the following additional libraries that might be useful to developing your \ntropoform scripts\n* [troposphere](https://github.com/cloudtools/troposphere) - to create your cloud formation template. (installed with tropoform)\n* [awacs](https://github.com/cloudtools/awacs) - AWS policy creation library \n* [boto3](https://github.com/boto/boto3) - the python AWS SDK\n\n\n### Installation\nTo install the latest version of tropoform\n```\npip install tropoform --user --upgrade\n```\n\nFor development projects, it is advised to install in a python\n[virtual environment](https://virtualenv.pypa.io/en/latest/)\n\n\nOr you can install from source https://github.com/cloudshiftstrategies/tropoform\n\n### Usage\n\nuse `tropoform -h` for help\n```\n$ tropform -h\nusage: tropoform [-h] [-v]\n {apply,plan,destroy,list,output,parameters,reason} ...\n\noptional arguments:\n -h, --help show this help message and exit\n -v, --verbose get DEBUG logging\n\noperation:\n {apply,plan,destroy,list,output,parameters,reason}\n apply create or update stack\n plan view change plan\n destroy remove stack\n list list stacks\n output view stack outputs\n parameters list parameters used in a stack\n reason list reasons for failed stack\n```\n\nsee detailed usage help for an opration `tropoform apply -h`\n```\nusage: tropoform apply [-h] [-m MODULE_NAME] [-p PARAMETER_FILES]\n [-c CAPABILITIES] [-r REGION] [--auto_approve]\n stack_name\n\npositional arguments:\n stack_name The name of the cloud formation stack on which to\n perform operation. If a module exists in the current\n working directory that matches the stack_name and has\n a get_template() method, module_name is not required\n\noptional arguments:\n -h, --help show this help message and exit\n -m MODULE_NAME, --module_name MODULE_NAME\n The name of the python troposphere module that will\n create the template. Module must have a get_template()\n method that returns a valid troposphere.Template\n object\n -p PARAMETER_FILES, --parameter_files PARAMETER_FILES\n Comma separated yaml parameter files that will be\n passed to cloud formation as parameters\n -c CAPABILITIES, --capabilities CAPABILITIES\n Comma separated list of AWS capabilities. default:\n CAPABILITY_NAMED_IAM\n -r REGION, --region REGION\n The name of the AWS region to perform operations.\n default is the env variable: AWS_DEFAULT_REGION\n --auto_approve If set, user will not be prompted to approve changes.\n default=False\n```\n\n### Usage Example\n\n1. Create a python script using tropoform that has at least one function called get_template()\n which returns the un-rendered troposphere.Template() object. \n\n In the `example.py` script below, we create an IAM user inside the function get_template() and return\n the completed template object\n\n example.py\n ```python\n from troposphere import Template\n from troposphere import iam\n\n def get_template():\n template = Template()\n template.add_resource(\n iam.User(\n \"testIamUser\",\n UserName=\"tropoform_test_user\"\n )\n )\n return template\n ```\n\n2. Configure your AWS credentials\n https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-credentials.html\n so that you can make API / CLI calls.\n * Test your credentials with an awscli command like `aws s3 ls`\n * or you can test the boto3 python api `python3 -c \"import boto3; client = boto3.client('s3'); print(client.list_buckets())\"`\n\n3. Run a `tropoform plan` on the stack and see that one IAM User resource will be created\n\n ```\n $ tropoform plan myStack -m example.py\n STACK: myStack is not yet deployed\n STACK: myStack creates 1\n # ) action logical_id resource_type\n 1) Create testIamUser AWS::IAM::User\n ```\n\n4. Use `tropofrom apply` (create) the stack\n\n ```\n $ tropoform apply myStack -m example.py\n STACK: myStack, Current Status: None\n CREATING Stack: myStack with 1 resources\n Are you sure? [yes|no] yes\n STACK: myStack, Status: CREATE_IN_PROGRESS - 16:36:10\n STACK: myStack, Status: CREATE_IN_PROGRESS - 16:36:25\n STACK: myStack, Status: CREATE_COMPLETE - 16:36:41\n STACK: myStack deployed 1 resources in 00:00:48\n STACK OUTPUTS:\n ```\n\n5. Use `tropoform list` to see stacks that are applied. Notice it is in status CREATE_COMPLETE\n ```\n $ tropoform list\n stack_name stack_status drift_status stack_description\n myStack CREATE_COMPLETE NOT_CHECKED \n ```\n\n6. Update the example.template and add another resource\n\n example.py\n ```python\n from troposphere import Template\n from troposphere import iam\n\n def get_template():\n template = Template()\n template.add_resource(\n iam.User(\n \"testIamUser\",\n UserName=\"tropoform_test_user\"\n )\n )\n template.add_resource(\n iam.User(\n \"testIamUser2\",\n UserName=\"tropoform_test_user2\"\n )\n )\n return template\n ```\n\n and run a new `tropoform plan`. Notice that it will add one new resource.\n ```\n $ tropoform plan myStack -m example.py\n STACK: myStack has 1 detected changes\n # ) action logical_id resource_id resource_type scope Replace?\n 1) Add testIamUser2 AWS::IAM::User [] \n ```\n\n7. `tropoform apply` the changes and then use a `tropoform list` to verify\n ```\n $ tropoform apply myStack -m example.py\n STACK: myStack, Current Status: CREATE_COMPLETE\n UPDATING Stack: myStack\n Are you sure? [yes|no] yes\n STACK: myStack, Status: UPDATE_IN_PROGRESS - 16:42:38\n STACK: myStack, Status: UPDATE_IN_PROGRESS - 16:42:54\n STACK: myStack, Status: UPDATE_COMPLETE - 16:43:09\n STACK: myStack updated 2 resources in 00:00:48\n STACK OUTPUTS:\n\n $ tropoform list\n stack_name stack_status drift_status stack_description\n myStack UPDATE_COMPLETE NOT_CHECKED \n ```\n8. `destroy` the stack when you are done with it\n ```\n $ tropoform destroy myStack\n DELETING STACK: myStack with 2 resources\n Are you sure? [yes|no] yes\n STACK: myStack, Status: UPDATE_COMPLETE - 16:44:37\n STACK: myStack deleted in 00:00:15\n\n ```\n\n#### Additional features \n1. Parameter files\n\n Often cloudformation templates will require parameters so that they can be easily\n reusable. You can create yaml based files with key: value pairs and add them as \n arguments to the `tropoform plan` and `tropoform apply` operations\n\n example_parms1.yaml\n ```yaml\n Parm1: Parameter 1\n Parm2: \"2\"\n ```\n\n example_parms2.yaml\n ```yaml\n Parm3: Parameter 3\n Parm4: \"4\"\n ```\n\n Using the parameter files in an apply\n ```\n $ tropoform apply myStack -m example.py -p example_parms1.yaml,example_parms2.yaml\n\n ```\n\n2. Capabilities\n\n Cloud formation stacks may require acknowledgement that it will create resources of\n certain types. The most common is CAPABILITIES_NAMED_IAM which authorizes cloud formation\n to create IAM resources. This is included by default in tropoform. But if your stack\n requires additional capabilities, you can include them with the `-c` argument. See more\n information about capabilities in this documentation:\n https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_CreateStack.html\n\n Using additional capabilities in an apply\n ```\n $ tropoform apply myStack -m example.py -c CAPABILITY_NAMED_IAM,CAPABILITY_AUTO_EXPAND\n\n ```\n\n3. Regions\n\n By default, troposphere will read the environment variable AWS_DEFAULT_REGION to determine\n where to manage stacks. But if you want to specify a different region for an operation\n pass the '-r' or '--region' argument\n\n Specifying a region in a list command\n ```\n $ tropoform list -r us-east-2\n\n ```\n\n4. Stack Names and Module Name\n\n If the name you want to specify for your cloudformation stack is in the current\n working directory and has the same name as the troposphere script, then you can omit\n the module_name parameter\n\n Example of creating a cloud formation stack called \"example\" when \"example.py\" troposphere\n script exists in the current working directory\n ```\n $ tropoform apply example\n\n ```\n\n Example of creating a cloud formation stack called \"myStack\" when \"example.py\" troposphere\n script exists in some filesystem location\n ```\n $ tropoform apply myStack -m ../scripts/example.py\n\n ```\n\n5. Auto Approve\n\n Sometimes when running tropoform in automated scripts, you dont want to be prompted to say\n yes to confirm the `apply` or `destroy` operation\n\n Example `--auto_approve`\n ```\n $ tropoform apply example --auto_approve\n ```\n\n6. Reason for failures\n\n If your cloudformation stack fails to apply for some reason, the cloudformation event(s)\n that caused the will be printed.\n\n In the example below, we tried to attach a ManagedIamPolicy that is intentionally misspelled\n ```\n $ tropoform apply myStack -m example.py\n STACK: myStack, Current Status: None\n CREATING Stack: myStack with 1 resources\n Are you sure? [yes|no] yes\n STACK: myStack, Status: CREATE_IN_PROGRESS - 17:32:22\n STACK: myStack, Status: CREATE_IN_PROGRESS - 17:32:38\n STACK: myStack, Status: ROLLBACK_COMPLETE - 17:32:54\n STACK: myStack not deployed and is in status ROLLBACK_COMPLETE\n STACK myStack create/update FAILED due to the following stack events:\n UTC time ResourceStatus ResourceType LogicalResourceId ResourceStatusReason\n 22:32:47 CREATE_FAILED AWS::IAM::User testIamUser Policy arn:aws:iam::aws:policy/AdministratorAcces does not exist or is not attachable. \n ```\n\n You can use the `tropoform reason` operation to look up the status of a failed stack\n ```\n $ tropoform reason myStack\n STACK myStack create/update FAILED due to the following stack events:\n UTC time ResourceStatus ResourceType LogicalResourceId ResourceStatusReason\n 22:32:47 CREATE_FAILED AWS::IAM::User testIamUser Policy arn:aws:iam::aws:policy/AdministratorAcces does not exist or is not attachable.\n ```\n\n7. Parameters\n\n If your stack was deployed with parameters, you can check those paramaters with the \n `tropoform parameters` operation\n ``` \n $ tropoform parameters myStack\n STACK: myStack Parameters: \n Parm1 = value1 \n ```\n\n8. Outputs\n\n If your stack specifies Output parameters, when the stack is done deploying, the outputs\n will be printed.\n ``` \n $ tropoform apply myStack -m example.py --auto_approve\n STACK: myStack, Current Status: None\n CREATING Stack: myStack with 1 resources\n STACK: myStack, Status: CREATE_IN_PROGRESS - 17:40:44\n STACK: myStack, Status: CREATE_IN_PROGRESS - 17:40:59\n STACK: myStack, Status: CREATE_COMPLETE - 17:41:15\n STACK: myStack deployed 1 resources in 00:00:48\n STACK OUTPUTS:\n userArn = arn:aws:iam::357849880876:user/tropoform_test_user\n ```\n\n If you want to access those outputs later, you can run `tropoform output`\n ``` \n $ tropoform output myStack\n STACK OUTPUTS:\n userArn = arn:aws:iam::357849880876:user/tropoform_test_user\n ```\n\n\n### Contributions welcome!\nOpen issues and send pull requests via the github repo https://github.com/cloudshiftstrategies/tropoform\n\n### Build Instructions\n\n```\n# Clone the repo\ngit clone https://github.com/cloudshiftstrategies/tropoform\ncd tropoform\n\n# Setup virtual environment\npipenv shell\n\n# Edit code. Main script is in: tropoform/tropoform.py\n\n# Test (requires current AWS credentials in an account where test stack can create/delete\npython3 -m unittest test\n\n# Create new version\n # edit __version__ in tropoform/tropoform.py\n # edit version in setup.py\n\n# Build\npython3 setup.py sdist bdist_wheel\n\n# Test local install\npython3 setup.py install\n\n# tag release\ngit add .\ngit commit -m \"xxx\"\ngitchangelog > Changelog.rst \n# update version in Changelog.rst\ngit commit -am \"updated changelog\"\ngit tag X.Y.Z -m \"xxx\"\ngit push && git push --tags\n\n# Publish to PyPy\ntwine upload --repository test dist/tropoform-X.Y.Z*\ntwine upload --repository pypi dist/tropoform-X.Y.Z*\n```\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/cloudshiftstrategies/tropoform", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "tropoform", "package_url": "https://pypi.org/project/tropoform/", "platform": "", "project_url": "https://pypi.org/project/tropoform/", "project_urls": { "Homepage": "https://github.com/cloudshiftstrategies/tropoform" }, "release_url": "https://pypi.org/project/tropoform/0.2.6/", "requires_dist": [ "boto3", "botocore", "troposphere", "awacs", "PyYAML", "colorlog" ], "requires_python": ">=3", "summary": "A Terraform like utility for managing AWS Cloud Formation Stacks with troposphere", "version": "0.2.6" }, "last_serial": 5156608, "releases": { "0.1.11": [ { "comment_text": "", "digests": { "md5": "1fd8fb48ce612983054609867f13c6b7", "sha256": "e262a38e7dd08a8b06e037debccfe3e286821e81068e20e21c371528cfc5c480" }, "downloads": -1, "filename": "tropoform-0.1.11-py3-none-any.whl", "has_sig": false, "md5_digest": "1fd8fb48ce612983054609867f13c6b7", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 30974, "upload_time": "2019-04-13T07:47:53", "url": "https://files.pythonhosted.org/packages/74/a2/0e86ea5af9f7ee76539485e44fd9c4bd133e5253b0fc3d87526c1eb362e2/tropoform-0.1.11-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8727f2f3e419ac56ef4ee73265239548", "sha256": "ca1926f17e83adefe4322ba20fed5182f014946a685f22fa6b60d4e1330f0ad6" }, "downloads": -1, "filename": "tropoform-0.1.11.tar.gz", "has_sig": false, "md5_digest": "8727f2f3e419ac56ef4ee73265239548", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 8719, "upload_time": "2019-04-13T07:47:54", "url": "https://files.pythonhosted.org/packages/d5/0e/e2ffd0fabe7ccc725e39b7dc4dff4e1b11303fa0baead0664d93399bf47e/tropoform-0.1.11.tar.gz" } ], "0.2.3": [ { "comment_text": "", "digests": { "md5": "964d1d43ce3184d1267efdcc8d958e12", "sha256": "aa6bf0bc829b8e4cf0078419a079560296aa67f0be6b827211dbb62f6f50f7c6" }, "downloads": -1, "filename": "tropoform-0.2.3-py3-none-any.whl", "has_sig": false, "md5_digest": "964d1d43ce3184d1267efdcc8d958e12", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 37091, "upload_time": "2019-04-14T03:57:31", "url": "https://files.pythonhosted.org/packages/5a/41/eb098b4eda3aba2ee623d7076155a40bc51675ca75b68a2801f0fed0afbb/tropoform-0.2.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8519f5924ea074d92b62e020f418ae42", "sha256": "0a0fcfe3b9057b462bdfd5c246d7c7b1e69d7780765e3803f199058f86cfad90" }, "downloads": -1, "filename": "tropoform-0.2.3.tar.gz", "has_sig": false, "md5_digest": "8519f5924ea074d92b62e020f418ae42", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 21526, "upload_time": "2019-04-14T03:57:32", "url": "https://files.pythonhosted.org/packages/88/b8/90cf69e5b90bd1fa2db2b78ffeab21c5c0403d2e1e23591ce33f1b904542/tropoform-0.2.3.tar.gz" } ], "0.2.4": [ { "comment_text": "", "digests": { "md5": "d16f72aa0372791af259ed9b6b9de55e", "sha256": "b369c1e5adb4f5b339658dfbf8aae64dadf5c0307352e4abd5f85f1df55451b6" }, "downloads": -1, "filename": "tropoform-0.2.4-py3-none-any.whl", "has_sig": false, "md5_digest": "d16f72aa0372791af259ed9b6b9de55e", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 37090, "upload_time": "2019-04-17T15:40:17", "url": "https://files.pythonhosted.org/packages/80/e4/9fc7b2f3896221fc3317467618c68aed932fc23c6e3fe6b3aa49a4c88af7/tropoform-0.2.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "3ffa29b6d983f3d4e698183263db61a0", "sha256": "44b8848b25053b3901c8a76f6529f23aea8d5dbab15463bea105439633b125e0" }, "downloads": -1, "filename": "tropoform-0.2.4.tar.gz", "has_sig": false, "md5_digest": "3ffa29b6d983f3d4e698183263db61a0", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 21548, "upload_time": "2019-04-17T15:40:20", "url": "https://files.pythonhosted.org/packages/f4/ef/e85b1e88244e9769c5ece2133fcdf53392e45d16e9c34ad2abb91935444d/tropoform-0.2.4.tar.gz" } ], "0.2.5": [ { "comment_text": "", "digests": { "md5": "88e3f83e1e7e8499bbb1e8048b6877d4", "sha256": "987ac29f9aa6440c1cd931891b82e957a1907d9f65a7353c99f3dde6119eb7de" }, "downloads": -1, "filename": "tropoform-0.2.5-py3-none-any.whl", "has_sig": false, "md5_digest": "88e3f83e1e7e8499bbb1e8048b6877d4", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 37129, "upload_time": "2019-04-17T15:57:49", "url": "https://files.pythonhosted.org/packages/9f/b4/da07ab20ed92bc276bc96bfabafdc8bfbe43491d946221bc0a06b13e888e/tropoform-0.2.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f19411684efb371278a4451e75fc6b5a", "sha256": "b7681a5157da57e81902c86a414205423e1a653550198cb1f06e83407294393d" }, "downloads": -1, "filename": "tropoform-0.2.5.tar.gz", "has_sig": false, "md5_digest": "f19411684efb371278a4451e75fc6b5a", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 21670, "upload_time": "2019-04-17T15:57:50", "url": "https://files.pythonhosted.org/packages/db/2c/35fcef64f91b4c272cc112dd0b464f4d43019784bdcc0c349b03099a1468/tropoform-0.2.5.tar.gz" } ], "0.2.6": [ { "comment_text": "", "digests": { "md5": "d2d9507bf9649184d16715a3699bff04", "sha256": "c332d0d4eb002a5388409c621935c7b225c8f6ee628afe192b18ecc0442b8492" }, "downloads": -1, "filename": "tropoform-0.2.6-py3-none-any.whl", "has_sig": false, "md5_digest": "d2d9507bf9649184d16715a3699bff04", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 37135, "upload_time": "2019-04-17T18:32:17", "url": "https://files.pythonhosted.org/packages/13/15/12ecfb3197a10f72a8395afd760428026cb296144bf53bdb04209740525d/tropoform-0.2.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "11096f59f435e0e5c60c9d4cb8699bfd", "sha256": "9e1923760293b0202d6fd0a37c79670970c812a435ea2e2438792b679fd0dbfd" }, "downloads": -1, "filename": "tropoform-0.2.6.tar.gz", "has_sig": false, "md5_digest": "11096f59f435e0e5c60c9d4cb8699bfd", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 21676, "upload_time": "2019-04-17T18:32:19", "url": "https://files.pythonhosted.org/packages/b9/13/36d8f32e868b52e8869917a36c39bf33713bdd50092bbd4c44c8b845fb76/tropoform-0.2.6.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d2d9507bf9649184d16715a3699bff04", "sha256": "c332d0d4eb002a5388409c621935c7b225c8f6ee628afe192b18ecc0442b8492" }, "downloads": -1, "filename": "tropoform-0.2.6-py3-none-any.whl", "has_sig": false, "md5_digest": "d2d9507bf9649184d16715a3699bff04", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 37135, "upload_time": "2019-04-17T18:32:17", "url": "https://files.pythonhosted.org/packages/13/15/12ecfb3197a10f72a8395afd760428026cb296144bf53bdb04209740525d/tropoform-0.2.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "11096f59f435e0e5c60c9d4cb8699bfd", "sha256": "9e1923760293b0202d6fd0a37c79670970c812a435ea2e2438792b679fd0dbfd" }, "downloads": -1, "filename": "tropoform-0.2.6.tar.gz", "has_sig": false, "md5_digest": "11096f59f435e0e5c60c9d4cb8699bfd", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 21676, "upload_time": "2019-04-17T18:32:19", "url": "https://files.pythonhosted.org/packages/b9/13/36d8f32e868b52e8869917a36c39bf33713bdd50092bbd4c44c8b845fb76/tropoform-0.2.6.tar.gz" } ] }