diff --git a/awx/ui/client/lib/components/_index.less b/awx/ui/client/lib/components/_index.less
index 72c14fe4b5..7d661e8122 100644
--- a/awx/ui/client/lib/components/_index.less
+++ b/awx/ui/client/lib/components/_index.less
@@ -8,6 +8,7 @@
@import 'popover/_index';
@import 'relaunchButton/_index';
@import 'tabs/_index';
+@import 'tag/_index';
@import 'truncate/_index';
@import 'utility/_index';
@import 'code-mirror/_index';
diff --git a/awx/ui/client/lib/components/index.js b/awx/ui/client/lib/components/index.js
index 35b0e0193d..bea2f38ce6 100644
--- a/awx/ui/client/lib/components/index.js
+++ b/awx/ui/client/lib/components/index.js
@@ -32,6 +32,7 @@ import sideNav from '~components/layout/side-nav.directive';
import sideNavItem from '~components/layout/side-nav-item.directive';
import tab from '~components/tabs/tab.directive';
import tabGroup from '~components/tabs/group.directive';
+import tag from '~components/tag/tag.directive';
import topNavItem from '~components/layout/top-nav-item.directive';
import truncate from '~components/truncate/truncate.directive';
import atCodeMirror from '~components/code-mirror';
@@ -78,6 +79,7 @@ angular
.directive('atSideNavItem', sideNavItem)
.directive('atTab', tab)
.directive('atTabGroup', tabGroup)
+ .directive('atTag', tag)
.directive('atTopNavItem', topNavItem)
.directive('atTruncate', truncate)
.service('BaseInputController', BaseInputController)
diff --git a/awx/ui/client/lib/components/tag/_index.less b/awx/ui/client/lib/components/tag/_index.less
new file mode 100644
index 0000000000..1fa4f5ace5
--- /dev/null
+++ b/awx/ui/client/lib/components/tag/_index.less
@@ -0,0 +1,51 @@
+.TagComponentWrapper {
+ padding: @at-space;
+}
+.TagComponent {
+ color: white;
+ background: @at-blue;
+ border-radius: @at-space;
+ font-size: 12px;
+ display: flex;
+ flex-direction: row;
+ align-content: center;
+ min-height: @at-space-4x;
+ overflow: hidden;
+ max-width: 200px;
+}
+
+.TagComponent-name {
+ margin: 2px @at-space-2x;
+ align-self: center;
+ word-break: break-word;
+ text-transform: lowercase;
+}
+
+.TagComponent--cloud {
+ &:before {
+ content: '\f0c2';
+ color: white;
+ height: @at-space-4x;
+ width: @at-space-4x;
+ }
+}
+
+.TagComponent--key {
+ &:before {
+ content: '\f084';
+ color: white;
+ height: @at-space-4x;
+ width: @at-space-4x;
+ }
+}
+
+.TagComponent-button {
+ padding: 0 @at-space;
+ .at-mixin-VerticallyCenter();
+}
+
+.TagComponent-button:hover {
+ cursor: pointer;
+ border-color: @at-color-error;
+ background-color: @at-color-error;
+}
diff --git a/awx/ui/client/lib/components/tag/tag.directive.js b/awx/ui/client/lib/components/tag/tag.directive.js
new file mode 100644
index 0000000000..0616bb5e0d
--- /dev/null
+++ b/awx/ui/client/lib/components/tag/tag.directive.js
@@ -0,0 +1,16 @@
+const templateUrl = require('~components/tag/tag.partial.html');
+
+function atTag () {
+ return {
+ restrict: 'E',
+ replace: true,
+ transclude: true,
+ templateUrl,
+ scope: {
+ tag: '=',
+ removeTag: '&?',
+ },
+ };
+}
+
+export default atTag;
diff --git a/awx/ui/client/lib/components/tag/tag.partial.html b/awx/ui/client/lib/components/tag/tag.partial.html
new file mode 100644
index 0000000000..ba7fbada4f
--- /dev/null
+++ b/awx/ui/client/lib/components/tag/tag.partial.html
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/awx/ui/client/lib/theme/_mixins.less b/awx/ui/client/lib/theme/_mixins.less
index 701613a2ec..a3aa4ef1df 100644
--- a/awx/ui/client/lib/theme/_mixins.less
+++ b/awx/ui/client/lib/theme/_mixins.less
@@ -102,4 +102,10 @@
.at-mixin-FontFixedWidth () {
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
+}
+
+.at-mixin-VerticallyCenter () {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
}
\ No newline at end of file