├── .github
├── ISSUE_TEMPLATE.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .vscode
└── launch.json
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
└── src
├── aci_docs_sample.py
└── requirements.txt
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
4 | > Please provide us with the following information:
5 | > ---------------------------------------------------------------
6 |
7 | ### This issue is for a: (mark with an `x`)
8 | ```
9 | - [ ] bug report -> please search issues before submitting
10 | - [ ] feature request
11 | - [ ] documentation issue or request
12 | - [ ] regression (a behavior that used to work and stopped in a new release)
13 | ```
14 |
15 | ### Minimal steps to reproduce
16 | >
17 |
18 | ### Any log messages given by the failure
19 | >
20 |
21 | ### Expected/desired behavior
22 | >
23 |
24 | ### OS and Version?
25 | > Windows 7, 8 or 10. Linux (which distribution). macOS (Yosemite? El Capitan? Sierra?)
26 |
27 | ### Versions
28 | >
29 |
30 | ### Mention any other details that might be useful
31 |
32 | > ---------------------------------------------------------------
33 | > Thanks! We'll be in touch soon.
34 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Purpose
2 |
3 | * ...
4 |
5 | ## Does this introduce a breaking change?
6 |
7 | ```
8 | [ ] Yes
9 | [ ] No
10 | ```
11 |
12 | ## Pull Request Type
13 | What kind of change does this Pull Request introduce?
14 |
15 |
16 | ```
17 | [ ] Bugfix
18 | [ ] Feature
19 | [ ] Code style update (formatting, local variables)
20 | [ ] Refactoring (no functional changes, no api changes)
21 | [ ] Documentation content changes
22 | [ ] Other... Please describe:
23 | ```
24 |
25 | ## How to Test
26 | * Get the code
27 |
28 | ```
29 | git clone [repo-address]
30 | cd [repo-name]
31 | git checkout [branch-name]
32 | npm install
33 | ```
34 |
35 | * Test the code
36 |
37 | ```
38 | ```
39 |
40 | ## What to Check
41 | Verify that the following are valid
42 | * ...
43 |
44 | ## Other Information
45 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | *.egg-info/
24 | .installed.cfg
25 | *.egg
26 | MANIFEST
27 |
28 | # PyInstaller
29 | # Usually these files are written by a python script from a template
30 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
31 | *.manifest
32 | *.spec
33 |
34 | # Installer logs
35 | pip-log.txt
36 | pip-delete-this-directory.txt
37 |
38 | # Unit test / coverage reports
39 | htmlcov/
40 | .tox/
41 | .coverage
42 | .coverage.*
43 | .cache
44 | nosetests.xml
45 | coverage.xml
46 | *.cover
47 | .hypothesis/
48 | .pytest_cache/
49 |
50 | # Translations
51 | *.mo
52 | *.pot
53 |
54 | # Django stuff:
55 | *.log
56 | local_settings.py
57 | db.sqlite3
58 |
59 | # Flask stuff:
60 | instance/
61 | .webassets-cache
62 |
63 | # Scrapy stuff:
64 | .scrapy
65 |
66 | # Sphinx documentation
67 | docs/_build/
68 |
69 | # PyBuilder
70 | target/
71 |
72 | # Jupyter Notebook
73 | .ipynb_checkpoints
74 |
75 | # pyenv
76 | .python-version
77 |
78 | # celery beat schedule file
79 | celerybeat-schedule
80 |
81 | # SageMath parsed files
82 | *.sage.py
83 |
84 | # Environments
85 | .env
86 | .venv
87 | env/
88 | venv/
89 | ENV/
90 | env.bak/
91 | venv.bak/
92 |
93 | # Spyder project settings
94 | .spyderproject
95 | .spyproject
96 |
97 | # Rope project settings
98 | .ropeproject
99 |
100 | # mkdocs documentation
101 | /site
102 |
103 | # mypy
104 | .mypy_cache/
105 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": "Python: Current File",
9 | "type": "python",
10 | "request": "launch",
11 | "program": "${file}"
12 | },
13 | {
14 | "name": "Python: Attach",
15 | "type": "python",
16 | "request": "attach",
17 | "localRoot": "${workspaceFolder}",
18 | "remoteRoot": "${workspaceFolder}",
19 | "port": 3000,
20 | "secret": "my_secret",
21 | "host": "localhost"
22 | },
23 | {
24 | "name": "Python: Terminal (integrated)",
25 | "type": "python",
26 | "request": "launch",
27 | "program": "${file}",
28 | "console": "integratedTerminal"
29 | },
30 | {
31 | "name": "Python: Terminal (external)",
32 | "type": "python",
33 | "request": "launch",
34 | "program": "${file}",
35 | "console": "externalTerminal"
36 | },
37 | {
38 | "name": "Python: Django",
39 | "type": "python",
40 | "request": "launch",
41 | "program": "${workspaceFolder}/manage.py",
42 | "args": [
43 | "runserver",
44 | "--noreload",
45 | "--nothreading"
46 | ],
47 | "debugOptions": [
48 | "RedirectOutput",
49 | "Django"
50 | ]
51 | },
52 | {
53 | "name": "Python: Flask (0.11.x or later)",
54 | "type": "python",
55 | "request": "launch",
56 | "module": "flask",
57 | "env": {
58 | "FLASK_APP": "${workspaceFolder}/app.py"
59 | },
60 | "args": [
61 | "run",
62 | "--no-debugger",
63 | "--no-reload"
64 | ]
65 | },
66 | {
67 | "name": "Python: Module",
68 | "type": "python",
69 | "request": "launch",
70 | "module": "module.name"
71 | },
72 | {
73 | "name": "Python: Pyramid",
74 | "type": "python",
75 | "request": "launch",
76 | "args": [
77 | "${workspaceFolder}/development.ini"
78 | ],
79 | "debugOptions": [
80 | "RedirectOutput",
81 | "Pyramid"
82 | ]
83 | },
84 | {
85 | "name": "Python: Watson",
86 | "type": "python",
87 | "request": "launch",
88 | "program": "${workspaceFolder}/console.py",
89 | "args": [
90 | "dev",
91 | "runserver",
92 | "--noreload=True"
93 | ]
94 | },
95 | {
96 | "name": "Python: All debug Options",
97 | "type": "python",
98 | "request": "launch",
99 | "pythonPath": "${config:python.pythonPath}",
100 | "program": "${file}",
101 | "module": "module.name",
102 | "env": {
103 | "VAR1": "1",
104 | "VAR2": "2"
105 | },
106 | "envFile": "${workspaceFolder}/.env",
107 | "args": [
108 | "arg1",
109 | "arg2"
110 | ],
111 | "debugOptions": [
112 | "RedirectOutput"
113 | ]
114 | }
115 | ]
116 | }
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [project-title] Changelog
2 |
3 |
4 | # x.y.z (yyyy-mm-dd)
5 |
6 | *Features*
7 | * ...
8 |
9 | *Bug Fixes*
10 | * ...
11 |
12 | *Breaking Changes*
13 | * ...
14 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to [project-title]
2 |
3 | This project welcomes contributions and suggestions. Most contributions require you to agree to a
4 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
5 | the rights to use your contribution. For details, visit https://cla.microsoft.com.
6 |
7 | When you submit a pull request, a CLA-bot will automatically determine whether you need to provide
8 | a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
9 | provided by the bot. You will only need to do this once across all repos using our CLA.
10 |
11 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
12 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
13 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
14 |
15 | - [Code of Conduct](#coc)
16 | - [Issues and Bugs](#issue)
17 | - [Feature Requests](#feature)
18 | - [Submission Guidelines](#submit)
19 |
20 | ## Code of Conduct
21 | Help us keep this project open and inclusive. Please read and follow our [Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
22 |
23 | ## Found an Issue?
24 | If you find a bug in the source code or a mistake in the documentation, you can help us by
25 | [submitting an issue](#submit-issue) to the GitHub Repository. Even better, you can
26 | [submit a Pull Request](#submit-pr) with a fix.
27 |
28 | ## Want a Feature?
29 | You can *request* a new feature by [submitting an issue](#submit-issue) to the GitHub
30 | Repository. If you would like to *implement* a new feature, please submit an issue with
31 | a proposal for your work first, to be sure that we can use it.
32 |
33 | * **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr).
34 |
35 | ## Submission Guidelines
36 |
37 | ### Submitting an Issue
38 | Before you submit an issue, search the archive, maybe your question was already answered.
39 |
40 | If your issue appears to be a bug, and hasn't been reported, open a new issue.
41 | Help us to maximize the effort we can spend fixing issues and adding new
42 | features, by not reporting duplicate issues. Providing the following information will increase the
43 | chances of your issue being dealt with quickly:
44 |
45 | * **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps
46 | * **Version** - what version is affected (e.g. 0.1.2)
47 | * **Motivation for or Use Case** - explain what are you trying to do and why the current behavior is a bug for you
48 | * **Browsers and Operating System** - is this a problem with all browsers?
49 | * **Reproduce the Error** - provide a live example or a unambiguous set of steps
50 | * **Related Issues** - has a similar issue been reported before?
51 | * **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be
52 | causing the problem (line of code or commit)
53 |
54 | You can file new issues by providing the above information at the corresponding repository's issues link: https://github.com/[organization-name]/[repository-name]/issues/new].
55 |
56 | ### Submitting a Pull Request (PR)
57 | Before you submit your Pull Request (PR) consider the following guidelines:
58 |
59 | * Search the repository (https://github.com/[organization-name]/[repository-name]/pulls) for an open or closed PR
60 | that relates to your submission. You don't want to duplicate effort.
61 |
62 | * Make your changes in a new git fork:
63 |
64 | * Commit your changes using a descriptive commit message
65 | * Push your fork to GitHub:
66 | * In GitHub, create a pull request
67 | * If we suggest changes then:
68 | * Make the required updates.
69 | * Rebase your fork and force push to your GitHub repository (this will update your Pull Request):
70 |
71 | ```shell
72 | git rebase master -i
73 | git push -f
74 | ```
75 |
76 | That's it! Thank you for your contribution!
77 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Microsoft Corporation. All rights reserved.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | page_type: sample
3 | languages:
4 | - python
5 | products:
6 | - azure
7 | description: "This sample application demonstrates several common Azure Container Instances operations in Python using the Azure libraries for Python."
8 | urlFragment: aci-docs-sample-python
9 | ---
10 |
11 | # Azure Container Instances Python code samples for documentation
12 |
13 | This sample application demonstrates several common [Azure Container Instances](https://docs.microsoft.com/azure/container-instances/) operations in Python using the [Azure libraries for Python](https://docs.microsoft.com/python/azure/python-sdk-azure-overview).
14 |
15 | The code in this project is ingested into one or more articles on [docs.microsoft.com](https://docs.microsoft.com). Modifying the code in the sample source may impact the rendering of code snippets on [docs.microsoft.com](https://docs.microsoft.com).
16 |
17 | This sample has been tested as functional on Python versions 2.7.15rc1 and 3.6.5.
18 |
19 | ## Features
20 |
21 | The code in this sample project demonstrates the following operations:
22 |
23 | * Authenticate with Azure
24 | * Create resource group
25 | * Create single- and multi-container container groups
26 | * Expose application container to internet with public DNS name
27 | * Multi-container group includes both application and sidecar containers
28 | * Run a task-based container with custom command line and environment variables
29 | * List container groups in resource group
30 | * Get and print container group details
31 | * Delete container groups
32 | * Delete resource group
33 |
34 | ## Getting Started
35 |
36 | ### Prerequisites
37 |
38 | * [Azure subscription](https://azure.microsoft.com/free)
39 | * [Python](https://docs.microsoft.com/python/azure/python-sdk-azure-install#where-to-get-python)
40 | * [pip](https://pypi.org/project/pip/)
41 | * [virtualenv](https://virtualenv.pypa.io) (optional)
42 |
43 | ### Run the sample
44 |
45 | 1. Optional but recommended, use [virtualenv](https://virtualenv.pypa.io/en/stable/) to create and activate a virtual environment for the project:
46 | ```
47 | virtualenv ~/venv/aci-docs-sample-python
48 | source ~/venv/aci-docs-sample-python/bin/activate
49 | ```
50 |
51 | 1. Use the [Azure CLI](https://docs.microsoft.com/cli/azure) (or [Cloud Shell](https://shell.azure.com/)) to generate an Azure credentials file ([more authentication details](https://docs.microsoft.com/python/azure/python-sdk-azure-authenticate?view=azure-python#mgmt-auth-file))
52 |
53 | `az ad sp create-for-rbac --sdk-auth > my.azureauth`
54 |
55 | 1. Set environment variable `AZURE_AUTH_LOCATION` to the full path of the credentials file
56 | 1. `git clone https://github.com/Azure-Samples/aci-docs-sample-python`
57 | 1. `cd aci-docs-sample-python`
58 | 1. `pip install -r src/requirements.txt`
59 | 1. `python src/aci_docs_sample.py`
60 |
61 | ...sample runs...
62 |
63 | 1. Exit virtualenv (if using a virtual environment): `deactivate`
64 |
65 | ## Resources
66 |
67 | * [Azure SDK for Python](https://github.com/Azure/azure-sdk-for-python) (GitHub)
68 | * [More Azure Container Instances code samples](https://azure.microsoft.com/resources/samples/?sort=0&term=aci)
69 |
--------------------------------------------------------------------------------
/src/aci_docs_sample.py:
--------------------------------------------------------------------------------
1 | import random
2 | import string
3 | import time
4 | import sys
5 | from os import getenv
6 | from azure.common.client_factory import get_client_from_auth_file
7 | from azure.mgmt.resource import ResourceManagementClient
8 | from azure.mgmt.containerinstance import ContainerInstanceManagementClient
9 | from azure.mgmt.containerinstance.models import (ContainerGroup,
10 | Container,
11 | ContainerGroupNetworkProtocol,
12 | ContainerGroupRestartPolicy,
13 | ContainerPort,
14 | EnvironmentVariable,
15 | IpAddress,
16 | Port,
17 | ResourceRequests,
18 | ResourceRequirements,
19 | OperatingSystemTypes)
20 |
21 | # Support input() on Python 2.x
22 | try:
23 | input = raw_input
24 | except NameError:
25 | pass
26 |
27 |
28 | def main():
29 | """Main entry point for the application.
30 | """
31 |
32 | azure_region = 'eastus'
33 | resource_group_name = 'aci-rg-' + ''.join(random.choice(string.digits)
34 | for _ in range(6))
35 | container_group_name = 'aci-' + ''.join(random.choice(string.digits)
36 | for _ in range(6))
37 |
38 | multi_container_group_name = container_group_name + "-multi"
39 | task_container_group_name = container_group_name + "-task"
40 |
41 | container_image_app = "microsoft/aci-helloworld"
42 | container_image_sidecar = "microsoft/aci-tutorial-sidecar"
43 | container_image_taskbased = "microsoft/aci-wordcount"
44 |
45 | # Authenticate the management clients with Azure.
46 | # Set the AZURE_AUTH_LOCATION environment variable to the full path to an
47 | # auth file. Generate an auth file with the Azure CLI or Cloud Shell:
48 | # az ad sp create-for-rbac --sdk-auth > my.azureauth
49 | auth_file_path = getenv('AZURE_AUTH_LOCATION', None)
50 | if auth_file_path is not None:
51 | print("Authenticating with Azure using credentials in file at {0}"
52 | .format(auth_file_path))
53 |
54 | aciclient = get_client_from_auth_file(
55 | ContainerInstanceManagementClient)
56 | resclient = get_client_from_auth_file(ResourceManagementClient)
57 | else:
58 | print("\nFailed to authenticate to Azure. Have you set the"
59 | " AZURE_AUTH_LOCATION environment variable?\n")
60 |
61 | # Create (and then get) a resource group into which the container groups
62 | # are to be created
63 | print("Creating resource group '{0}'...".format(resource_group_name))
64 | resclient.resource_groups.create_or_update(resource_group_name,
65 | {'location': azure_region})
66 | resource_group = resclient.resource_groups.get(resource_group_name)
67 |
68 | # Demonstrate various container group operations
69 | create_container_group(aciclient, resource_group, container_group_name,
70 | container_image_app)
71 | create_container_group_multi(aciclient, resource_group,
72 | multi_container_group_name,
73 | container_image_app,
74 | container_image_sidecar)
75 | run_task_based_container(aciclient, resource_group,
76 | task_container_group_name,
77 | container_image_taskbased,
78 | None)
79 | list_container_groups(aciclient, resource_group)
80 | print_container_group_details(aciclient,
81 | resource_group,
82 | multi_container_group_name)
83 |
84 | # Clean up resources
85 | input("Press ENTER to delete all resources created by this sample: ")
86 | aciclient.container_groups.delete(resource_group_name,
87 | container_group_name)
88 | aciclient.container_groups.delete(resource_group_name,
89 | multi_container_group_name)
90 | aciclient.container_groups.delete(resource_group_name,
91 | task_container_group_name)
92 | resclient.resource_groups.delete(resource_group_name)
93 |
94 |
95 | def create_container_group(aci_client, resource_group,
96 | container_group_name, container_image_name):
97 | """Creates a container group with a single container.
98 |
99 | Arguments:
100 | aci_client {azure.mgmt.containerinstance.ContainerInstanceManagementClient}
101 | -- An authenticated container instance management client.
102 | resource_group {azure.mgmt.resource.resources.models.ResourceGroup}
103 | -- The resource group in which to create the container group.
104 | container_group_name {str}
105 | -- The name of the container group to create.
106 | container_image_name {str}
107 | -- The container image name and tag, for example:
108 | microsoft\aci-helloworld:latest
109 | """
110 | print("Creating container group '{0}'...".format(container_group_name))
111 |
112 | # Configure the container
113 | container_resource_requests = ResourceRequests(memory_in_gb=1, cpu=1.0)
114 | container_resource_requirements = ResourceRequirements(
115 | requests=container_resource_requests)
116 | container = Container(name=container_group_name,
117 | image=container_image_name,
118 | resources=container_resource_requirements,
119 | ports=[ContainerPort(port=80)])
120 |
121 | # Configure the container group
122 | ports = [Port(protocol=ContainerGroupNetworkProtocol.tcp, port=80)]
123 | group_ip_address = IpAddress(ports=ports,
124 | dns_name_label=container_group_name,
125 | type="Public")
126 | group = ContainerGroup(location=resource_group.location,
127 | containers=[container],
128 | os_type=OperatingSystemTypes.linux,
129 | ip_address=group_ip_address)
130 |
131 | # Create the container group
132 | aci_client.container_groups.create_or_update(resource_group.name,
133 | container_group_name,
134 | group)
135 |
136 | # Get the created container group
137 | container_group = aci_client.container_groups.get(resource_group.name,
138 | container_group_name)
139 |
140 | print("Once DNS has propagated, container group '{0}' will be reachable at"
141 | " http://{1}".format(container_group_name,
142 | container_group.ip_address.fqdn))
143 |
144 |
145 | def create_container_group_multi(aci_client, resource_group,
146 | container_group_name,
147 | container_image_1, container_image_2):
148 | """Creates a container group with two containers in the specified
149 | resource group.
150 |
151 | Arguments:
152 | aci_client {azure.mgmt.containerinstance.ContainerInstanceManagementClient}
153 | -- An authenticated container instance management client.
154 | resource_group {azure.mgmt.resource.resources.models.ResourceGroup}
155 | -- The resource group in which to create the container group.
156 | container_group_name {str}
157 | -- The name of the container group to create.
158 | container_image_1 {str}
159 | -- The first container image name and tag, for example:
160 | microsoft\aci-helloworld:latest
161 | container_image_2 {str}
162 | -- The second container image name and tag, for example:
163 | microsoft\aci-tutorial-sidecar:latest
164 | """
165 | print("Creating container group '{0}'...".format(container_group_name))
166 |
167 | # Configure the containers
168 | container_resource_requests = ResourceRequests(memory_in_gb=2, cpu=1.0)
169 | container_resource_requirements = ResourceRequirements(
170 | requests=container_resource_requests)
171 |
172 | container_1 = Container(name=container_group_name + '-1',
173 | image=container_image_1,
174 | resources=container_resource_requirements,
175 | ports=[ContainerPort(port=80)])
176 |
177 | container_2 = Container(name=container_group_name + '-2',
178 | image=container_image_2,
179 | resources=container_resource_requirements)
180 |
181 | # Configure the container group
182 | ports = [Port(protocol=ContainerGroupNetworkProtocol.tcp, port=80)]
183 | group_ip_address = IpAddress(
184 | ports=ports, dns_name_label=container_group_name, type='Public')
185 | group = ContainerGroup(location=resource_group.location,
186 | containers=[container_1, container_2],
187 | os_type=OperatingSystemTypes.linux,
188 | ip_address=group_ip_address)
189 |
190 | # Create the container group
191 | aci_client.container_groups.create_or_update(resource_group.name,
192 | container_group_name, group)
193 |
194 | # Get the created container group
195 | container_group = aci_client.container_groups.get(resource_group.name,
196 | container_group_name)
197 |
198 | print("Once DNS has propagated, container group '{0}' will be reachable at"
199 | " http://{1}".format(container_group_name,
200 | container_group.ip_address.fqdn))
201 |
202 |
203 | def run_task_based_container(aci_client, resource_group, container_group_name,
204 | container_image_name, start_command_line=None):
205 | """Creates a container group with a single task-based container who's
206 | restart policy is 'Never'. If specified, the container runs a custom
207 | command line at startup.
208 |
209 | Arguments:
210 | aci_client {azure.mgmt.containerinstance.ContainerInstanceManagementClient}
211 | -- An authenticated container instance management client.
212 | resource_group {azure.mgmt.resource.resources.models.ResourceGroup}
213 | -- The resource group in which to create the container group.
214 | container_group_name {str}
215 | -- The name of the container group to create.
216 | container_image_name {str}
217 | -- The container image name and tag, for example:
218 | microsoft\aci-helloworld:latest
219 | start_command_line {str}
220 | -- The command line that should be executed when the
221 | container starts. This value can be None.
222 | """
223 | # If a start command wasn't specified, use a default
224 | if start_command_line is None:
225 | start_command_line = "python wordcount.py http://shakespeare.mit.edu/romeo_juliet/full.html"
226 |
227 | # Configure some environment variables in the container which the
228 | # wordcount.py or other script can read to modify its behavior.
229 | env_var_1 = EnvironmentVariable(name='NumWords', value='5')
230 | env_var_2 = EnvironmentVariable(name='MinLength', value='8')
231 |
232 | print("Creating container group '{0}' with start command '{1}'"
233 | .format(container_group_name, start_command_line))
234 |
235 | # Configure the container
236 | container_resource_requests = ResourceRequests(memory_in_gb=1, cpu=1.0)
237 | container_resource_requirements = ResourceRequirements(
238 | requests=container_resource_requests)
239 | container = Container(name=container_group_name,
240 | image=container_image_name,
241 | resources=container_resource_requirements,
242 | command=start_command_line.split(),
243 | environment_variables=[env_var_1, env_var_2])
244 |
245 | # Configure the container group
246 | group = ContainerGroup(location=resource_group.location,
247 | containers=[container],
248 | os_type=OperatingSystemTypes.linux,
249 | restart_policy=ContainerGroupRestartPolicy.never)
250 |
251 | # Create the container group
252 | result = aci_client.container_groups.create_or_update(resource_group.name,
253 | container_group_name,
254 | group)
255 |
256 | # Wait for the container create operation to complete. The operation is
257 | # "done" when the container group provisioning state is one of:
258 | # Succeeded, Canceled, Failed
259 | while result.done() is False:
260 | sys.stdout.write('.')
261 | time.sleep(1)
262 |
263 | # Get the provisioning state of the container group.
264 | container_group = aci_client.container_groups.get(resource_group.name,
265 | container_group_name)
266 | if str(container_group.provisioning_state).lower() == 'succeeded':
267 | print("\nCreation of container group '{}' succeeded."
268 | .format(container_group_name))
269 | else:
270 | print("\nCreation of container group '{}' failed. Provisioning state"
271 | "is: {}".format(container_group_name,
272 | container_group.provisioning_state))
273 |
274 | # Get the logs for the container
275 | logs = aci_client.container.list_logs(resource_group.name,
276 | container_group_name,
277 | container.name)
278 |
279 | print("Logs for container '{0}':".format(container_group_name))
280 | print("{0}".format(logs.content))
281 |
282 |
283 | def list_container_groups(aci_client, resource_group):
284 | """Lists the container groups in the specified resource group.
285 |
286 | Arguments:
287 | aci_client {azure.mgmt.containerinstance.ContainerInstanceManagementClient}
288 | -- An authenticated container instance management client.
289 | resource_group {azure.mgmt.resource.resources.models.ResourceGroup}
290 | -- The resource group containing the container group(s).
291 | """
292 | print("Listing container groups in resource group '{0}'...".format(
293 | resource_group.name))
294 |
295 | container_groups = aci_client.container_groups.list_by_resource_group(
296 | resource_group.name)
297 |
298 | for container_group in container_groups:
299 | print(" {0}".format(container_group.name))
300 |
301 |
302 | def print_container_group_details(aci_client, resource_group, container_group_name):
303 | """Gets the specified container group and then prints a few of its properties and their values.
304 |
305 | Arguments:
306 | aci_client {azure.mgmt.containerinstance.ContainerInstanceManagementClient}
307 | -- An authenticated container instance management client.
308 | resource_group {azure.mgmt.resource.resources.models.ResourceGroup}
309 | -- The name of the resource group containing the container
310 | group.
311 | container_group_name {str}
312 | -- The name of the container group whose details should be
313 | printed.
314 | """
315 | print("Getting container group details for container group '{0}'..."
316 | .format(container_group_name))
317 |
318 | container_group = aci_client.container_groups.get(resource_group.name,
319 | container_group_name)
320 | print("------------------------")
321 | print("Name: {0}".format(container_group.name))
322 | print("State: {0}".format(container_group.provisioning_state))
323 | print("FQDN: {0}".format(container_group.ip_address.fqdn))
324 | print("IP: {0}".format(container_group.ip_address.ip))
325 | print("Region: {0}".format(container_group.location))
326 | print("Containers:")
327 | for container in container_group.containers:
328 | print(" Name: {0}".format(container.name))
329 | print(" Image: {0}".format(container.image))
330 | print(" State: {0}".format(
331 | container.instance_view.current_state.state))
332 | print(" ----------")
333 |
334 |
335 | if __name__ == "__main__":
336 | main()
337 |
--------------------------------------------------------------------------------
/src/requirements.txt:
--------------------------------------------------------------------------------
1 | azure-common==1.1.18
2 | azure-mgmt-containerinstance==1.4.1
3 | azure-mgmt-resource==2.1.0
--------------------------------------------------------------------------------