{"id":49138,"date":"2023-06-20T18:28:55","date_gmt":"2023-09-29T07:17:21","guid":{"rendered":"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8ansible-molecule%e7%9a%84%e4%bb%a3%e7%90%86%e9%a9%b1%e5%8a%a8%e7%a8%8b%e5%ba%8f%ef%bc%8c%e9%80%9a%e8%bf%87terraform%e5%88%9b%e5%bb%ba%e7%94%a8%e4%ba%8e%e6%b5%8b%e8%af%95%e7%9a%84aws\/"},"modified":"2024-04-30T09:50:21","modified_gmt":"2024-04-30T01:50:21","slug":"%e4%bd%bf%e7%94%a8ansible-molecule%e7%9a%84%e4%bb%a3%e7%90%86%e9%a9%b1%e5%8a%a8%e7%a8%8b%e5%ba%8f%ef%bc%8c%e9%80%9a%e8%bf%87terraform%e5%88%9b%e5%bb%ba%e7%94%a8%e4%ba%8e%e6%b5%8b%e8%af%95%e7%9a%84aws","status":"publish","type":"post","link":"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8ansible-molecule%e7%9a%84%e4%bb%a3%e7%90%86%e9%a9%b1%e5%8a%a8%e7%a8%8b%e5%ba%8f%ef%bc%8c%e9%80%9a%e8%bf%87terraform%e5%88%9b%e5%bb%ba%e7%94%a8%e4%ba%8e%e6%b5%8b%e8%af%95%e7%9a%84aws\/","title":{"rendered":"\u4f7f\u7528Ansible Molecule\u7684\u4ee3\u7406\u9a71\u52a8\u7a0b\u5e8f\uff0c\u901a\u8fc7terraform\u521b\u5efa\u7528\u4e8e\u6d4b\u8bd5\u7684AWS EC2\u5b9e\u4f8b"},"content":{"rendered":"<h1>\u95ee\u9898\uff1a<\/h1>\n<p>\u4f7f\u7528Ansible Molecule\u8fdb\u884cPlaybook\u6d4b\u8bd5\u65f6\uff0c\u5982\u679c\u5728\u4e91\u4e0a\u8fdb\u884c\u6d4b\u8bd5\uff0c\u4f7f\u7528Terraform\u6709\u4ee5\u4e0b\u597d\u5904\u3002<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">\u69d8\u3005\u306a\u30af\u30e9\u30a6\u30c9\u306b\u5bfe\u5fdc\u53ef\u80fd<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\u51aa\u7b49\u6027\u306fterraform\u306b\u3066\u5bfe\u5fdc<\/ul>\n<p>\u5728\u8fd9\u91cc\u4ee5 AWS EC2 \u73af\u5883\u4e3a\u4f8b\u8fdb\u884c\u8bbe\u7f6e\u7684\u5c1d\u8bd5\u3002<\/p>\n<h1>\u73af\u5883: \u5f62\u6210\u4e00\u4e2a\u4eba\u6216\u7269\u6240\u5904\u7684\u81ea\u7136\u548c\u793e\u4f1a\u6761\u4ef6\uff0c\u5305\u62ec\u7a7a\u6c14\u3001\u6c34\u3001\u571f\u58e4\u3001\u6c14\u5019\u3001\u52a8\u690d\u7269\u7b49\u56e0\u7d20\u3002<\/h1>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">macOS 10.15.7<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">Python(pyenv) 3.8.2<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">ansible 2.10.2<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">molecule 3.1.5<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">Terraform v0.13.4<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">yq 2.10.1 (\u30aa\u30d7\u30b7\u30e7\u30f3)<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">vm\u63a5\u7d9a\u306b\u4f7f\u7528\u3059\u308bssh-key ~\/.ssh\/id_rsa, ~\/.ssh\/id_rsa.pub<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\u74b0\u5883\u5909\u6570 AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY<\/ul>\n<h1>\u4e3b\u8981\u6587\u4ef6:<\/h1>\n<pre class=\"post-pre\"><code>.\r\n\u251c\u2500\u2500 molecule\r\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 default\r\n\u2502\u00a0\u00a0     \u251c\u2500\u2500 common.tf.yml             # terraform\u7528ec2\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb1\r\n\u2502\u00a0\u00a0     \u251c\u2500\u2500 ins01.tf.yml              # terraform\u7528ec2\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb2\r\n\u2502       \u2502 \r\n\u2502\u00a0\u00a0     \u251c\u2500\u2500 (common.tf.json)          # common.tf.yml\u304b\u3089\u751f\u6210\r\n\u2502\u00a0\u00a0     \u251c\u2500\u2500 (ins01.tf.json)           # ins01.tf.yml\u304b\u3089\u751f\u6210\r\n\u2502       \u2502 \r\n\u2502\u00a0\u00a0     \u251c\u2500\u2500 (instance_conf-ins01.yml) # terraform\u4f5c\u6210\r\n\u2502       \u2502                             # molecule\u306b\u9023\u643a\u3059\u308b\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3078\u306e\u63a5\u7d9a\u60c5\u5831\r\n\u2502       \u2502 \r\n\u2502\u00a0\u00a0     \u251c\u2500\u2500 (terraform.tfstate)       # terraform\u4f5c\u6210\u3002\u30b9\u30c6\u30fc\u30bf\u30b9\u60c5\u5831\r\n\u2502       \u2502 \r\n\u2502\u00a0\u00a0     \u251c\u2500\u2500 molecule.yml              # molecule\u5b9a\u7fa9\u60c5\u5831\r\n\u2502\u00a0\u00a0     \u251c\u2500\u2500 create.yml                # molecule vm\u4f5c\u6210playbook\r\n\u2502\u00a0\u00a0     \u251c\u2500\u2500 prepare.yml               # molecule vm\u4e8b\u524d\u6e96\u5099playbook\r\n\u2502\u00a0\u00a0     \u251c\u2500\u2500 converge.yml              # molecule vm\u3078\u306e\u5909\u66f4\u53cd\u6620playbook\r\n\u2502\u00a0\u00a0     \u251c\u2500\u2500 verify.yml                # molecule vm\u691c\u8a3cplaybook\r\n\u2502\u00a0\u00a0     \u2514\u2500\u2500 destroy.yml               # molecule vm\u524a\u9664playbook\r\n\u2514\u2500\u2500 tasks\r\n \u00a0\u00a0 \u2514\u2500\u2500 main.yml\r\n<\/code><\/pre>\n<p>\u4ee5\u4e0b\u662f\u6837\u672c\u4ee3\u7801\uff1a<br \/>\nhttps:\/\/github.com\/hiroyuki-onodera\/molecule-delegated-terraform-ec2<\/p>\n<h1>\u7b2c\u4e00\u7ae0\uff1a\u901a\u8fc7Terraform\u7ba1\u7406AWS EC2<\/h1>\n<h2>\u5728\u4e8b\u524d\u51c6\u5907\u9636\u6bb5\uff0c\u5728IAM\u4e2d\u6dfb\u52a0\u5177\u6709AmazonEC2\u5b8c\u5168\u8bbf\u95ee\u6743\u9650\u7684\u7528\u6237\u3002<\/h2>\n<p>\u5728AWS\u63a7\u5236\u53f0\u4e2d\uff0c\u901a\u8fc7Identity and Access Management\uff08IAM\uff09&gt; \u7528\u6237\u83dc\u5355\u6765\u6dfb\u52a0\u7528\u6237\u3002<\/p>\n<p>\u5728\u8fd9\u91cc\uff0c\u6211\u4eec\u91c7\u53d6\u4ee5\u4e0b\u7684\u65b9\u5f0f<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">AWS \u30a2\u30af\u30bb\u30b9\u306e\u7a2e\u985e: \u30d7\u30ed\u30b0\u30e9\u30e0\u306b\u3088\u308b\u30a2\u30af\u30bb\u30b9 &#8211; \u30a2\u30af\u30bb\u30b9\u30ad\u30fc\u3092\u4f7f\u7528<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">\u30a2\u30af\u30bb\u30b9\u6a29\u9650\u306e\u5883\u754c: \u30a2\u30af\u30bb\u30b9\u6a29\u9650\u306e\u5883\u754c\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">\u30a2\u30af\u30bb\u30b9\u8a31\u53ef\u306e\u8a2d\u5b9a<\/ul>\n<\/li>\n<\/ul>\n<p>\u65e2\u5b58\u306e\u30dd\u30ea\u30b7\u30fc\u3092\u76f4\u63a5\u30a2\u30bf\u30c3\u30c1<\/p>\n<p>AWS \u7ba1\u7406\u30dd\u30ea\u30b7\u30fc AmazonEC2FullAccess<\/p>\n<p>\u5c06\u83b7\u53d6\u5230\u7684\u8bbf\u95ee\u5bc6\u94a5ID\u548c\u79d8\u5bc6\u8bbf\u95ee\u5bc6\u94a5\u8bbe\u7f6e\u4e3a\u73af\u5883\u53d8\u91cfAWS_ACCESS_KEY_ID\u548cAWS_SECRET_ACCESS_KEY\u3002<\/p>\n<p>\u5728Bash\u7684\u60c5\u51b5\u4e0b\u7684\u4f8b\u5b50<\/p>\n<pre class=\"post-pre\"><code>$ cat &lt;&lt;EOC &gt;&gt; ~\/.bash_profile\r\nexport AWS_ACCESS_KEY_ID=\"....................\"\r\nexport AWS_SECRET_ACCESS_KEY=\"........................................\"\r\nEOC\r\n$ . ~\/.bash_profile\r\n<\/code><\/pre>\n<h2>\u4f7f\u7528 Terraform \u8fdb\u884c\u63d0\u4f9b\u7a0b\u5e8f\u548c\u7f51\u7edc\u5b9a\u4e49\u3002<\/h2>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">.tf\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u306f\u4ed6\u306e\u30e6\u30fc\u30c6\u30a3\u30ea\u30c6\u30a3\u3068\u306e\u9023\u643a\u306a\u3069\u304c\u56f0\u96e3<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">.tf.json\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u306f\u4eba\u304c\u76f4\u63a5\u4f7f\u7528\u3059\u308b\u306b\u306f\u96e3\u3057\u3044<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">\u3053\u3053\u3067\u306f\u3001.tf.json\u3092YAML\u3067\u8868\u8a18\u3057\u305f\u30d5\u30a1\u30a4\u30eb\u306b\u3066ec2\u8a2d\u5b9a\u3092\u884c\u3044\u3001terraform\u4f7f\u7528\u524d\u306bjson\u5316<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">\u6700\u521d\u304b\u3089.tf\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u3084.tf.json\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u3067\u8a18\u8ff0\u3001\u7ba1\u7406\u3059\u308b\u306a\u3089\u3070YAML\u7ba1\u7406\u306f\u4e0d\u8981<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">common.tf.yml \u306f\u3001provider\u3084\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u5b9a\u7fa9\u306a\u3069\u500b\u5225\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306b1:1\u3067\u5bfe\u5fdc\u3057\u306a\u3044\u8a2d\u5b9a\u3092\u307e\u3068\u3081\u305f\u3082\u306e\u3002<\/ul>\n<\/li>\n<\/ul>\n<p>VPC EC2\u5b9a\u7fa9\u306e\u5927\u90e8\u5206\u306f\u4ee5\u4e0b\u304b\u3089\u5f15\u7528\u3055\u305b\u3066\u3044\u305f\u3060\u3044\u3066\u3044\u307e\u3059\u3002\u3042\u308a\u304c\u3068\u3046\u3054\u3056\u3044\u307e\u3059\u3002<\/p>\n<p>Terraform\u3067VPC\u30fbEC2\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u69cb\u7bc9\u3057\u3066ssh\u63a5\u7d9a\u3059\u308b<br \/>\nhttps:\/\/qiita.com\/kou_pg_0131\/items\/45cdde3d27bd75f1bfd5<\/p>\n<pre class=\"post-pre\"><code><span class=\"nn\">---<\/span>\r\n<span class=\"na\">terraform<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">required_providers<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">aws<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">source<\/span><span class=\"pi\">:<\/span> <span class=\"s\">hashicorp\/aws<\/span>\r\n      <span class=\"na\">version<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">~&gt;<\/span> <span class=\"s\">3.0\"<\/span>\r\n<span class=\"na\">provider<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">aws<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">region<\/span><span class=\"pi\">:<\/span> <span class=\"s\">ap-northeast-1<\/span>\r\n<span class=\"na\">data<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">aws_ami<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">ami01<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">most_recent<\/span><span class=\"pi\">:<\/span> <span class=\"no\">true<\/span>\r\n      <span class=\"na\">owners<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">amazon<\/span>\r\n      <span class=\"na\">filter<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">architecture<\/span>\r\n        <span class=\"na\">values<\/span><span class=\"pi\">:<\/span>\r\n        <span class=\"pi\">-<\/span> <span class=\"s\">x86_64<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">root-device-type<\/span>\r\n        <span class=\"na\">values<\/span><span class=\"pi\">:<\/span>\r\n        <span class=\"pi\">-<\/span> <span class=\"s\">ebs<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">name<\/span>\r\n        <span class=\"na\">values<\/span><span class=\"pi\">:<\/span>\r\n        <span class=\"pi\">-<\/span> <span class=\"s\">amzn2-ami-hvm-*<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">virtualization-type<\/span>\r\n        <span class=\"na\">values<\/span><span class=\"pi\">:<\/span>\r\n        <span class=\"pi\">-<\/span> <span class=\"s\">hvm<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">block-device-mapping.volume-type<\/span>\r\n        <span class=\"na\">values<\/span><span class=\"pi\">:<\/span>\r\n        <span class=\"pi\">-<\/span> <span class=\"s\">gp2<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">state<\/span>\r\n        <span class=\"na\">values<\/span><span class=\"pi\">:<\/span>\r\n        <span class=\"pi\">-<\/span> <span class=\"s\">available<\/span>\r\n<span class=\"na\">resource<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">aws_vpc<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">vpc01<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">cidr_block<\/span><span class=\"pi\">:<\/span> <span class=\"s\">10.0.0.0\/16<\/span>\r\n      <span class=\"na\">enable_dns_support<\/span><span class=\"pi\">:<\/span> <span class=\"no\">true<\/span>\r\n      <span class=\"na\">enable_dns_hostnames<\/span><span class=\"pi\">:<\/span> <span class=\"no\">true<\/span>\r\n  <span class=\"na\">aws_subnet<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">subnet01<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">cidr_block<\/span><span class=\"pi\">:<\/span> <span class=\"s\">10.0.1.0\/24<\/span>\r\n      <span class=\"na\">availability_zone<\/span><span class=\"pi\">:<\/span> <span class=\"s\">ap-northeast-1a<\/span>\r\n      <span class=\"na\">vpc_id<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">${aws_vpc.vpc01.id}\"<\/span>\r\n      <span class=\"na\">map_public_ip_on_launch<\/span><span class=\"pi\">:<\/span> <span class=\"no\">true<\/span>\r\n  <span class=\"na\">aws_internet_gateway<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">internet_gateway01<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">vpc_id<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">${aws_vpc.vpc01.id}\"<\/span>\r\n  <span class=\"na\">aws_route_table<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">route_table01<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">vpc_id<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">${aws_vpc.vpc01.id}\"<\/span>\r\n  <span class=\"na\">aws_route<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">route01<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">gateway_id<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">${aws_internet_gateway.internet_gateway01.id}\"<\/span>\r\n      <span class=\"na\">route_table_id<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">${aws_route_table.route_table01.id}\"<\/span>\r\n      <span class=\"na\">destination_cidr_block<\/span><span class=\"pi\">:<\/span> <span class=\"s\">0.0.0.0\/0<\/span>\r\n  <span class=\"na\">aws_route_table_association<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">route_table_association01<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">subnet_id<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">${aws_subnet.subnet01.id}\"<\/span>\r\n      <span class=\"na\">route_table_id<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">${aws_route_table.route_table01.id}\"<\/span>\r\n  <span class=\"na\">aws_security_group<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">security_group01<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">security_group01<\/span>\r\n      <span class=\"na\">vpc_id<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">${aws_vpc.vpc01.id}\"<\/span>\r\n  <span class=\"na\">aws_security_group_rule<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">in_ssh<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">security_group_id<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">${aws_security_group.security_group01.id}\"<\/span>\r\n      <span class=\"na\">type<\/span><span class=\"pi\">:<\/span> <span class=\"s\">ingress<\/span>\r\n      <span class=\"na\">cidr_blocks<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">0.0.0.0\/0<\/span>\r\n      <span class=\"na\">from_port<\/span><span class=\"pi\">:<\/span> <span class=\"m\">22<\/span>\r\n      <span class=\"na\">to_port<\/span><span class=\"pi\">:<\/span> <span class=\"m\">22<\/span>\r\n      <span class=\"na\">protocol<\/span><span class=\"pi\">:<\/span> <span class=\"s\">tcp<\/span>\r\n    <span class=\"na\">in_icmp<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">security_group_id<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">${aws_security_group.security_group01.id}\"<\/span>\r\n      <span class=\"na\">type<\/span><span class=\"pi\">:<\/span> <span class=\"s\">ingress<\/span>\r\n      <span class=\"na\">cidr_blocks<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">0.0.0.0\/0<\/span>\r\n      <span class=\"na\">from_port<\/span><span class=\"pi\">:<\/span> <span class=\"s\">-1<\/span>\r\n      <span class=\"na\">to_port<\/span><span class=\"pi\">:<\/span> <span class=\"s\">-1<\/span>\r\n      <span class=\"na\">protocol<\/span><span class=\"pi\">:<\/span> <span class=\"s\">icmp<\/span>\r\n    <span class=\"na\">out_all<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">security_group_id<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">${aws_security_group.security_group01.id}\"<\/span>\r\n      <span class=\"na\">type<\/span><span class=\"pi\">:<\/span> <span class=\"s\">egress<\/span>\r\n      <span class=\"na\">cidr_blocks<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">0.0.0.0\/0<\/span>\r\n      <span class=\"na\">from_port<\/span><span class=\"pi\">:<\/span> <span class=\"m\">0<\/span>\r\n      <span class=\"na\">to_port<\/span><span class=\"pi\">:<\/span> <span class=\"m\">0<\/span>\r\n      <span class=\"na\">protocol<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">-1\"<\/span>\r\n  <span class=\"na\">aws_key_pair<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">key_pair01<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">key_name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">key_pair01<\/span>\r\n      <span class=\"na\">public_key<\/span><span class=\"pi\">:<\/span> <span class=\"s\">${file(\"~\/.ssh\/id_rsa.pub\")}<\/span>\r\n<\/code><\/pre>\n<h2>\u901a\u8fc7Terraform\u5bf9\u5b9e\u4f8b\u8fdb\u884c\u7279\u5b9a\u5b9a\u4e49\u3002<\/h2>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u540d.tf.yml\u306f\u3001\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306b1:1\u3067\u5bfe\u5fdc\u3059\u308b\u8cc7\u6e90\u3092\u307e\u3068\u3081\u305f\u3082\u306e<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u6bce\u306b1\u30d5\u30a1\u30a4\u30eb\u306e\u60f3\u5b9a<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">j2\u306a\u3069\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u30a8\u30f3\u30b8\u30f3\u3092\u7528\u3044\u3066\u306e\u4f5c\u6210\u306f\u3001\u3069\u306e\u7bc4\u56f2\u307e\u3067\u30e6\u30fc\u30b6\u30fc\u6307\u5b9a\u3068\u3059\u308b\u304b\u306a\u3069\u74b0\u5883\u3001\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u4f9d\u5b58\u306e\u9805\u76ee\u304c\u591a\u304f\u3001\u4e0d\u5fc5\u8981\u306b\u8907\u96d1\u5316\u3059\u308b\u70ba\u306b\u65ad\u5ff5\u3002\u30b7\u30f3\u30d7\u30eb\u306b\u3053\u306e\u30d5\u30a1\u30a4\u30eb\u5185\u3067\u306e\u76f4\u63a5\u6307\u5b9a\u306b\u3088\u308b\u8a2d\u5b9a\u3068\u3057\u3066\u3044\u308b\u3002<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">\u4f5c\u6210\u3057\u305f\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3078\u306e\u63a5\u7d9a\u60c5\u5831\u306flocal_file:\u30ea\u30bd\u30fc\u30b9\u3092\u7528\u3044\u3066Molecule\u306b\u9023\u643a\u3059\u308b<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\u30e6\u30fc\u30b6\u30fc\u5229\u4fbf\u3092\u8003\u616e\u3057\u3066ssh\u30ed\u30b0\u30a4\u30f3\u65b9\u6cd5\u3092output\u306b\u3066\u8868\u793a<\/ul>\n<pre class=\"post-pre\"><code><span class=\"nn\">---<\/span>\r\n<span class=\"na\">resource<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">aws_instance<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">ins01<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">ami<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">${data.aws_ami.ami01.image_id}\"<\/span>\r\n      <span class=\"na\">vpc_security_group_ids<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">${aws_security_group.security_group01.id}\"<\/span>\r\n      <span class=\"na\">subnet_id<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">${aws_subnet.subnet01.id}\"<\/span>\r\n      <span class=\"na\">key_name<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">${aws_key_pair.key_pair01.id}\"<\/span>\r\n      <span class=\"na\">instance_type<\/span><span class=\"pi\">:<\/span> <span class=\"s\">t2.micro<\/span>\r\n  <span class=\"na\">aws_eip<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">eip-ins01<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">instance<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">${aws_instance.ins01.id}\"<\/span>\r\n      <span class=\"na\">vpc<\/span><span class=\"pi\">:<\/span> <span class=\"no\">true<\/span>\r\n  <span class=\"na\">local_file<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">instance_conf-ins01<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">filename<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">.\/instance_conf-ins01.yml\"<\/span>\r\n      <span class=\"na\">content<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">|<\/span>\r\n        <span class=\"s\"># this file is maintaind by terraform<\/span>\r\n        <span class=\"s\">---<\/span>\r\n        <span class=\"s\">instance: ins01<\/span>\r\n        <span class=\"s\">address: ${aws_eip.eip-ins01.public_ip}<\/span>\r\n        <span class=\"s\">user: ec2-user<\/span>\r\n        <span class=\"s\">port: 22<\/span>\r\n        <span class=\"s\">identity_file: ~\/.ssh\/id_rsa<\/span>\r\n<span class=\"na\">output<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">ssh_login-ins01<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">value<\/span><span class=\"pi\">:<\/span> <span class=\"s\">ssh -o UserKnownHostsFile=\/dev\/null -o StrictHostKeyChecking=no -i ~\/.ssh\/id_rsa<\/span>\r\n      <span class=\"s\">ec2-user@${aws_eip.eip-ins01.public_ip}<\/span>\r\n<\/code><\/pre>\n<p>\u4f7f\u7528\u672c\u5730\u6587\u4ef6\u5c06\u63a5\u53e3\u8fde\u63a5\u65b9\u5f0f\u4e0e\u5206\u5b50\u5bf9\u63a5\u5230\u5b9e\u4f8b\u4e0a\u3002<\/p>\n<h2>\u901a\u8fc7\u4f7f\u7528Terraform\u8fdb\u884c\u90e8\u7f72\u548c\u9500\u6bc1\u786e\u8ba4<\/h2>\n<h3>\u51c6\u5907\u597dtf.json\u6587\u4ef6\u3002<\/h3>\n<p>\u5982\u679c\u4e00\u5f00\u59cb\u5c31\u4f7f\u7528.tf.json\u6216\u8005.tf\u6587\u4ef6\u7684\u8bdd\u5c31\u4e0d\u9700\u8981\u4e86\u3002<br \/>\n\u901a\u8fc7yq\u5b9e\u7528\u5de5\u5177\uff0c\u5c06YAML\u6587\u4ef6\u8f6c\u6362\u4e3aterraform\u7528\u7684.tf.json\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code>$ cd molecule\/default\/\r\n$ yq . common.tf.yml &gt; common.tf.json\r\n$ yq . ins01.tf.yml &gt; ins01.tf.json\r\n<\/code><\/pre>\n<p>yq\u5728MAC\u4e0a\u9810\u8a2d\u4e26\u672a\u5b89\u88dd\u3002<br \/>\n\u53ef\u4ee5\u4f7f\u7528Python\u7b49\u5176\u4ed6\u66ff\u4ee3\u65b9\u5f0f\u5be6\u73fe\u3002<\/p>\n<pre class=\"post-pre\"><code>$ cd molecule\/default\/\r\n$ cat common.tf.yml | python -c \"import yaml; import json; import sys; print(json.dumps(yaml.load(sys.stdin, Loader=yaml.FullLoader), indent=2))\" &gt; common.tf.json\r\n$ cat ins01.tf.yml | python -c \"import yaml; import json; import sys; print(json.dumps(yaml.load(sys.stdin, Loader=yaml.FullLoader), indent=2))\" &gt; ins01.tf.json\r\n<\/code><\/pre>\n<h3>\u8fdb\u884cterraform\u7684\u521d\u59cb\u8bbe\u7f6e (\u8fdb\u884cterraform init)<\/h3>\n<pre class=\"post-pre\"><code>$ terraform init \r\n\r\nInitializing the backend...\r\n\r\nInitializing provider plugins...\r\n- Using previously-installed hashicorp\/aws v3.13.0\r\n- Using previously-installed hashicorp\/local v1.4.0\r\n...\r\nTerraform has been successfully initialized!\r\n...\r\n<\/code><\/pre>\n<p>\u63d0\u4f9b\u7a0b\u5e8f\u6587\u4ef6\u5c06\u653e\u7f6e\u5728.terraform\/plugins\u76ee\u5f55\u4e0b\u3002<br \/>\n\u5982\u679c\u4e8b\u5148\u5c06\u5176\u653e\u7f6e\u5728~\/.terraform.d\/plugins\u76ee\u5f55\u4e2d\uff0c.terraform\/plugins\u76ee\u5f55\u5c06\u6210\u4e3a\u4e00\u4e2a\u7b26\u53f7\u94fe\u63a5\u3002<\/p>\n<h3>\u521b\u5efaAWS\u8d44\u6e90\uff08\u4f7f\u7528terraform apply\uff09<\/h3>\n<pre class=\"post-pre\"><code>$ terraform apply --auto-approve\r\n...\r\n\r\nApply complete! Resources: 14 added, 0 changed, 0 destroyed.\r\n\r\nOutputs:\r\n\r\nssh_login-ins01 = ssh -o UserKnownHostsFile=\/dev\/null -o StrictHostKeyChecking=no -i ~\/.ssh\/id_rsa ec2-user@52.68.125.189\r\n<\/code><\/pre>\n<h3>\u767b\u5165EC2\u5b9e\u4f8b\uff0c\u767b\u51fa\u3002<\/h3>\n<pre class=\"post-pre\"><code>$ ssh -o UserKnownHostsFile=\/dev\/null -o StrictHostKeyChecking=no -i ~\/.ssh\/id_rsa ec2-user@52.68.125.189\r\nWarning: Permanently added '52.68.125.189' (ECDSA) to the list of known hosts.\r\n\r\n       __|  __|_  )\r\n       _|  (     \/   Amazon Linux 2 AMI\r\n      ___|\\___|___|\r\n\r\nhttps:\/\/aws.amazon.com\/amazon-linux-2\/\r\n25 package(s) needed for security, out of 39 available\r\nRun \"sudo yum update\" to apply all updates.\r\n[ec2-user@ip-10-0-1-74 ~]$ ^D\r\n\u30ed\u30b0\u30a2\u30a6\u30c8\r\nConnection to 52.68.125.189 closed.\r\n<\/code><\/pre>\n<h3>AWS\u8d44\u6e90\u5220\u9664 (Terraform\u9500\u6bc1)<\/h3>\n<pre class=\"post-pre\"><code>$ terraform destroy --auto-approve\r\n...\r\naws_vpc.vpc01: Destruction complete after 1s\r\n\r\nDestroy complete! Resources: 14 destroyed.\r\n<\/code><\/pre>\n<h1>CH2. \u4e0e\u5206\u5b50\u7684\u5408\u4f5c<\/h1>\n<h2>\u5206\u5b50\u8a2d\u5b9a\u6a94\u6848\uff08molecule.yml\uff09<\/h2>\n<p>\u5728\u4e2d\u6587\u4e2d\u6709\u591a\u79cd\u9009\u62e9\u6765\u91cd\u65b0\u8868\u8fbe\u4e0a\u8ff0\u53e5\u5b50\uff0c\u4ee5\u4e0b\u662f\u4e00\u79cd\u53ef\u80fd\u7684\u65b9\u5f0f\uff1a<\/p>\n<p>\u901a\u8fc7\u547d\u4ee4\u300c$ molecule init role ROLENAME &#8211;driver-name delegated\u300d\u521b\u5efa\u7684molecule.yml\u6587\u4ef6\u9700\u8981\u8fdb\u884c\u7f16\u8f91\uff0c\u5728\u7f16\u8f91\u65f6\u9700\u4e0eterraform\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684platforms\u7684name\u4fdd\u6301\u4e00\u81f4\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nn\">---<\/span>\r\n<span class=\"na\">dependency<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">galaxy<\/span>\r\n<span class=\"na\">driver<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">delegated<\/span>\r\n<span class=\"na\">platforms<\/span><span class=\"pi\">:<\/span> <span class=\"c1\"># terraform\u306b\u3066\u4f5c\u6210\u3059\u308bec2\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3068\u540d\u524d\u304c\u5408\u81f4\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b<\/span>\r\n  <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">ins01<\/span>\r\n<span class=\"na\">provisioner<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">ansible<\/span>\r\n<span class=\"na\">verifier<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">ansible<\/span>\r\n<\/code><\/pre>\n<h2>\u521b\u5efa\u7528\u4e8e\u6d4b\u8bd5\u73af\u5883\u7684Molecule playbook\uff08create.yml\uff09\u3002<\/h2>\n<p>\u5728\u521b\u5efa.yml\u6587\u4ef6\u65f6\uff0c\u901a\u8fc7molecule init role ROLENAME &#8211;driver-name delegated\u8fdb\u884c\u7f16\u8f91\u3002 Dump\u4efb\u52a1\u6ca1\u6709\u8fdb\u884c\u4efb\u4f55\u66f4\u6539\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nn\">---<\/span>\r\n<span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Create<\/span>\r\n  <span class=\"na\">hosts<\/span><span class=\"pi\">:<\/span> <span class=\"s\">localhost<\/span>\r\n  <span class=\"na\">connection<\/span><span class=\"pi\">:<\/span> <span class=\"s\">local<\/span>\r\n  <span class=\"na\">gather_facts<\/span><span class=\"pi\">:<\/span> <span class=\"no\">false<\/span>\r\n  <span class=\"c1\">#no_log: \"{{ molecule_no_log }}\"<\/span>\r\n  <span class=\"na\">tasks<\/span><span class=\"pi\">:<\/span>\r\n\r\n  <span class=\"c1\"># molecule.yml\u3068terraform\u8a2d\u5b9a\u306e\u6574\u5408\u6027\u691c\u8a3c\u75281(\u30aa\u30d7\u30b7\u30e7\u30f3)<\/span>\r\n  <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">set_fact molecule_platforms<\/span>\r\n    <span class=\"na\">set_fact<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">molecule_platforms<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">{{<\/span> <span class=\"s\">molecule_yml.platforms|map(attribute='name')|list<\/span> <span class=\"s\">}}\"<\/span>\r\n  <span class=\"pi\">-<\/span> <span class=\"na\">debug<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">var<\/span><span class=\"pi\">:<\/span> <span class=\"s\">molecule_platforms<\/span>\r\n\r\n  <span class=\"c1\"># \u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u4f5c\u6210\u51e6\u7406\u672c\u4f53(\u5fc5\u9808)<\/span>\r\n  <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">terraform apply -auto-approve<\/span>\r\n    <span class=\"na\">shell<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">|-<\/span>\r\n      <span class=\"s\">set -ex<\/span>\r\n      <span class=\"s\">exec 2&gt;&amp;1<\/span>\r\n      <span class=\"s\">which yq<\/span>\r\n      <span class=\"s\">which terraform<\/span>\r\n      <span class=\"s\">! ls *.tf.json || rm *.tf.json<\/span>\r\n      <span class=\"s\">! ls instance_conf-*.yml || rm instance_conf-*.yml<\/span>\r\n      <span class=\"s\">ls *.tf.yml | awk '{TO=$1; sub(\/.tf.yml$\/,\".tf.json\",TO); print \"yq . \"$1\" &gt; \"TO}' | bash -x<\/span>\r\n      <span class=\"s\">terraform init -no-color<\/span>\r\n      <span class=\"s\">terraform apply -auto-approve -no-color || terraform apply -auto-approve -no-color<\/span>\r\n    <span class=\"na\">register<\/span><span class=\"pi\">:<\/span> <span class=\"s\">r<\/span>\r\n  <span class=\"pi\">-<\/span> <span class=\"na\">debug<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">var<\/span><span class=\"pi\">:<\/span> <span class=\"s\">r.stdout_lines<\/span>\r\n\r\n  <span class=\"c1\"># Molecule\u306b\u9023\u643a\u3059\u308b\u5404\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3078\u306e\u63a5\u7d9a\u60c5\u5831\u3092list\u306b\u307e\u3068\u3081\u308b(\u5fc5\u9808)<\/span>\r\n  <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Make instance_conf from terraform localfile<\/span>\r\n    <span class=\"na\">vars<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">instance_conf<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">[]<\/span>\r\n    <span class=\"na\">with_fileglob<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"pi\">-<\/span> <span class=\"s\">instance_conf-*.yml<\/span>\r\n    <span class=\"na\">set_fact<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">instance_conf<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">{{<\/span> <span class=\"s\">instance_conf<\/span> <span class=\"s\">+<\/span> <span class=\"s\">[lookup('file',item)|from_yaml]<\/span> <span class=\"s\">}}\"<\/span>\r\n\r\n  <span class=\"c1\"># molecule.yml\u3068terraform\u8a2d\u5b9a\u306e\u6574\u5408\u6027\u691c\u8a3c\u75282(\u30aa\u30d7\u30b7\u30e7\u30f3)<\/span>\r\n  <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">set_fact terraform_platforms<\/span>\r\n    <span class=\"na\">set_fact<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">terraform_platforms<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">{{<\/span> <span class=\"s\">instance_conf|map(attribute='instance')|list<\/span> <span class=\"s\">}}\"<\/span>\r\n  <span class=\"pi\">-<\/span> <span class=\"na\">debug<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">var<\/span><span class=\"pi\">:<\/span> <span class=\"s\">terraform_platforms<\/span>\r\n  <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Check molecule_platforms is included in terraform_platforms<\/span>\r\n    <span class=\"na\">assert<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">that<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">{{<\/span> <span class=\"s\">(molecule_platforms|difference(terraform_platforms))<\/span> <span class=\"s\">==<\/span> <span class=\"s\">[]<\/span> <span class=\"s\">}}\"<\/span>\r\n\r\n  <span class=\"c1\"># Molecule\u306b\u9023\u643a\u3059\u308b\u5404\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3078\u306e\u63a5\u7d9a\u60c5\u5831\u3092\u30d5\u30a1\u30a4\u30eb\u51fa\u529b(\u5fc5\u9808)<\/span>\r\n  <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Dump instance config<\/span>\r\n    <span class=\"na\">copy<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">content<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">|<\/span>\r\n        <span class=\"s\"># Molecule managed<\/span>\r\n\r\n        <span class=\"s\">{{ instance_conf | to_json | from_json | to_yaml }}<\/span>\r\n      <span class=\"na\">dest<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">{{<\/span> <span class=\"s\">molecule_instance_config<\/span> <span class=\"s\">}}\"<\/span>\r\n<\/code><\/pre>\n<h2>\u5206\u5b50\u4f7f\u7528\u6d4b\u8bd5\u73af\u5883\u51c6\u5907playbook \uff08prepare.yml\uff09\u3002<\/h2>\n<p>\u5982\u679c\u76ee\u6807\u7cfb\u7edf\u6ca1\u6709\u5b89\u88c5Python\uff0c\u5219\u53ef\u4ee5\u4f7f\u7528raw\u6a21\u5757\u6765\u8fdb\u884cPython\u7684\u5b89\u88c5\u3002<br \/>\n\u5728\u8fd9\u91cc\uff0c\u7b49\u5f85\u8fde\u63a5\u7684\u5b8c\u6210\u3002<br \/>\n\uff08\u7531\u4e8e\u5728terraform\u7ed3\u675f\u65f6\u5b9e\u4f8b\u5df2\u7ecf\u542f\u52a8\uff0c\u6240\u4ee5\u51e0\u4e4e\u4e0d\u9700\u8981\u7b49\u5f85\u3002\uff09<\/p>\n<pre class=\"post-pre\"><code><span class=\"nn\">---<\/span>\r\n<span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Prepare<\/span>\r\n  <span class=\"na\">hosts<\/span><span class=\"pi\">:<\/span> <span class=\"s\">all<\/span>\r\n  <span class=\"na\">gather_facts<\/span><span class=\"pi\">:<\/span> <span class=\"s\">no<\/span>\r\n  <span class=\"na\">tasks<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"pi\">-<\/span> <span class=\"na\">wait_for_connection<\/span><span class=\"pi\">:<\/span>\r\n<\/code><\/pre>\n<h2>\u4f7f\u7528\u5206\u5b50\uff08Molecule\uff09\u8fdb\u884c\u6d4b\u8bd5\u73af\u5883\u5220\u9664\u7684\u64ad\u653e\u4e66\uff08destroy.yml\uff09\u3002<\/h2>\n<p>\u4f7f\u7528molecule init role ROLENAME\u547d\u4ee4\uff0c\u5e76\u9009\u62e9&#8211;driver-name delegated\u9009\u9879\u6765\u521b\u5efa\u4e00\u4e2a\u540d\u4e3adestroy.yml\u7684\u6587\u4ef6\u540e\uff0c\u8fdb\u884c\u7f16\u8f91\u3002\u4e0d\u9700\u8981\u5bf9Dump\u4efb\u52a1\u8fdb\u884c\u66f4\u6539\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nn\">---<\/span>\r\n<span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Destroy<\/span>\r\n  <span class=\"na\">hosts<\/span><span class=\"pi\">:<\/span> <span class=\"s\">localhost<\/span>\r\n  <span class=\"na\">connection<\/span><span class=\"pi\">:<\/span> <span class=\"s\">local<\/span>\r\n  <span class=\"na\">gather_facts<\/span><span class=\"pi\">:<\/span> <span class=\"no\">false<\/span>\r\n  <span class=\"na\">no_log<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">{{<\/span> <span class=\"s\">molecule_no_log<\/span> <span class=\"s\">}}\"<\/span>\r\n  <span class=\"na\">tasks<\/span><span class=\"pi\">:<\/span>\r\n\r\n  <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Populate instance config<\/span>\r\n    <span class=\"na\">shell<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">|-<\/span>\r\n      <span class=\"s\">set -ex<\/span>\r\n      <span class=\"s\">exec 2&gt;&amp;1<\/span>\r\n      <span class=\"s\">terraform destroy --auto-approve -no-color || terraform destroy --auto-approve -no-color<\/span>\r\n    <span class=\"na\">register<\/span><span class=\"pi\">:<\/span> <span class=\"s\">r<\/span>\r\n  <span class=\"pi\">-<\/span> <span class=\"na\">debug<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">var<\/span><span class=\"pi\">:<\/span> <span class=\"s\">r.stdout_lines<\/span>\r\n\r\n  <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Populate instance config<\/span>\r\n    <span class=\"na\">set_fact<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">instance_conf<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">{}<\/span>\r\n\r\n  <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Dump instance config<\/span>\r\n    <span class=\"na\">copy<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">content<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">|<\/span>\r\n        <span class=\"s\"># Molecule managed<\/span>\r\n\r\n        <span class=\"s\">{{ instance_conf | to_json | from_json | to_yaml }}<\/span>\r\n      <span class=\"na\">dest<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">{{<\/span> <span class=\"s\">molecule_instance_config<\/span> <span class=\"s\">}}\"<\/span>\r\n<\/code><\/pre>\n<h2>\u8c03\u7528\u6d4b\u8bd5\u76ee\u6807\u89d2\u8272\u7684playbook\uff08converge.yml\uff09\u3002<\/h2>\n<p>\u6211\u6b63\u5728\u5bf9\u8fd9\u4e2a\u89d2\u8272\u7684\u76ee\u5f55\u540d\u79f0\u8fdb\u884c\u4fee\u6b63\uff0c\u4ee5\u4fbf\u80fd\u591f\u8ddf\u968f\u5176\u66f4\u6539\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nn\">---<\/span>\r\n<span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Converge<\/span>\r\n  <span class=\"na\">hosts<\/span><span class=\"pi\">:<\/span> <span class=\"s\">all<\/span>\r\n  <span class=\"na\">tasks<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"pi\">-<\/span> <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">Include<\/span> <span class=\"s\">{{<\/span> <span class=\"s\">playbook_dir|dirname|dirname|basename<\/span> <span class=\"s\">}}\"<\/span>\r\n      <span class=\"na\">include_role<\/span><span class=\"pi\">:<\/span>\r\n        <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">{{<\/span> <span class=\"s\">playbook_dir|dirname|dirname|basename<\/span> <span class=\"s\">}}\"<\/span>\r\n<\/code><\/pre>\n<h2>\u6d4b\u8bd5\u76ee\u6807\u89d2\u8272\u7684tasks\/main.yml<\/h2>\n<p>\u5728\u8fd9\u91cc\uff0c\u83b7\u53d6\u5e76\u663e\u793a\u76ee\u6807\u5b9e\u4f8b\u7684\u64cd\u4f5c\u7cfb\u7edf\u7c7b\u578b\u4fe1\u606f<\/p>\n<pre class=\"post-pre\"><code>---\r\n- debug:\r\n    var: ansible_distribution\r\n<\/code><\/pre>\n<h2>\u5206\u5b50\u6d4b\u8bd5\u7684\u5b9e\u4f8b\u3002<\/h2>\n<p>\u5728\u5206\u5b50\u6d4b\u8bd5\u4e2d\uff0c\u5c1d\u8bd5\u4ee5\u8fde\u7eed\u7684\u65b9\u5f0f\u6267\u884c\u5b9e\u4f8b\u521b\u5efa\u3001\u53cd\u6620\u548c\u5220\u9664\u3002<\/p>\n<pre class=\"post-pre\"><code>$ molecule test \r\n--&gt; Test matrix\r\n\r\n\u2514\u2500\u2500 default\r\n    \u251c\u2500\u2500 dependency\r\n    \u251c\u2500\u2500 lint\r\n    \u251c\u2500\u2500 cleanup\r\n    \u251c\u2500\u2500 destroy\r\n    \u251c\u2500\u2500 syntax\r\n    \u251c\u2500\u2500 create\r\n    \u251c\u2500\u2500 prepare\r\n    \u251c\u2500\u2500 converge\r\n    \u251c\u2500\u2500 idempotence\r\n    \u251c\u2500\u2500 side_effect\r\n    \u251c\u2500\u2500 verify\r\n    \u251c\u2500\u2500 cleanup\r\n    \u2514\u2500\u2500 destroy\r\n\r\n--&gt; Scenario: 'default'\r\n--&gt; Action: 'dependency'\r\nSkipping, missing the requirements file.\r\nSkipping, missing the requirements file.\r\n--&gt; Scenario: 'default'\r\n--&gt; Action: 'lint'\r\n--&gt; Lint is disabled.\r\n--&gt; Scenario: 'default'\r\n--&gt; Action: 'cleanup'\r\nSkipping, cleanup playbook not configured.\r\n--&gt; Scenario: 'default'\r\n--&gt; Action: 'destroy'\r\n\r\n    PLAY [Destroy] *****************************************************************\r\n\r\n    TASK [Populate instance config] ************************************************\r\n    changed: [localhost]\r\n\r\n    TASK [debug] *******************************************************************\r\n    ok: [localhost]\r\n\r\n    TASK [Populate instance config] ************************************************\r\n    ok: [localhost]\r\n\r\n    TASK [Dump instance config] ****************************************************\r\n    changed: [localhost]\r\n\r\n    PLAY RECAP *********************************************************************\r\n    localhost                  : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0\r\n\r\n--&gt; Scenario: 'default'\r\n--&gt; Action: 'syntax'\r\n\r\n    playbook: \/Users\/aa220269\/repo\/repo-test\/cookbooks\/molecule-delegated-terraform-ec2\/molecule\/default\/converge.yml\r\n--&gt; Scenario: 'default'\r\n--&gt; Action: 'create'\r\n\r\n    PLAY [Create] ******************************************************************\r\n\r\n    TASK [set_fact molecule_platforms] *********************************************\r\n    ok: [localhost]\r\n\r\n    TASK [debug] *******************************************************************\r\n    ok: [localhost] =&gt; {\r\n        \"molecule_platforms\": [\r\n            \"ins01\"\r\n        ]\r\n    }\r\n\r\n    TASK [terraform apply -auto-approve] *******************************************\r\n    changed: [localhost]\r\n\r\n    TASK [debug] *******************************************************************\r\n    ok: [localhost] =&gt; {\r\n        \"r.stdout_lines\": [\r\n            \"+ which yq\",\r\n            \"\/Users\/aa220269\/.pyenv\/shims\/yq\",\r\n            \"+ which terraform\",\r\n            \"\/usr\/local\/bin\/terraform\",\r\n            \"+ ls common.tf.json ins01.tf.json\",\r\n            \"common.tf.json\",\r\n            \"ins01.tf.json\",\r\n            \"+ rm common.tf.json ins01.tf.json\",\r\n            \"+ ls 'instance_conf-*.yml'\",\r\n            \"ls: instance_conf-*.yml: No such file or directory\",\r\n            \"+ ls common.tf.yml ins01.tf.yml\",\r\n            \"+ awk '{TO=$1; sub(\/.tf.yml$\/,\\\".tf.json\\\",TO); print \\\"yq . \\\"$1\\\" &gt; \\\"TO}'\",\r\n            \"+ bash -x\",\r\n            \"+ yq . common.tf.yml\",\r\n            \"+ yq . ins01.tf.yml\",\r\n            \"+ terraform init -no-color\",\r\n            \"\",\r\n            \"Initializing the backend...\",\r\n            \"\",\r\n            \"Initializing provider plugins...\",\r\n            \"- Using previously-installed hashicorp\/aws v3.13.0\",\r\n            \"- Using previously-installed hashicorp\/local v1.4.0\",\r\n            \"\",\r\n            \"The following providers do not have any version constraints in configuration,\",\r\n            \"so the latest version was installed.\",\r\n            \"\",\r\n            \"To prevent automatic upgrades to new major versions that may contain breaking\",\r\n            \"changes, we recommend adding version constraints in a required_providers block\",\r\n            \"in your configuration, with the constraint strings suggested below.\",\r\n            \"\",\r\n            \"* hashicorp\/local: version = \\\"~&gt; 1.4.0\\\"\",\r\n            \"\",\r\n            \"Terraform has been successfully initialized!\",\r\n            \"\",\r\n            \"You may now begin working with Terraform. Try running \\\"terraform plan\\\" to see\",\r\n            \"any changes that are required for your infrastructure. All Terraform commands\",\r\n            \"should now work.\",\r\n            \"\",\r\n            \"If you ever set or change modules or backend configuration for Terraform,\",\r\n            \"rerun this command to reinitialize your working directory. If you forget, other\",\r\n            \"commands will detect it and remind you to do so if necessary.\",\r\n            \"+ terraform apply -auto-approve -no-color\",\r\n            \"data.aws_ami.ami01: Refreshing state...\",\r\n            \"aws_vpc.vpc01: Creating...\",\r\n            \"aws_key_pair.key_pair01: Creating...\",\r\n            \"aws_key_pair.key_pair01: Creation complete after 1s [id=key_pair01]\",\r\n            \"aws_vpc.vpc01: Creation complete after 3s [id=vpc-004bac783f79ba162]\",\r\n            \"aws_route_table.route_table01: Creating...\",\r\n            \"aws_internet_gateway.internet_gateway01: Creating...\",\r\n            \"aws_security_group.security_group01: Creating...\",\r\n            \"aws_subnet.subnet01: Creating...\",\r\n            \"aws_route_table.route_table01: Creation complete after 0s [id=rtb-01a167c14ee021fe3]\",\r\n            \"aws_subnet.subnet01: Creation complete after 1s [id=subnet-0ffa370a28910b65a]\",\r\n            \"aws_route_table_association.route_table_association01: Creating...\",\r\n            \"aws_internet_gateway.internet_gateway01: Creation complete after 1s [id=igw-0cfeaa28a6412a523]\",\r\n            \"aws_route.route01: Creating...\",\r\n            \"aws_route_table_association.route_table_association01: Creation complete after 0s [id=rtbassoc-0695a2e2b04fb4728]\",\r\n            \"aws_security_group.security_group01: Creation complete after 1s [id=sg-05db55c4377f19c4f]\",\r\n            \"aws_security_group_rule.out_all: Creating...\",\r\n            \"aws_security_group_rule.in_icmp: Creating...\",\r\n            \"aws_security_group_rule.in_ssh: Creating...\",\r\n            \"aws_instance.ins01: Creating...\",\r\n            \"aws_route.route01: Creation complete after 1s [id=r-rtb-01a167c14ee021fe31080289494]\",\r\n            \"aws_security_group_rule.out_all: Creation complete after 1s [id=sgrule-3399627109]\",\r\n            \"aws_security_group_rule.in_ssh: Creation complete after 2s [id=sgrule-740776232]\",\r\n            \"aws_security_group_rule.in_icmp: Creation complete after 2s [id=sgrule-1963657664]\",\r\n            \"aws_instance.ins01: Still creating... [10s elapsed]\",\r\n            \"aws_instance.ins01: Still creating... [20s elapsed]\",\r\n            \"aws_instance.ins01: Still creating... [30s elapsed]\",\r\n            \"aws_instance.ins01: Creation complete after 33s [id=i-0f6d44308394d6b5c]\",\r\n            \"aws_eip.eip-ins01: Creating...\",\r\n            \"aws_eip.eip-ins01: Creation complete after 1s [id=eipalloc-0c4b8efe50c27636c]\",\r\n            \"local_file.instance_conf-ins01: Creating...\",\r\n            \"local_file.instance_conf-ins01: Creation complete after 0s [id=7d42af9527d38119349dc1f1c15e81e7a9c7e02e]\",\r\n            \"\",\r\n            \"Apply complete! Resources: 14 added, 0 changed, 0 destroyed.\",\r\n            \"\",\r\n            \"Outputs:\",\r\n            \"\",\r\n            \"ssh_login-ins01 = ssh -o UserKnownHostsFile=\/dev\/null -o StrictHostKeyChecking=no -i ~\/.ssh\/id_rsa ec2-user@54.249.181.45\"\r\n        ]\r\n    }\r\n\r\n    TASK [Make instance_conf from terraform localfile] *****************************\r\n    ok: [localhost] =&gt; (item=\/Users\/aa220269\/repo\/repo-test\/cookbooks\/molecule-delegated-terraform-ec2\/molecule\/default\/instance_conf-ins01.yml)\r\n\r\n    TASK [set_fact terraform_platforms] ********************************************\r\n    ok: [localhost]\r\n\r\n    TASK [debug] *******************************************************************\r\n    ok: [localhost] =&gt; {\r\n        \"terraform_platforms\": [\r\n            \"ins01\"\r\n        ]\r\n    }\r\n\r\n    TASK [Check molecule_platforms is included in terraform_platforms] *************\r\n    ok: [localhost] =&gt; {\r\n        \"changed\": false,\r\n        \"msg\": \"All assertions passed\"\r\n    }\r\n\r\n    TASK [Dump instance config] ****************************************************\r\n    changed: [localhost]\r\n\r\n    PLAY RECAP *********************************************************************\r\n    localhost                  : ok=9    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0\r\n\r\n--&gt; Scenario: 'default'\r\n--&gt; Action: 'prepare'\r\n\r\n    PLAY [Prepare] *****************************************************************\r\n\r\n    TASK [wait_for_connection] *****************************************************\r\n    ok: [ins01]\r\n\r\n    PLAY RECAP *********************************************************************\r\n    ins01                      : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0\r\n\r\n--&gt; Scenario: 'default'\r\n--&gt; Action: 'converge'\r\n\r\n    PLAY [Converge] ****************************************************************\r\n\r\n    TASK [Gathering Facts] *********************************************************\r\n[WARNING]: Platform linux on host ins01 is using the discovered Python\r\ninterpreter at \/usr\/bin\/python, but future installation of another Python\r\ninterpreter could change the meaning of that path. See https:\/\/docs.ansible.com\r\n\/ansible\/2.10\/reference_appendices\/interpreter_discovery.html for more\r\ninformation.\r\n    ok: [ins01]\r\n\r\n    TASK [Include molecule-delegated-terraform-ec2] ********************************\r\n\r\n    TASK [molecule-delegated-terraform-ec2 : debug] ********************************\r\n    ok: [ins01] =&gt; {\r\n        \"ansible_distribution\": \"Amazon\"\r\n    }\r\n\r\n    PLAY RECAP *********************************************************************\r\n    ins01                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0\r\n\r\n--&gt; Scenario: 'default'\r\n--&gt; Action: 'idempotence'\r\nIdempotence completed successfully.\r\n--&gt; Scenario: 'default'\r\n--&gt; Action: 'side_effect'\r\nSkipping, side effect playbook not configured.\r\n--&gt; Scenario: 'default'\r\n--&gt; Action: 'verify'\r\n--&gt; Running Ansible Verifier\r\n\r\n    PLAY [Verify] ******************************************************************\r\n\r\n    TASK [Example assertion] *******************************************************\r\n    ok: [ins01] =&gt; {\r\n        \"changed\": false,\r\n        \"msg\": \"All assertions passed\"\r\n    }\r\n\r\n    PLAY RECAP *********************************************************************\r\n    ins01                      : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0\r\n\r\nVerifier completed successfully.\r\n--&gt; Scenario: 'default'\r\n--&gt; Action: 'cleanup'\r\nSkipping, cleanup playbook not configured.\r\n--&gt; Scenario: 'default'\r\n--&gt; Action: 'destroy'\r\n\r\n    PLAY [Destroy] *****************************************************************\r\n\r\n    TASK [Populate instance config] ************************************************\r\n    changed: [localhost]\r\n\r\n    TASK [debug] *******************************************************************\r\n    ok: [localhost]\r\n\r\n    TASK [Populate instance config] ************************************************\r\n    ok: [localhost]\r\n\r\n    TASK [Dump instance config] ****************************************************\r\n    changed: [localhost]\r\n\r\n    PLAY RECAP *********************************************************************\r\n    localhost                  : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0\r\n\r\n--&gt; Pruning extra files from scenario ephemeral directory\r\n\r\n<\/code><\/pre>\n<h1>\u8bf7\u63d0\u4f9b\u4e00\u4e9b\u4e2d\u6587\u7684\u53e5\u5b50\uff0c\u6211\u4f1a\u4e3a\u60a8\u8fdb\u884c\u6539\u5199\u3002<\/h1>\n<p>\u4f7f\u7528Terraform\u6784\u5efaVPC\u548cEC2\u5b9e\u4f8b\uff0c\u5e76\u8fdb\u884cssh\u8fde\u63a5\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u95ee\u9898\uff1a \u4f7f\u7528Ansible Molecule\u8fdb\u884cPlaybook\u6d4b\u8bd5\u65f6\uff0c\u5982\u679c\u5728\u4e91\u4e0a\u8fdb\u884c\u6d4b\u8bd5\uff0c\u4f7f\u7528Terrafo [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-49138","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v21.5 (Yoast SEO v21.5) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>\u4f7f\u7528Ansible Molecule\u7684\u4ee3\u7406\u9a71\u52a8\u7a0b\u5e8f\uff0c\u901a\u8fc7terraform\u521b\u5efa\u7528\u4e8e\u6d4b\u8bd5\u7684AWS EC2\u5b9e\u4f8b - Blog - Silicon Cloud<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.silicloud.com\/zh\/blog\/\u4f7f\u7528ansible-molecule\u7684\u4ee3\u7406\u9a71\u52a8\u7a0b\u5e8f\uff0c\u901a\u8fc7terraform\u521b\u5efa\u7528\u4e8e\u6d4b\u8bd5\u7684aws\/\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u4f7f\u7528Ansible Molecule\u7684\u4ee3\u7406\u9a71\u52a8\u7a0b\u5e8f\uff0c\u901a\u8fc7terraform\u521b\u5efa\u7528\u4e8e\u6d4b\u8bd5\u7684AWS EC2\u5b9e\u4f8b\" \/>\n<meta property=\"og:description\" content=\"\u95ee\u9898\uff1a \u4f7f\u7528Ansible Molecule\u8fdb\u884cPlaybook\u6d4b\u8bd5\u65f6\uff0c\u5982\u679c\u5728\u4e91\u4e0a\u8fdb\u884c\u6d4b\u8bd5\uff0c\u4f7f\u7528Terrafo [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.silicloud.com\/zh\/blog\/\u4f7f\u7528ansible-molecule\u7684\u4ee3\u7406\u9a71\u52a8\u7a0b\u5e8f\uff0c\u901a\u8fc7terraform\u521b\u5efa\u7528\u4e8e\u6d4b\u8bd5\u7684aws\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog - Silicon Cloud\" \/>\n<meta property=\"article:published_time\" content=\"2023-09-29T07:17:21+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-04-30T01:50:21+00:00\" \/>\n<meta name=\"author\" content=\"\u79d1, \u96c5\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"\u79d1, \u96c5\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8ansible-molecule%e7%9a%84%e4%bb%a3%e7%90%86%e9%a9%b1%e5%8a%a8%e7%a8%8b%e5%ba%8f%ef%bc%8c%e9%80%9a%e8%bf%87terraform%e5%88%9b%e5%bb%ba%e7%94%a8%e4%ba%8e%e6%b5%8b%e8%af%95%e7%9a%84aws\/\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8ansible-molecule%e7%9a%84%e4%bb%a3%e7%90%86%e9%a9%b1%e5%8a%a8%e7%a8%8b%e5%ba%8f%ef%bc%8c%e9%80%9a%e8%bf%87terraform%e5%88%9b%e5%bb%ba%e7%94%a8%e4%ba%8e%e6%b5%8b%e8%af%95%e7%9a%84aws\/\",\"name\":\"\u4f7f\u7528Ansible Molecule\u7684\u4ee3\u7406\u9a71\u52a8\u7a0b\u5e8f\uff0c\u901a\u8fc7terraform\u521b\u5efa\u7528\u4e8e\u6d4b\u8bd5\u7684AWS EC2\u5b9e\u4f8b - Blog - Silicon Cloud\",\"isPartOf\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\"},\"datePublished\":\"2023-09-29T07:17:21+00:00\",\"dateModified\":\"2024-04-30T01:50:21+00:00\",\"author\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/41e222757cdd2a3365361328bd79970a\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8ansible-molecule%e7%9a%84%e4%bb%a3%e7%90%86%e9%a9%b1%e5%8a%a8%e7%a8%8b%e5%ba%8f%ef%bc%8c%e9%80%9a%e8%bf%87terraform%e5%88%9b%e5%bb%ba%e7%94%a8%e4%ba%8e%e6%b5%8b%e8%af%95%e7%9a%84aws\/#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8ansible-molecule%e7%9a%84%e4%bb%a3%e7%90%86%e9%a9%b1%e5%8a%a8%e7%a8%8b%e5%ba%8f%ef%bc%8c%e9%80%9a%e8%bf%87terraform%e5%88%9b%e5%bb%ba%e7%94%a8%e4%ba%8e%e6%b5%8b%e8%af%95%e7%9a%84aws\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8ansible-molecule%e7%9a%84%e4%bb%a3%e7%90%86%e9%a9%b1%e5%8a%a8%e7%a8%8b%e5%ba%8f%ef%bc%8c%e9%80%9a%e8%bf%87terraform%e5%88%9b%e5%bb%ba%e7%94%a8%e4%ba%8e%e6%b5%8b%e8%af%95%e7%9a%84aws\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.silicloud.com\/zh\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u4f7f\u7528Ansible Molecule\u7684\u4ee3\u7406\u9a71\u52a8\u7a0b\u5e8f\uff0c\u901a\u8fc7terraform\u521b\u5efa\u7528\u4e8e\u6d4b\u8bd5\u7684AWS EC2\u5b9e\u4f8b\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/\",\"name\":\"Blog - Silicon Cloud\",\"description\":\"\",\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/41e222757cdd2a3365361328bd79970a\",\"name\":\"\u79d1, \u96c5\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/1b2d3e00a7df03689797ebd4af8c5827ba5af936849a71050ec331f4cf902c5d?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/1b2d3e00a7df03689797ebd4af8c5827ba5af936849a71050ec331f4cf902c5d?s=96&d=mm&r=g\",\"caption\":\"\u79d1, \u96c5\"},\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/author\/keya\/\"},{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8ansible-molecule%e7%9a%84%e4%bb%a3%e7%90%86%e9%a9%b1%e5%8a%a8%e7%a8%8b%e5%ba%8f%ef%bc%8c%e9%80%9a%e8%bf%87terraform%e5%88%9b%e5%bb%ba%e7%94%a8%e4%ba%8e%e6%b5%8b%e8%af%95%e7%9a%84aws\/#local-main-organization-logo\",\"url\":\"\",\"contentUrl\":\"\",\"caption\":\"Blog - Silicon Cloud\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"\u4f7f\u7528Ansible Molecule\u7684\u4ee3\u7406\u9a71\u52a8\u7a0b\u5e8f\uff0c\u901a\u8fc7terraform\u521b\u5efa\u7528\u4e8e\u6d4b\u8bd5\u7684AWS EC2\u5b9e\u4f8b - Blog - Silicon Cloud","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.silicloud.com\/zh\/blog\/\u4f7f\u7528ansible-molecule\u7684\u4ee3\u7406\u9a71\u52a8\u7a0b\u5e8f\uff0c\u901a\u8fc7terraform\u521b\u5efa\u7528\u4e8e\u6d4b\u8bd5\u7684aws\/","og_locale":"zh_CN","og_type":"article","og_title":"\u4f7f\u7528Ansible Molecule\u7684\u4ee3\u7406\u9a71\u52a8\u7a0b\u5e8f\uff0c\u901a\u8fc7terraform\u521b\u5efa\u7528\u4e8e\u6d4b\u8bd5\u7684AWS EC2\u5b9e\u4f8b","og_description":"\u95ee\u9898\uff1a \u4f7f\u7528Ansible Molecule\u8fdb\u884cPlaybook\u6d4b\u8bd5\u65f6\uff0c\u5982\u679c\u5728\u4e91\u4e0a\u8fdb\u884c\u6d4b\u8bd5\uff0c\u4f7f\u7528Terrafo [&hellip;]","og_url":"https:\/\/www.silicloud.com\/zh\/blog\/\u4f7f\u7528ansible-molecule\u7684\u4ee3\u7406\u9a71\u52a8\u7a0b\u5e8f\uff0c\u901a\u8fc7terraform\u521b\u5efa\u7528\u4e8e\u6d4b\u8bd5\u7684aws\/","og_site_name":"Blog - Silicon Cloud","article_published_time":"2023-09-29T07:17:21+00:00","article_modified_time":"2024-04-30T01:50:21+00:00","author":"\u79d1, \u96c5","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"\u79d1, \u96c5","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"11 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8ansible-molecule%e7%9a%84%e4%bb%a3%e7%90%86%e9%a9%b1%e5%8a%a8%e7%a8%8b%e5%ba%8f%ef%bc%8c%e9%80%9a%e8%bf%87terraform%e5%88%9b%e5%bb%ba%e7%94%a8%e4%ba%8e%e6%b5%8b%e8%af%95%e7%9a%84aws\/","url":"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8ansible-molecule%e7%9a%84%e4%bb%a3%e7%90%86%e9%a9%b1%e5%8a%a8%e7%a8%8b%e5%ba%8f%ef%bc%8c%e9%80%9a%e8%bf%87terraform%e5%88%9b%e5%bb%ba%e7%94%a8%e4%ba%8e%e6%b5%8b%e8%af%95%e7%9a%84aws\/","name":"\u4f7f\u7528Ansible Molecule\u7684\u4ee3\u7406\u9a71\u52a8\u7a0b\u5e8f\uff0c\u901a\u8fc7terraform\u521b\u5efa\u7528\u4e8e\u6d4b\u8bd5\u7684AWS EC2\u5b9e\u4f8b - Blog - Silicon Cloud","isPartOf":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website"},"datePublished":"2023-09-29T07:17:21+00:00","dateModified":"2024-04-30T01:50:21+00:00","author":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/41e222757cdd2a3365361328bd79970a"},"breadcrumb":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8ansible-molecule%e7%9a%84%e4%bb%a3%e7%90%86%e9%a9%b1%e5%8a%a8%e7%a8%8b%e5%ba%8f%ef%bc%8c%e9%80%9a%e8%bf%87terraform%e5%88%9b%e5%bb%ba%e7%94%a8%e4%ba%8e%e6%b5%8b%e8%af%95%e7%9a%84aws\/#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8ansible-molecule%e7%9a%84%e4%bb%a3%e7%90%86%e9%a9%b1%e5%8a%a8%e7%a8%8b%e5%ba%8f%ef%bc%8c%e9%80%9a%e8%bf%87terraform%e5%88%9b%e5%bb%ba%e7%94%a8%e4%ba%8e%e6%b5%8b%e8%af%95%e7%9a%84aws\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8ansible-molecule%e7%9a%84%e4%bb%a3%e7%90%86%e9%a9%b1%e5%8a%a8%e7%a8%8b%e5%ba%8f%ef%bc%8c%e9%80%9a%e8%bf%87terraform%e5%88%9b%e5%bb%ba%e7%94%a8%e4%ba%8e%e6%b5%8b%e8%af%95%e7%9a%84aws\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.silicloud.com\/zh\/blog\/"},{"@type":"ListItem","position":2,"name":"\u4f7f\u7528Ansible Molecule\u7684\u4ee3\u7406\u9a71\u52a8\u7a0b\u5e8f\uff0c\u901a\u8fc7terraform\u521b\u5efa\u7528\u4e8e\u6d4b\u8bd5\u7684AWS EC2\u5b9e\u4f8b"}]},{"@type":"WebSite","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website","url":"https:\/\/www.silicloud.com\/zh\/blog\/","name":"Blog - Silicon Cloud","description":"","inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/41e222757cdd2a3365361328bd79970a","name":"\u79d1, \u96c5","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/1b2d3e00a7df03689797ebd4af8c5827ba5af936849a71050ec331f4cf902c5d?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1b2d3e00a7df03689797ebd4af8c5827ba5af936849a71050ec331f4cf902c5d?s=96&d=mm&r=g","caption":"\u79d1, \u96c5"},"url":"https:\/\/www.silicloud.com\/zh\/blog\/author\/keya\/"},{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8ansible-molecule%e7%9a%84%e4%bb%a3%e7%90%86%e9%a9%b1%e5%8a%a8%e7%a8%8b%e5%ba%8f%ef%bc%8c%e9%80%9a%e8%bf%87terraform%e5%88%9b%e5%bb%ba%e7%94%a8%e4%ba%8e%e6%b5%8b%e8%af%95%e7%9a%84aws\/#local-main-organization-logo","url":"","contentUrl":"","caption":"Blog - Silicon Cloud"}]}},"_links":{"self":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/49138","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/comments?post=49138"}],"version-history":[{"count":2,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/49138\/revisions"}],"predecessor-version":[{"id":91188,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/49138\/revisions\/91188"}],"wp:attachment":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/media?parent=49138"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/categories?post=49138"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/tags?post=49138"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}